mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2025-05-07 09:23:11 +00:00
455 lines
24 KiB
C#
455 lines
24 KiB
C#
using HAI_Shared;
|
|
using OmniLinkBridge.OmniLink;
|
|
using log4net;
|
|
using MQTTnet;
|
|
using MQTTnet.Client;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using Newtonsoft.Json;
|
|
using MQTTnet.Extensions.ManagedClient;
|
|
using OmniLinkBridge.MQTT;
|
|
using MQTTnet.Protocol;
|
|
using System.Text.RegularExpressions;
|
|
using System.Text;
|
|
|
|
namespace OmniLinkBridge.Modules
|
|
{
|
|
public class MQTTModule : IModule
|
|
{
|
|
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private OmniLinkII OmniLink { get; set; }
|
|
private IManagedMqttClient MqttClient { get; set; }
|
|
|
|
private Regex regexTopic = new Regex(Global.mqtt_prefix + "/([A-Za-z]+)([0-9]+)/(.*)", RegexOptions.Compiled);
|
|
|
|
private readonly AutoResetEvent trigger = new AutoResetEvent(false);
|
|
|
|
public MQTTModule(OmniLinkII omni)
|
|
{
|
|
OmniLink = omni;
|
|
OmniLink.OnConnect += OmniLink_OnConnect;
|
|
OmniLink.OnAreaStatus += Omnilink_OnAreaStatus;
|
|
OmniLink.OnZoneStatus += Omnilink_OnZoneStatus;
|
|
OmniLink.OnUnitStatus += Omnilink_OnUnitStatus;
|
|
OmniLink.OnThermostatStatus += Omnilink_OnThermostatStatus;
|
|
}
|
|
|
|
public void Startup()
|
|
{
|
|
MqttClientOptionsBuilder options = new MqttClientOptionsBuilder()
|
|
.WithTcpServer(Global.mqtt_server);
|
|
|
|
if (!string.IsNullOrEmpty(Global.mqtt_username))
|
|
options = options
|
|
.WithCredentials(Global.mqtt_username, Global.mqtt_password);
|
|
|
|
ManagedMqttClientOptions manoptions = new ManagedMqttClientOptionsBuilder()
|
|
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
|
|
.WithClientOptions(options.Build())
|
|
.Build();
|
|
|
|
MqttClient = new MqttFactory().CreateManagedMqttClient();
|
|
MqttClient.Connected += (sender, e) => { log.Debug("Connected"); };
|
|
MqttClient.ConnectingFailed += (sender, e) => { log.Debug("Error " + e.Exception.Message); };
|
|
|
|
MqttClient.StartAsync(manoptions);
|
|
|
|
MqttClient.ApplicationMessageReceived += MqttClient_ApplicationMessageReceived;
|
|
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.brightness_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.temperature_heat_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.temperature_cool_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.humidify_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.dehumidify_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.mode_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.fan_mode_command}").Build());
|
|
MqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic($"{Global.mqtt_prefix}/+/{Topic.hold_command}").Build());
|
|
|
|
// Wait until shutdown
|
|
trigger.WaitOne();
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_prefix}/status", "offline", MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
|
|
private void MqttClient_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
|
|
{
|
|
Match match = regexTopic.Match(e.ApplicationMessage.Topic);
|
|
|
|
if (!match.Success)
|
|
return;
|
|
|
|
string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
|
|
|
|
log.Debug($"Received: Type: {match.Groups[1].Value}, Id: {match.Groups[2].Value}, Command: {match.Groups[3].Value}, Value: {payload}");
|
|
|
|
if (match.Groups[1].Value == "area" && ushort.TryParse(match.Groups[2].Value, out ushort areaId) && areaId < OmniLink.Controller.Areas.Count)
|
|
{
|
|
ProcessAreaReceived(OmniLink.Controller.Areas[areaId], match.Groups[3].Value, payload);
|
|
}
|
|
if (match.Groups[1].Value == "zone" && ushort.TryParse(match.Groups[2].Value, out ushort zoneId) && zoneId < OmniLink.Controller.Zones.Count)
|
|
{
|
|
ProcessZoneReceived(OmniLink.Controller.Zones[zoneId], match.Groups[3].Value, payload);
|
|
}
|
|
else if (match.Groups[1].Value == "unit" && ushort.TryParse(match.Groups[2].Value, out ushort unitId) && unitId < OmniLink.Controller.Units.Count)
|
|
{
|
|
ProcessUnitReceived(OmniLink.Controller.Units[unitId], match.Groups[3].Value, payload);
|
|
}
|
|
else if (match.Groups[1].Value == "thermostat" && ushort.TryParse(match.Groups[2].Value, out ushort thermostatId) && thermostatId < OmniLink.Controller.Thermostats.Count)
|
|
{
|
|
ProcessThermostatReceived(OmniLink.Controller.Thermostats[thermostatId], match.Groups[3].Value, payload);
|
|
}
|
|
else if (match.Groups[1].Value == "button" && ushort.TryParse(match.Groups[2].Value, out ushort buttonId) && buttonId < OmniLink.Controller.Buttons.Count)
|
|
{
|
|
ProcessButtonReceived(OmniLink.Controller.Buttons[buttonId], match.Groups[3].Value, payload);
|
|
}
|
|
}
|
|
|
|
private void ProcessAreaReceived(clsArea area, string command, string payload)
|
|
{
|
|
if (string.Compare(command, Topic.command.ToString()) == 0)
|
|
{
|
|
if(string.Compare(payload, "arm_home", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to home");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityDay, 0, (ushort)area.Number);
|
|
}
|
|
else if (string.Compare(payload, "arm_away", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to away");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityAway, 0, (ushort)area.Number);
|
|
}
|
|
else if (string.Compare(payload, "arm_night", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to night");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityNight, 0, (ushort)area.Number);
|
|
}
|
|
else if (string.Compare(payload, "disarm", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to disarm");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityOff, 0, (ushort)area.Number);
|
|
}
|
|
// The below aren't supported by Home Assistant
|
|
else if (string.Compare(payload, "arm_home_instant", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to home instant");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityDyi, 0, (ushort)area.Number);
|
|
}
|
|
else if (string.Compare(payload, "arm_night_delay", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to night delay");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityNtd, 0, (ushort)area.Number);
|
|
}
|
|
else if (string.Compare(payload, "arm_vacation", true) == 0)
|
|
{
|
|
log.Debug("SetArea: " + area.Number + " to vacation");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityVac, 0, (ushort)area.Number);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessZoneReceived(clsZone zone, string command, string payload)
|
|
{
|
|
if (string.Compare(command, Topic.command.ToString()) == 0)
|
|
{
|
|
if (string.Compare(payload, "bypass", true) == 0)
|
|
{
|
|
log.Debug("SetZone: " + zone.Number + " to " + payload);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Bypass, 0, (ushort)zone.Number);
|
|
}
|
|
else if (string.Compare(payload, "restore", true) == 0)
|
|
{
|
|
log.Debug("SetZone: " + zone.Number + " to " + payload);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Restore, 0, (ushort)zone.Number);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessUnitReceived(clsUnit unit, string command, string payload)
|
|
{
|
|
if (string.Compare(command, Topic.command.ToString()) == 0 && (payload == "ON" || payload == "OFF"))
|
|
{
|
|
if (unit.ToState() != payload)
|
|
{
|
|
log.Debug("SetUnit: " + unit.Number + " to " + payload);
|
|
|
|
if (payload == "ON")
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.On, 0, (ushort)unit.Number);
|
|
else
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Off, 0, (ushort)unit.Number);
|
|
}
|
|
}
|
|
else if (string.Compare(command, Topic.brightness_command.ToString()) == 0 && Int32.TryParse(payload, out int unitValue))
|
|
{
|
|
log.Debug("SetUnit: " + unit.Number + " to " + payload + "%");
|
|
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Level, BitConverter.GetBytes(unitValue)[0], (ushort)unit.Number);
|
|
|
|
// Force status change instead of waiting on controller to update
|
|
// Home Assistant sends brightness immediately followed by ON,
|
|
// which will cause light to go to 100% brightness
|
|
unit.Status = (byte)(100 + unitValue);
|
|
}
|
|
}
|
|
|
|
private void ProcessThermostatReceived(clsThermostat thermostat, string command, string payload)
|
|
{
|
|
if (string.Compare(command, Topic.temperature_heat_command.ToString()) == 0 && double.TryParse(payload, out double tempLow))
|
|
{
|
|
int temp = tempLow.ToCelsius().ToOmniTemp();
|
|
log.Debug("SetThermostatHeatSetpoint: " + thermostat.Number + " to " + payload + "F (" + temp + ")");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SetLowSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.temperature_cool_command.ToString()) == 0 && double.TryParse(payload, out double tempHigh))
|
|
{
|
|
int temp = tempHigh.ToCelsius().ToOmniTemp();
|
|
log.Debug("SetThermostatCoolSetpoint: " + thermostat.Number + " to " + payload + "F (" + temp + ")");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SetHighSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.humidify_command.ToString()) == 0 && double.TryParse(payload, out double humidify))
|
|
{
|
|
int level = humidify.ToCelsius().ToOmniTemp();
|
|
log.Debug("SetThermostatHumidifySetpoint: " + thermostat.Number + " to " + payload + "% (" + level + ")");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SetHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.dehumidify_command.ToString()) == 0 && double.TryParse(payload, out double dehumidify))
|
|
{
|
|
int level = dehumidify.ToCelsius().ToOmniTemp();
|
|
log.Debug("SetThermostatDehumidifySetpoint: " + thermostat.Number + " to " + payload + "% (" + level + ")");
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.SetDeHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.mode_command.ToString()) == 0 && Enum.TryParse(payload, true, out enuThermostatMode mode))
|
|
{
|
|
log.Debug("SetThermostatMode: " + thermostat.Number + " to " + payload);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Mode, BitConverter.GetBytes((int)mode)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.fan_mode_command.ToString()) == 0 && Enum.TryParse(payload, true, out enuThermostatFanMode fanMode))
|
|
{
|
|
log.Debug("SetThermostatFanMode: " + thermostat.Number + " to " + payload);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes((int)fanMode)[0], (ushort)thermostat.Number);
|
|
}
|
|
else if (string.Compare(command, Topic.hold_command.ToString()) == 0 && Enum.TryParse(payload, true, out enuThermostatHoldMode holdMode))
|
|
{
|
|
log.Debug("SetThermostatHold: " + thermostat.Number + " to " + payload);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes((int)holdMode)[0], (ushort)thermostat.Number);
|
|
}
|
|
}
|
|
|
|
private void ProcessButtonReceived(clsButton button, string command, string payload)
|
|
{
|
|
if (string.Compare(command, Topic.command.ToString()) == 0 && payload == "ON")
|
|
{
|
|
log.Debug("PushButton: " + button.Number);
|
|
OmniLink.Controller.SendCommand(enuUnitCommand.Button, 0, (ushort)button.Number);
|
|
}
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
trigger.Set();
|
|
}
|
|
|
|
private void OmniLink_OnConnect(object sender, EventArgs e)
|
|
{
|
|
PublishConfig();
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_prefix}/status", "online", MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
|
|
private void PublishConfig()
|
|
{
|
|
PublishAreas();
|
|
PublishZones();
|
|
PublishUnits();
|
|
PublishThermostats();
|
|
PublishButtons();
|
|
}
|
|
|
|
private void PublishAreas()
|
|
{
|
|
log.Debug("Publishing areas");
|
|
|
|
for (ushort i = 1; i < OmniLink.Controller.Areas.Count; i++)
|
|
{
|
|
clsArea area = OmniLink.Controller.Areas[i];
|
|
|
|
if (area.DefaultProperties == true)
|
|
{
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
continue;
|
|
}
|
|
|
|
PublishAreaState(area);
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(area.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
|
|
private void PublishZones()
|
|
{
|
|
log.Debug("Publishing zones");
|
|
|
|
for (ushort i = 1; i < OmniLink.Controller.Zones.Count; i++)
|
|
{
|
|
clsZone zone = OmniLink.Controller.Zones[i];
|
|
|
|
if (zone.DefaultProperties == true || Global.mqtt_discovery_ignore_zones.Contains(zone.Number))
|
|
{
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}temp/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}humidity/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
continue;
|
|
}
|
|
|
|
PublishZoneState(zone);
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(zone.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(zone.ToConfigSensor()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
|
|
if (zone.IsTemperatureZone())
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}temp/config",
|
|
JsonConvert.SerializeObject(zone.ToConfigTemp()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
else if (zone.IsHumidityZone())
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}humidity/config",
|
|
JsonConvert.SerializeObject(zone.ToConfigHumidity()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
|
|
private void PublishUnits()
|
|
{
|
|
log.Debug("Publishing units");
|
|
|
|
for (ushort i = 1; i < OmniLink.Controller.Units.Count; i++)
|
|
{
|
|
string type = i < 385 ? "light" : "switch";
|
|
|
|
clsUnit unit = OmniLink.Controller.Units[i];
|
|
|
|
if (unit.DefaultProperties == true || Global.mqtt_discovery_ignore_units.Contains(unit.Number))
|
|
{
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/{type}/{Global.mqtt_prefix}/unit{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
continue;
|
|
}
|
|
|
|
PublishUnitState(unit);
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/{type}/{Global.mqtt_prefix}/unit{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(unit.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
|
|
private void PublishThermostats()
|
|
{
|
|
log.Debug("Publishing thermostats");
|
|
|
|
for (ushort i = 1; i < OmniLink.Controller.Thermostats.Count; i++)
|
|
{
|
|
clsThermostat thermostat = OmniLink.Controller.Thermostats[i];
|
|
|
|
if (thermostat.DefaultProperties == true)
|
|
{
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}humidity/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
continue;
|
|
}
|
|
|
|
PublishThermostatState(thermostat);
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(thermostat.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}humidity/config",
|
|
JsonConvert.SerializeObject(thermostat.ToConfigHumidity()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
|
|
private void PublishButtons()
|
|
{
|
|
log.Debug("Publishing buttons");
|
|
|
|
for (ushort i = 1; i < OmniLink.Controller.Buttons.Count; i++)
|
|
{
|
|
clsButton button = OmniLink.Controller.Buttons[i];
|
|
|
|
if (button.DefaultProperties == true)
|
|
{
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
continue;
|
|
}
|
|
|
|
// Buttons are always off
|
|
MqttClient.PublishAsync(button.ToTopic(Topic.state), "OFF", MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
|
|
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config",
|
|
JsonConvert.SerializeObject(button.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
|
|
private void Omnilink_OnAreaStatus(object sender, AreaStatusEventArgs e)
|
|
{
|
|
PublishAreaState(e.Area);
|
|
}
|
|
|
|
private void Omnilink_OnZoneStatus(object sender, ZoneStatusEventArgs e)
|
|
{
|
|
PublishZoneState(e.Zone);
|
|
}
|
|
|
|
private void Omnilink_OnUnitStatus(object sender, UnitStatusEventArgs e)
|
|
{
|
|
PublishUnitState(e.Unit);
|
|
}
|
|
|
|
private void Omnilink_OnThermostatStatus(object sender, ThermostatStatusEventArgs e)
|
|
{
|
|
if(!e.EventTimer)
|
|
PublishThermostatState(e.Thermostat);
|
|
}
|
|
|
|
private void PublishAreaState(clsArea area)
|
|
{
|
|
MqttClient.PublishAsync(area.ToTopic(Topic.state), area.ToState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(area.ToTopic(Topic.basic_state), area.ToBasicState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
|
|
private void PublishZoneState(clsZone zone)
|
|
{
|
|
MqttClient.PublishAsync(zone.ToTopic(Topic.state), zone.ToState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(zone.ToTopic(Topic.basic_state), zone.ToBasicState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
|
|
if(zone.IsTemperatureZone())
|
|
MqttClient.PublishAsync(zone.ToTopic(Topic.current_temperature), zone.TempText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
else if (zone.IsHumidityZone())
|
|
MqttClient.PublishAsync(zone.ToTopic(Topic.current_humidity), zone.TempText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
|
|
private void PublishUnitState(clsUnit unit)
|
|
{
|
|
MqttClient.PublishAsync(unit.ToTopic(Topic.state), unit.ToState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
|
|
if(unit.Number < 385)
|
|
MqttClient.PublishAsync(unit.ToTopic(Topic.brightness_state), unit.ToBrightnessState().ToString(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
|
|
private void PublishThermostatState(clsThermostat thermostat)
|
|
{
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.current_operation), thermostat.ToOperationState(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.current_temperature), thermostat.TempText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.current_humidity), thermostat.HumidityText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.temperature_heat_state), thermostat.HeatSetpointText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.temperature_cool_state), thermostat.CoolSetpointText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.humidify_state), thermostat.HumidifySetpointText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.dehumidify_state), thermostat.DehumidifySetpointText(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.mode_state), thermostat.ModeText().ToLower(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.fan_mode_state), thermostat.FanModeText().ToLower(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
MqttClient.PublishAsync(thermostat.ToTopic(Topic.hold_state), thermostat.HoldStatusText().ToLower(), MqttQualityOfServiceLevel.AtMostOnce, true);
|
|
}
|
|
}
|
|
}
|