public static void ChangeZone(long lRequestId, int iZone, bool bOn) { AirConditionerCommand command = new AirConditionerCommand(); string[] strZones; Logging.WriteDebugLog("AirConditioner.ChangeZone() [0x{0}] Changing Zone: {1}", lRequestId.ToString("X8"), iZone); lock (_oLockCommand) { command.amOn = _airConditionerCommand.amOn; command.tempTarget = _airConditionerCommand.tempTarget; command.fanSpeed = _airConditionerCommand.fanSpeed; command.mode = _airConditionerCommand.mode; strZones = _airConditionerCommand.enabledZones.Split(new char[] { ',' }); if (strZones.Length != 8 | iZone < 1 | iZone > 8) { command.enabledZones = _airConditionerCommand.enabledZones; } else { strZones[iZone - 1] = bOn ? "1" : "0"; command.enabledZones = string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", strZones[0], strZones[1], strZones[2], strZones[3], strZones[4], strZones[5], strZones[6], strZones[7]); MQTT.SendMessage(string.Format("actron/aircon/zone{0}", iZone), bOn ? "ON" : "OFF"); } } PostCommand(lRequestId, "System", command); }
private static void MQTTRegister() { Logging.WriteDebugLog("Service.MQTTRegister()"); MQTT.SendMessage("homeassistant/climate/actronaircon/config", "{{\"name\":\"{1}\",\"modes\":[\"off\",\"auto\",\"cool\",\"fan_only\",\"heat\"],\"fan_modes\":[\"high\",\"medium\",\"low\"],\"mode_command_topic\":\"actron/aircon/mode/set\",\"temperature_command_topic\":\"actron/aircon/temperature/set\",\"fan_mode_command_topic\":\"actron/aircon/fan/set\",\"min_temp\":\"12\",\"max_temp\":\"30\",\"temp_step\":\"0.5\",\"fan_mode_state_topic\":\"actron/aircon/fanmode\",\"action_topic\":\"actron/aircon/compressor\",\"temperature_state_topic\":\"actron/aircon/settemperature\",\"mode_state_topic\":\"actron/aircon/mode\",\"current_temperature_topic\":\"actron/aircon/temperature\",\"availability_topic\":\"{0}/status\"}}", _strServiceName.ToLower(), _strDeviceName); foreach (int iZone in AirConditioner.Zones.Keys) { MQTT.SendMessage(string.Format("homeassistant/switch/actron/airconzone{0}/config", iZone), "{{\"name\":\"{0} Zone\",\"state_topic\":\"actron/aircon/zone{1}\",\"command_topic\":\"actron/aircon/zone{1}/set\",\"payload_on\":\"ON\",\"payload_off\":\"OFF\",\"state_on\":\"ON\",\"state_off\":\"OFF\",\"availability_topic\":\"{2}/status\"}}", AirConditioner.Zones[iZone].Name, iZone, _strServiceName.ToLower()); MQTT.Subscribe("actron/aircon/zone{0}/set", iZone); if (_bRegisterZoneTemperatures) { MQTT.SendMessage(string.Format("homeassistant/sensor/actron/airconzone{0}/config", iZone), "{{\"name\":\"{0}\",\"state_topic\":\"actron/aircon/zone{1}/temperature\",\"unit_of_measurement\":\"\u00B0C\",\"availability_topic\":\"{2}/status\"}}", AirConditioner.Zones[iZone].Name, iZone, _strServiceName.ToLower()); } else { MQTT.SendMessage(string.Format("homeassistant/sensor/actron/airconzone{0}/config", iZone), "{{}}"); // Clear existing devices } } MQTT.Subscribe("actron/aircon/mode/set"); MQTT.Subscribe("actron/aircon/fan/set"); MQTT.Subscribe("actron/aircon/temperature/set"); }
public static void Start() { IConfigurationRoot configuration; IHost webHost; bool bMQTTTLS; Logging.WriteDebugLog("Service.Start() Build Date: {0}", Properties.Resources.BuildDate); try { configuration = new ConfigurationBuilder().AddJsonFile(_strConfigFile, false, true).Build(); } catch (Exception eException) { Logging.WriteDebugLogError("Service.Start()", eException, "Unable to build configuration instance."); return; } bool.TryParse(configuration["RegisterZoneTemperatures"] ?? "false", out _bRegisterZoneTemperatures); bool.TryParse(configuration["ForwardToOriginalWebService"] ?? "false", out _bForwardToOriginalWebService); bool.TryParse(configuration["MQTTTLS"] ?? "false", out bMQTTTLS); Logging.WriteDebugLog("Service.Start() RegisterZoneTemperatures: {0}", _bRegisterZoneTemperatures); Logging.WriteDebugLog("Service.Start() ForwardToOriginalWebService: {0}", _bForwardToOriginalWebService); Logging.WriteDebugLog("Service.Start() MQTT TLS: {0}", bMQTTTLS); MQTT.StartMQTT(configuration["MQTTBroker"] ?? "core-mosquitto", bMQTTTLS, _strServiceName, configuration["MQTTUser"] ?? "", configuration["MQTTPassword"] ?? "", MQTTProcessor); AirConditioner.Configure(configuration); MQTTRegister(); try { webHost = Host.CreateDefaultBuilder().ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup <ASPNETCoreStartup>().UseConfiguration(configuration).UseUrls($"http://*:80/"); }).Build(); } catch (Exception eException) { Logging.WriteDebugLogError("Service.Start()", eException, "Unable to build Kestrel instance."); return; } webHost.Run(); }
public static void ChangeTemperature(long lRequestId, double dblTemperature) { AirConditionerCommand command = new AirConditionerCommand(); Logging.WriteDebugLog("AirConditioner.ChangeTemperature() [0x{0}] Changing Temperature: {1}", lRequestId.ToString("X8"), dblTemperature); lock (_oLockCommand) { command.amOn = _airConditionerCommand.amOn; command.tempTarget = dblTemperature; command.fanSpeed = _airConditionerCommand.fanSpeed; command.mode = _airConditionerCommand.mode; command.enabledZones = _airConditionerCommand.enabledZones; } MQTT.SendMessage("actron/aircon/settemperature", command.tempTarget.ToString()); PostCommand(lRequestId, "System", command); }
public static void ChangeFanSpeed(long lRequestId, FanSpeed speed) { AirConditionerCommand command = new AirConditionerCommand(); Logging.WriteDebugLog("AirConditioner.ChangeFanSpeed() [0x{0}] Changing Fan Speed: {1}", lRequestId.ToString("X8"), Enum.GetName(typeof(FanSpeed), speed)); lock (_oLockCommand) { command.amOn = _airConditionerCommand.amOn; command.tempTarget = _airConditionerCommand.tempTarget; command.fanSpeed = (int)speed; command.mode = _airConditionerCommand.mode; command.enabledZones = _airConditionerCommand.enabledZones; } MQTT.SendMessage("actron/aircon/fanmode", Enum.GetName(typeof(FanSpeed), speed).ToLower()); PostCommand(lRequestId, "System", command); }
public static void ChangeMode(long lRequestId, AirConditionerMode mode) { AirConditionerCommand command = new AirConditionerCommand(); Logging.WriteDebugLog("AirConditioner.ChangeMode() [0x{0}] Changing Mode: {1}", lRequestId.ToString("X8"), Enum.GetName(typeof(AirConditionerMode), mode)); lock (_oLockCommand) { command.amOn = (mode == AirConditionerMode.None ? false : true); command.tempTarget = _airConditionerCommand.tempTarget; command.fanSpeed = _airConditionerCommand.fanSpeed; command.mode = (mode == AirConditionerMode.None ? _airConditionerData.iMode : (int)mode); command.enabledZones = _airConditionerCommand.enabledZones; } MQTT.SendMessage("actron/aircon/mode", (mode != AirConditionerMode.None ? Enum.GetName(typeof(ModeMQTT), mode).ToLower() : "off")); PostCommand(lRequestId, "System", command); }
public static void Start() { IConfigurationRoot configuration; IWebHost webHost; Logging.WriteDebugLog("Service.Start()"); try { configuration = new ConfigurationBuilder().AddJsonFile(_strConfigFile, false, true).Build(); } catch (Exception eException) { Logging.WriteDebugLogError("Service.Start()", eException, "Unable to build configuration instance."); return; } bool.TryParse(configuration["RegisterZoneTemperatures"] ?? "false", out _bRegisterZoneTemperatures); Logging.WriteDebugLog("Service.Start() RegisterZoneTemperatures: {0}", _bRegisterZoneTemperatures); MQTT.StartMQTT(configuration["MQTTBroker"] ?? "core-mosquitto", _strServiceName, configuration["MQTTUser"] ?? "", configuration["MQTTPassword"] ?? "", MQTTProcessor); AirConditioner.Configure(configuration); MQTTRegister(); try { webHost = new WebHostBuilder().UseKestrel().UseStartup <ASPNETCoreStartup>().UseConfiguration(configuration).UseUrls($"http://*:80/").Build(); } catch (Exception eException) { Logging.WriteDebugLogError("Service.Start()", eException, "Unable to build Kestrel instance."); return; } webHost.Run(); }
public static void Stop() { Logging.WriteDebugLog("Service.Stop()"); MQTT.StopMQTT(); }
public static void PostData(AirConditionerData data) { string strZones; if (!_bDataReceived) { Logging.WriteDebugLog("AirConditioner.PostData() First Data Received"); _bDataReceived = true; } else { Logging.WriteDebugLog("AirConditioner.PostData()"); } // Update read/write fields if not suppressed if (DateTime.Now.Subtract(_dtLastCommand) < TimeSpan.FromSeconds(_iSuppressTimer)) { Logging.WriteDebugLog("AirConditioner.PostData() Suppressing Data Update"); } else { lock (_oLockData) { _airConditionerData.bOn = data.bOn; _airConditionerData.bZone1 = data.bZone1; _airConditionerData.bZone2 = data.bZone2; _airConditionerData.bZone3 = data.bZone3; _airConditionerData.bZone4 = data.bZone4; _airConditionerData.bZone5 = data.bZone5; _airConditionerData.bZone6 = data.bZone6; _airConditionerData.bZone7 = data.bZone7; _airConditionerData.bZone8 = data.bZone8; _airConditionerData.dblSetTemperature = data.dblSetTemperature; _airConditionerData.iFanSpeed = data.iFanSpeed; _airConditionerData.iMode = data.iMode; MQTT.SendMessage("actron/aircon/fanmode", Enum.GetName(typeof(FanSpeed), _airConditionerData.iFanSpeed).ToLower()); MQTT.SendMessage("actron/aircon/mode", (_airConditionerData.bOn ? Enum.GetName(typeof(ModeMQTT), _airConditionerData.iMode).ToLower() : "off")); MQTT.SendMessage("actron/aircon/settemperature", _airConditionerData.dblSetTemperature.ToString()); // Need to move to an array instead of 8 x boolean. if (_dZones.Count >= 1) { MQTT.SendMessage("actron/aircon/zone1", _airConditionerData.bZone1 ? "ON" : "OFF"); } if (_dZones.Count >= 2) { MQTT.SendMessage("actron/aircon/zone2", _airConditionerData.bZone2 ? "ON" : "OFF"); } if (_dZones.Count >= 3) { MQTT.SendMessage("actron/aircon/zone3", _airConditionerData.bZone3 ? "ON" : "OFF"); } if (_dZones.Count >= 4) { MQTT.SendMessage("actron/aircon/zone4", _airConditionerData.bZone4 ? "ON" : "OFF"); } if (_dZones.Count >= 5) { MQTT.SendMessage("actron/aircon/zone5", _airConditionerData.bZone5 ? "ON" : "OFF"); } if (_dZones.Count >= 6) { MQTT.SendMessage("actron/aircon/zone6", _airConditionerData.bZone6 ? "ON" : "OFF"); } if (_dZones.Count >= 7) { MQTT.SendMessage("actron/aircon/zone7", _airConditionerData.bZone7 ? "ON" : "OFF"); } if (_dZones.Count >= 8) { MQTT.SendMessage("actron/aircon/zone8", _airConditionerData.bZone8 ? "ON" : "OFF"); } } } // Update read only fields on each post lock (_oLockData) { _airConditionerData.dtLastUpdate = DateTime.Now; _airConditionerData.bESPOn = data.bESPOn; _airConditionerData.iCompressorActivity = data.iCompressorActivity; _airConditionerData.iFanContinuous = data.iFanContinuous; _airConditionerData.dblRoomTemperature = data.dblRoomTemperature; _airConditionerData.dblZone1Temperature = data.dblZone1Temperature; _airConditionerData.dblZone2Temperature = data.dblZone2Temperature; _airConditionerData.dblZone3Temperature = data.dblZone3Temperature; _airConditionerData.dblZone4Temperature = data.dblZone4Temperature; _airConditionerData.dblZone5Temperature = data.dblZone5Temperature; _airConditionerData.dblZone6Temperature = data.dblZone6Temperature; _airConditionerData.dblZone7Temperature = data.dblZone7Temperature; _airConditionerData.dblZone8Temperature = data.dblZone8Temperature; _airConditionerData.strErrorCode = data.strErrorCode; MQTT.SendMessage("actron/aircon/temperature", _airConditionerData.dblRoomTemperature.ToString()); if (Service.RegisterZoneTemperatures) { if (_dZones.Count >= 1) { MQTT.SendMessage("actron/aircon/zone1/temperature", _airConditionerData.dblZone1Temperature.ToString()); } if (_dZones.Count >= 2) { MQTT.SendMessage("actron/aircon/zone2/temperature", _airConditionerData.dblZone2Temperature.ToString()); } if (_dZones.Count >= 3) { MQTT.SendMessage("actron/aircon/zone3/temperature", _airConditionerData.dblZone3Temperature.ToString()); } if (_dZones.Count >= 4) { MQTT.SendMessage("actron/aircon/zone4/temperature", _airConditionerData.dblZone4Temperature.ToString()); } if (_dZones.Count >= 5) { MQTT.SendMessage("actron/aircon/zone5/temperature", _airConditionerData.dblZone5Temperature.ToString()); } if (_dZones.Count >= 6) { MQTT.SendMessage("actron/aircon/zone6/temperature", _airConditionerData.dblZone6Temperature.ToString()); } if (_dZones.Count >= 7) { MQTT.SendMessage("actron/aircon/zone7/temperature", _airConditionerData.dblZone7Temperature.ToString()); } if (_dZones.Count >= 8) { MQTT.SendMessage("actron/aircon/zone8/temperature", _airConditionerData.dblZone8Temperature.ToString()); } } switch (_airConditionerData.iCompressorActivity) { case 0: MQTT.SendMessage("actron/aircon/compressor", "heating"); break; case 1: MQTT.SendMessage("actron/aircon/compressor", "cooling"); break; case 2: if (_airConditionerData.bOn) { MQTT.SendMessage("actron/aircon/compressor", "idle"); } else { MQTT.SendMessage("actron/aircon/compressor", "off"); } break; default: MQTT.SendMessage("actron/aircon/compressor", "off"); break; } } lock (_oLockCommand) { if (!_bPendingCommand) { if (DateTime.Now.Subtract(_dtLastCommand) < TimeSpan.FromSeconds(_iSuppressTimer)) { Logging.WriteDebugLog("AirConditioner.PostData() Suppressing Command Update"); } else if (_airConditionerCommand.amOn != _airConditionerData.bOn || _airConditionerCommand.fanSpeed != _airConditionerData.iFanSpeed || _airConditionerCommand.mode != _airConditionerData.iMode || _airConditionerCommand.tempTarget != _airConditionerData.dblSetTemperature) { Logging.WriteDebugLog("AirConditioner.PostData() Updating Command"); _airConditionerCommand.amOn = _airConditionerData.bOn; _airConditionerCommand.fanSpeed = _airConditionerData.iFanSpeed; _airConditionerCommand.mode = _airConditionerData.iMode; _airConditionerCommand.tempTarget = _airConditionerData.dblSetTemperature; } } if (DateTime.Now.Subtract(_dtLastCommand) < TimeSpan.FromSeconds(_iSuppressTimer)) { Logging.WriteDebugLog("AirConditioner.PostData() Suppressing Zone Update"); } else if (!_bPendingZone) { strZones = string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", _airConditionerData.bZone1 ? "1" : "0", _airConditionerData.bZone2 ? "1" : "0", _airConditionerData.bZone3 ? "1" : "0", _airConditionerData.bZone4 ? "1" : "0", _airConditionerData.bZone5 ? "1" : "0", _airConditionerData.bZone6 ? "1" : "0", _airConditionerData.bZone7 ? "1" : "0", _airConditionerData.bZone8 ? "1" : "0"); if (_airConditionerCommand.enabledZones != strZones) { Logging.WriteDebugLog("AirConditioner.PostData() Updating Zones"); _airConditionerCommand.enabledZones = strZones; } } } MQTT.Update(null); }