diff --git a/OmniLinkBridge/MQTT/AreaState.cs b/OmniLinkBridge/MQTT/AreaState.cs
new file mode 100644
index 0000000..7e90746
--- /dev/null
+++ b/OmniLinkBridge/MQTT/AreaState.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OmniLinkBridge.MQTT
+{
+ public class AreaState
+ {
+ public string mode { get; set; }
+ public bool arming { get; set; }
+ public bool burglary_alarm { get; set; }
+ public bool fire_alarm { get; set; }
+ public bool gas_alarm { get; set; }
+ public bool auxiliary_alarm { get; set; }
+ public bool freeze_alarm { get; set; }
+ public bool water_alarm { get; set; }
+ public bool duress_alarm { get; set; }
+ public bool temperature_alarm { get; set; }
+ }
+}
diff --git a/OmniLinkBridge/MQTT/BinarySensor.cs b/OmniLinkBridge/MQTT/BinarySensor.cs
index 4e82da8..7565b02 100644
--- a/OmniLinkBridge/MQTT/BinarySensor.cs
+++ b/OmniLinkBridge/MQTT/BinarySensor.cs
@@ -14,17 +14,23 @@ namespace OmniLinkBridge.MQTT
public enum DeviceClass
{
battery,
+ cold,
door,
garage_door,
gas,
+ heat,
moisture,
motion,
problem,
+ safety,
smoke,
window
}
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public DeviceClass? device_class { get; set; }
+
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public string value_template { get; set; }
}
}
diff --git a/OmniLinkBridge/MQTT/MappingExtensions.cs b/OmniLinkBridge/MQTT/MappingExtensions.cs
index 4517730..6436981 100644
--- a/OmniLinkBridge/MQTT/MappingExtensions.cs
+++ b/OmniLinkBridge/MQTT/MappingExtensions.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HAI_Shared;
+using Newtonsoft.Json;
namespace OmniLinkBridge.MQTT
{
@@ -25,7 +26,9 @@ namespace OmniLinkBridge.MQTT
public static string ToState(this clsArea area)
{
- if (area.AreaBurglaryAlarmText != "OK")
+ if (area.AreaAlarms.IsBitSet(0) || // Burgulary
+ area.AreaAlarms.IsBitSet(3) || // Auxiliary
+ area.AreaAlarms.IsBitSet(6)) // Duress
return "triggered";
else if (area.ExitTimer > 0)
return "pending";
@@ -52,7 +55,9 @@ namespace OmniLinkBridge.MQTT
public static string ToBasicState(this clsArea area)
{
- if (area.AreaBurglaryAlarmText != "OK")
+ if (area.AreaAlarms.IsBitSet(0) || // Burgulary
+ area.AreaAlarms.IsBitSet(3) || // Auxiliary
+ area.AreaAlarms.IsBitSet(6)) // Duress
return "triggered";
else if (area.ExitTimer > 0)
return "pending";
@@ -74,6 +79,130 @@ namespace OmniLinkBridge.MQTT
}
}
+ public static BinarySensor ToConfigBurglary(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Burglary";
+ ret.device_class = BinarySensor.DeviceClass.safety;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.burglary_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigFire(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Fire";
+ ret.device_class = BinarySensor.DeviceClass.smoke;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.fire_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigGas(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Gas";
+ ret.device_class = BinarySensor.DeviceClass.gas;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.gas_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigAux(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Auxiliary";
+ ret.device_class = BinarySensor.DeviceClass.problem;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.burglary_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigFreeze(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Freeze";
+ ret.device_class = BinarySensor.DeviceClass.cold;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.freeze_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigWater(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Water";
+ ret.device_class = BinarySensor.DeviceClass.moisture;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.water_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigDuress(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Duress";
+ ret.device_class = BinarySensor.DeviceClass.safety;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.duress_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static BinarySensor ToConfigTemp(this clsArea area)
+ {
+ BinarySensor ret = new BinarySensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Temp";
+ ret.device_class = BinarySensor.DeviceClass.heat;
+ ret.state_topic = area.ToTopic(Topic.json_state);
+ ret.value_template = "{% if value_json.temperature_alarm %} ON {%- else -%} OFF {%- endif %}";
+ return ret;
+ }
+
+ public static string ToJsonState(this clsArea area)
+ {
+ AreaState state = new AreaState()
+ {
+ arming = area.ExitTimer > 0,
+ burglary_alarm = area.AreaAlarms.IsBitSet(0),
+ fire_alarm = area.AreaAlarms.IsBitSet(1),
+ gas_alarm = area.AreaAlarms.IsBitSet(2),
+ auxiliary_alarm = area.AreaAlarms.IsBitSet(3),
+ freeze_alarm = area.AreaAlarms.IsBitSet(4),
+ water_alarm = area.AreaAlarms.IsBitSet(5),
+ duress_alarm = area.AreaAlarms.IsBitSet(6),
+ temperature_alarm = area.AreaAlarms.IsBitSet(7)
+ };
+
+ switch (area.AreaMode)
+ {
+ case enuSecurityMode.Night:
+ state.mode = "night";
+ break;
+ case enuSecurityMode.NightDly:
+ state.mode = "night_delay";
+ break;
+ case enuSecurityMode.Day:
+ state.mode = "home";
+ break;
+ case enuSecurityMode.DayInst:
+ state.mode = "home_instant";
+ break;
+ case enuSecurityMode.Away:
+ state.mode = "away";
+ break;
+ case enuSecurityMode.Vacation:
+ state.mode = "vacation";
+ break;
+ case enuSecurityMode.Off:
+ default:
+ state.mode = "off";
+ break;
+ }
+
+ return JsonConvert.SerializeObject(state);
+ }
+
public static string ToTopic(this clsZone zone, Topic topic)
{
return $"{Global.mqtt_prefix}/zone{zone.Number.ToString()}/{topic.ToString()}";
@@ -250,10 +379,20 @@ namespace OmniLinkBridge.MQTT
return $"{Global.mqtt_prefix}/thermostat{thermostat.Number.ToString()}/{topic.ToString()}";
}
+ public static Sensor ToConfigTemp(this clsThermostat zone)
+ {
+ Sensor ret = new Sensor();
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Temp";
+ ret.device_class = Sensor.DeviceClass.temperature;
+ ret.state_topic = zone.ToTopic(Topic.current_temperature);
+ ret.unit_of_measurement = "°F";
+ return ret;
+ }
+
public static Sensor ToConfigHumidity(this clsThermostat zone)
{
Sensor ret = new Sensor();
- ret.name = Global.mqtt_discovery_name_prefix + zone.Name;
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Humidity";
ret.device_class = Sensor.DeviceClass.humidity;
ret.state_topic = zone.ToTopic(Topic.current_humidity);
ret.unit_of_measurement = "%";
diff --git a/OmniLinkBridge/MQTT/Topics.cs b/OmniLinkBridge/MQTT/Topics.cs
index 3af3003..cd1858e 100644
--- a/OmniLinkBridge/MQTT/Topics.cs
+++ b/OmniLinkBridge/MQTT/Topics.cs
@@ -26,6 +26,7 @@ namespace OmniLinkBridge.MQTT
public static Topic command { get { return new Topic("command"); } }
public static Topic basic_state { get { return new Topic("basic_state"); } }
+ public static Topic json_state { get { return new Topic("json_state"); } }
public static Topic brightness_state { get { return new Topic("brightness_state"); } }
public static Topic brightness_command { get { return new Topic("brightness_command"); } }
diff --git a/OmniLinkBridge/Modules/MQTTModule.cs b/OmniLinkBridge/Modules/MQTTModule.cs
index 810bb9f..44028ca 100644
--- a/OmniLinkBridge/Modules/MQTTModule.cs
+++ b/OmniLinkBridge/Modules/MQTTModule.cs
@@ -290,6 +290,14 @@ namespace OmniLinkBridge.Modules
if (area.DefaultProperties == true)
{
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}fire/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}gas/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}aux/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}freeze/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}water/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}duress/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}temp/config", null, MqttQualityOfServiceLevel.AtMostOnce, true);
continue;
}
@@ -297,6 +305,22 @@ namespace OmniLinkBridge.Modules
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config",
JsonConvert.SerializeObject(area.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config",
+ JsonConvert.SerializeObject(area.ToConfigBurglary()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}fire/config",
+ JsonConvert.SerializeObject(area.ToConfigFire()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}gas/config",
+ JsonConvert.SerializeObject(area.ToConfigGas()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}aux/config",
+ JsonConvert.SerializeObject(area.ToConfigAux()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}freeze/config",
+ JsonConvert.SerializeObject(area.ToConfigFreeze()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}water/config",
+ JsonConvert.SerializeObject(area.ToConfigWater()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}duress/config",
+ JsonConvert.SerializeObject(area.ToConfigDuress()), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}temp/config",
+ JsonConvert.SerializeObject(area.ToConfigTemp()), MqttQualityOfServiceLevel.AtMostOnce, true);
}
}
@@ -367,6 +391,7 @@ namespace OmniLinkBridge.Modules
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()}temp/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;
}
@@ -375,6 +400,8 @@ namespace OmniLinkBridge.Modules
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()}temp/config",
+ JsonConvert.SerializeObject(thermostat.ToConfigTemp()), 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);
}
@@ -452,6 +479,7 @@ namespace OmniLinkBridge.Modules
{
MqttClient.PublishAsync(area.ToTopic(Topic.state), area.ToState(), MqttQualityOfServiceLevel.AtMostOnce, true);
MqttClient.PublishAsync(area.ToTopic(Topic.basic_state), area.ToBasicState(), MqttQualityOfServiceLevel.AtMostOnce, true);
+ MqttClient.PublishAsync(area.ToTopic(Topic.json_state), area.ToJsonState(), MqttQualityOfServiceLevel.AtMostOnce, true);
}
private void PublishZoneState(clsZone zone)
diff --git a/OmniLinkBridge/OmniLinkBridge.csproj b/OmniLinkBridge/OmniLinkBridge.csproj
index 43b7675..e6e61f7 100644
--- a/OmniLinkBridge/OmniLinkBridge.csproj
+++ b/OmniLinkBridge/OmniLinkBridge.csproj
@@ -77,6 +77,7 @@
+