/// <summary> /// Constructor. /// </summary> /// <param name="mooseBoxRESTAPI">Instance to a versioned MooseBox REST API.</param> /// <param name="registeredFans">Current MooseBox Fan Automation config to build instance from.</param> internal FanAutomation(IMooseBoxRESTAPI mooseBoxRESTAPI, List<FanAutomationConfig> registeredFans) { //Parameter Validations. if (mooseBoxRESTAPI == null) throw new ArgumentNullException("IMooseBoxRESTAPI mooseBoxRESTAPI"); if (registeredFans == null) throw new ArgumentNullException("List<FanAutomationConfig> registeredFans"); //Set Members. m_mooseBoxRESTAPI = mooseBoxRESTAPI; m_registeredFansDict = new Dictionary<Fan, Tuple<TemperatureSensor, Single>>(); //Populate cache if we're building from a config object. foreach (var registeredFan in registeredFans) { TemperatureSensor temperatureSensor = new TemperatureSensor(registeredFan.SerialNumber, mooseBoxRESTAPI); foreach (var fanConfig in registeredFan.FansConfig) { Fan fan = new Fan(fanConfig.FanNumber, mooseBoxRESTAPI); m_registeredFansDict[fan] = new Tuple<TemperatureSensor, Single>(temperatureSensor, fanConfig.PowerOnThresholdCelsius); } } }
/// <summary> /// Compares this instance of a Fan against another for value equality. /// </summary> /// <param name="obj">Instance to compare against.</param> /// <returns>true if equal; false otherwise.</returns> public override bool Equals(object obj) { bool result = true; Fan other = obj as Fan; if (other != null) { result &= (this.m_fanNumber == other.m_fanNumber); } else { result = false; } return(result); }
/// <summary> /// Unregisters a fan from temperature automation. /// </summary> /// <param name="fan">USB Fan to unregister.</param> /// <returns>Asynchronous Processing Task.</returns> internal async Task Unregister(Fan fan) { //Parameter Validations. if (fan == null) { throw new ArgumentNullException("Fan fan"); } //Is it registered? if (m_registeredFansDict.ContainsKey(fan) == false) { return; //Nothing to do! } //It is, attempt an unregistration. await m_mooseBoxRESTAPI.UnegisterFanAutomation(fan.Number); //Now remove it from local cache. m_registeredFansDict.Remove(fan); }
/// <summary> /// Registers a fan for automation with an associated temperature sensor. /// </summary> /// <param name="fan">USB Fan to register.</param> /// <param name="temperatureSensor">Temperature sensor to register against.</param> /// <param name="celsiusThreshold">Warmest allowable reading before automating fan cooling.</param> /// <returns>Asynchronous Processing Task.</returns> internal async Task Register(Fan fan, TemperatureSensor temperatureSensor, Single celsiusThreshold) { bool unregisterPrev = false; Tuple <TemperatureSensor, Single> value = null; //Parameter Validations. if (fan == null) { throw new ArgumentNullException("Fan fan"); } if (temperatureSensor == null) { throw new ArgumentNullException("TemperatureSensor temperatureSensor"); } //Is it already registered? Are we changing? if (m_registeredFansDict.TryGetValue(fan, out value) == true) { Debug.Assert(value != null); Debug.Assert(value.Item1 != null); if (value.Item1.Equals(temperatureSensor) == true && value.Item2 == celsiusThreshold) { return; //Nothing to do! } unregisterPrev = true; } //User is requesting an overwrite, which is an unregistration first. if (unregisterPrev == true) { await m_mooseBoxRESTAPI.UnegisterFanAutomation(fan.Number); } //Register the new fan information. await m_mooseBoxRESTAPI.RegisterFanAutomation(fan.Number, temperatureSensor.SerialNumber, celsiusThreshold); //Update the local cache. m_registeredFansDict[fan] = new Tuple <TemperatureSensor, Single>(temperatureSensor, celsiusThreshold); }
/// <summary> /// Changes the color of a numbered fan's power status led on main panel. /// </summary> /// <param name="fan">Fan to change LED of.</param> /// <param name="ledColor">Color to change LED to.</param> private void UpdateFanLED(Fan fan, LEDColors ledColor) { PictureBox ledPictureBox = null; Debug.Assert(fan != null); //Lookup the LED WinForm picture box to redraw. switch(fan.Number) { case 1: ledPictureBox = pictureBoxFan1LED; break; case 2: ledPictureBox = pictureBoxFan2LED; break; case 3: ledPictureBox = pictureBoxFan3LED; break; default: throw new ArgumentOutOfRangeException("Fan fan", string.Format("Invalid Fan Number. Found: {0}", fan.Number)); } //Redraw the the LED image for the fan. Debug.Assert(ledPictureBox != null); LEDHelper.ChangeColor(ledPictureBox, ledColor); }
/// <summary> /// Changes the color of a numbered fan's power status led on main panel. /// </summary> /// <param name="fan">Fan to change LED of.</param> /// <param name="isPowered">true if a USB Fan is powered; false otherwise.</param> private void UpdateFanLED(Fan fan, bool isPowered) { if (isPowered == true) UpdateFanLED(fan, LEDColors.Green); else UpdateFanLED(fan, LEDColors.Red); }
/// <summary> /// Registers a fan for automation with an associated temperature sensor. /// </summary> /// <param name="fan">USB Fan to register.</param> /// <param name="temperatureSensor">Temperature sensor to register against.</param> /// <param name="celsiusThreshold">Warmest allowable reading before automating fan cooling.</param> /// <returns>Asynchronous Processing Task.</returns> internal async Task Register(Fan fan, TemperatureSensor temperatureSensor, Single celsiusThreshold) { bool unregisterPrev = false; Tuple<TemperatureSensor, Single> value = null; //Parameter Validations. if (fan == null) throw new ArgumentNullException("Fan fan"); if (temperatureSensor == null) throw new ArgumentNullException("TemperatureSensor temperatureSensor"); //Is it already registered? Are we changing? if (m_registeredFansDict.TryGetValue(fan, out value) == true) { Debug.Assert(value != null); Debug.Assert(value.Item1 != null); if (value.Item1.Equals(temperatureSensor) == true && value.Item2 == celsiusThreshold) return; //Nothing to do! unregisterPrev = true; } //User is requesting an overwrite, which is an unregistration first. if (unregisterPrev == true) await m_mooseBoxRESTAPI.UnegisterFanAutomation(fan.Number); //Register the new fan information. await m_mooseBoxRESTAPI.RegisterFanAutomation(fan.Number, temperatureSensor.SerialNumber, celsiusThreshold); //Update the local cache. m_registeredFansDict[fan] = new Tuple<TemperatureSensor, Single>(temperatureSensor, celsiusThreshold); }
/// <summary> /// Tests whether a USB Fan is registered for automation. /// </summary> /// <param name="fan">USB Fan to test.</param> /// <returns>true if registered; false otherwise.</returns> internal bool IsRegistered(Fan fan) { //Parameter Validations. if (fan == null) throw new ArgumentNullException("Fan fan"); //Lookup its existance in the cache. return m_registeredFansDict.ContainsKey(fan); }
/// <summary> /// Attempts to get current registration information for a USB Fan, if it was registered. /// </summary> /// <param name="fan">USB Fan to query information for.</param> /// <param name="temperatureSensor">Temperature sensor fan is tied to.</param> /// <param name="celsiusThreshold">Warmest allowd reading before fan cooling is automated.</param> /// <returns>true if registration information was queried; false otherwise.</returns> internal bool TryGetRegistrationInfo(Fan fan, out TemperatureSensor temperatureSensor, out Single celsiusThreshold) { bool result = false; Tuple<TemperatureSensor, Single> value = null; temperatureSensor = null; celsiusThreshold = Single.NaN; //Parameter Validations. if (fan == null) throw new ArgumentNullException("Fan fan"); //Check our cache, which is synchronized. if (m_registeredFansDict.TryGetValue(fan, out value) == true) { //Set outputs. temperatureSensor = value.Item1; celsiusThreshold = value.Item2; result = true; } return result; }
/// <summary> /// Unregisters a fan from temperature automation. /// </summary> /// <param name="fan">USB Fan to unregister.</param> /// <returns>Asynchronous Processing Task.</returns> internal async Task Unregister(Fan fan) { //Parameter Validations. if (fan == null) throw new ArgumentNullException("Fan fan"); //Is it registered? if (m_registeredFansDict.ContainsKey(fan) == false) return; //Nothing to do! //It is, attempt an unregistration. await m_mooseBoxRESTAPI.UnegisterFanAutomation(fan.Number); //Now remove it from local cache. m_registeredFansDict.Remove(fan); }
/// <summary> /// Synchronizes UI's radio buttons to reflect Fan power states. /// </summary> /// <param name="fan">USB Fan to synchronize UI to.</param> /// <param name="isPowered">true if powered; false otherwise.</param> private void UpdateRadioButton(Fan fan, bool isPowered) { Debug.Assert(fan != null); switch(fan.Number) { case 1: if (isPowered == true) radioButtonFan1On.Checked = true; else radioButtonFan1Off.Checked = true; break; case 2: if (isPowered == true) radioButtonFan2On.Checked = true; else radioButtonFan2Off.Checked = true; break; case 3: if (isPowered == true) radioButtonFan3On.Checked = true; else radioButtonFan3Off.Checked = true; break; default: throw new ArgumentOutOfRangeException("Fan fan", string.Format("Unknown Fan Number. Found: {0}", fan.Number)); } }
/// <summary> /// Updates a USB Fan for a manual override operation. /// </summary> /// <param name="fan">USB Fan to update.</param> private void UpdateFan(Fan fan) { Debug.Assert(fan != null); switch (fan.Number) { case 1: AsyncHelper.RunSync(() => { return Fan.Fan1.SetPower(radioButtonFan1On.Checked); }); break; case 2: AsyncHelper.RunSync(() => { return Fan.Fan2.SetPower(radioButtonFan2On.Checked); }); break; case 3: AsyncHelper.RunSync(() => { return Fan.Fan3.SetPower(radioButtonFan3On.Checked); }); break; default: throw new ArgumentOutOfRangeException("Fan fan", string.Format("Unknown Fan Number. Found: {0}", fan.Number)); } }
/// <summary> /// Master worker method to synchronize UI with Fan Automation state. /// </summary> /// <param name="fan">USB Fan to synchronize to.</param> /// <param name="comboBox">ComboBox with sensor serial numbers.</param> /// <param name="textBox">TextBox with user-entered celsius thresholds.</param> /// <param name="button">Enable/Disable button.</param> private void Update(Fan fan, ComboBox comboBox, TextBox textBox, Button button) { bool found = false; Single celsiusThreshold = Single.NaN; TemperatureSensor temperatureSensor = null; Debug.Assert(fan != null); Debug.Assert(comboBox != null); Debug.Assert(textBox != null); Debug.Assert(button != null); found = m_fanAutomationRef.TryGetRegistrationInfo(fan, out temperatureSensor, out celsiusThreshold); //Part I: Update the ComboBoxes. if (found == true) { comboBox.SelectedText = temperatureSensor.SerialNumber; comboBox.SelectedItem = temperatureSensor.SerialNumber; comboBox.Enabled = false; } else { comboBox.SelectedItem = -1; comboBox.Enabled = true; } //Part II: Update the TextBoxes. if (found == true) { textBoxFan1.Text = ConvertUnits.Temperature.CelsiusToFahrenheit(celsiusThreshold).ToString(); textBox.ReadOnly = true; textBox.Enabled = false; } else { textBox.ReadOnly = false; textBox.Enabled = true; } //Part III: Update Buttons. if (found == true) button.Text = DisableText; else button.Text = EnableText; }
/// <summary> /// Master worker method to process a Fan automation request. /// </summary> /// <param name="fan">USB Fan to automate.</param> /// <param name="comboBox">ComboBox with sensor serial number.</param> /// <param name="textBox">TextBox with user-entered celsius threshold.</param> /// <param name="button">Enable/Disable button.</param> private void ProcessButtonClick(Fan fan, ComboBox comboBox, TextBox textBox, Button button) { Debug.Assert(fan != null); Debug.Assert(comboBox != null); Debug.Assert(textBox != null); Debug.Assert(button != null); //If it's already enabled, then disable it - allow the user to make edits. if (button.Text == DisableText) { //Unregister the fan from automation. AsyncHelper.RunSync(() => { return m_fanAutomationRef.Unregister(fan); }); //Automatically un-power it. AsyncHelper.RunSync(() => { return fan.SetPower(false); }); //Now prompt the user that we unpowered the fan. MessageBox.Show(string.Format("USB Fan #{0} has been unpowered. To change power without automation go to Fan Manual Override dialog.", fan.Number), "Fan Unpowered", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { Debug.Assert(button.Text == EnableText); //Ensure they selected a temperature sensor. if (comboBox.SelectedItem as string != TemperatureSensor._59000002A218F928.SerialNumber && comboBox.SelectedItem as string != TemperatureSensor._F7000002A215B828.SerialNumber) { MessageBox.Show("Please select a Temperature Sensor to register the fan against.", "Warning", MessageBoxButtons.OK); return; } //Validate the Celsius Range. bool isValid = false; Single celsiusThreshold = Single.NaN; try { celsiusThreshold = ConvertUnits.Temperature.FahrenheitToCelsius(Convert.ToSingle(textBox.Text)); isValid = (celsiusThreshold >= Limits.MinTemperatureCelsius) && (celsiusThreshold <= Limits.MaxTemperatureCelsius); } catch { isValid = false; } if (isValid == false) MessageBox.Show(string.Format("Temperature Threshold must be between {0}F and {1}F. Please re-enter and try again.", ConvertUnits.Temperature.CelsiusToFahrenheit(Limits.MinTemperatureCelsius), ConvertUnits.Temperature.CelsiusToFahrenheit(Limits.MaxTemperatureCelsius)), "Bad Temperature Threshold", MessageBoxButtons.OK, MessageBoxIcon.Error); //Register the fan for automation. TemperatureSensor temperatureSensor = null; if (comboBox.SelectedItem as string == TemperatureSensor._59000002A218F928.SerialNumber) temperatureSensor = TemperatureSensor._59000002A218F928; else temperatureSensor = TemperatureSensor._F7000002A215B828; AsyncHelper.RunSync(() => { return m_fanAutomationRef.Register(fan, temperatureSensor, celsiusThreshold); }); } //Call update Update(); }