diff --git a/OmniLinkBridge/MQTT/Device.cs b/OmniLinkBridge/MQTT/Device.cs
index 6496731..e917365 100644
--- a/OmniLinkBridge/MQTT/Device.cs
+++ b/OmniLinkBridge/MQTT/Device.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
+using OmniLinkBridge.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,11 +10,16 @@ namespace OmniLinkBridge.MQTT
{
public class Device
{
+ public string unique_id { get; set; }
+
public string name { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string state_topic { get; set; }
public string availability_topic { get; set; } = $"{Global.mqtt_prefix}/status";
+
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public DeviceRegistry device { get; set; } = MQTTModule.MqttDeviceRegistry;
}
}
diff --git a/OmniLinkBridge/MQTT/DeviceRegistry.cs b/OmniLinkBridge/MQTT/DeviceRegistry.cs
new file mode 100644
index 0000000..4669311
--- /dev/null
+++ b/OmniLinkBridge/MQTT/DeviceRegistry.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OmniLinkBridge.MQTT
+{
+ public class DeviceRegistry
+ {
+ public string identifiers { get; set; }
+ public string name { get; set; }
+ public string sw_version { get; set; }
+ public string model { get; set; }
+ public string manufacturer { get; set; }
+ }
+}
diff --git a/OmniLinkBridge/MQTT/MappingExtensions.cs b/OmniLinkBridge/MQTT/MappingExtensions.cs
index 9f49096..6463a7d 100644
--- a/OmniLinkBridge/MQTT/MappingExtensions.cs
+++ b/OmniLinkBridge/MQTT/MappingExtensions.cs
@@ -18,6 +18,7 @@ namespace OmniLinkBridge.MQTT
public static Alarm ToConfig(this clsArea area)
{
Alarm ret = new Alarm();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}";
ret.name = Global.mqtt_discovery_name_prefix + area.Name;
ret.state_topic = area.ToTopic(Topic.basic_state);
ret.command_topic = area.ToTopic(Topic.command);
@@ -82,6 +83,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigBurglary(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}burglary";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Burglary";
ret.device_class = BinarySensor.DeviceClass.safety;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -92,6 +94,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigFire(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}fire";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Fire";
ret.device_class = BinarySensor.DeviceClass.smoke;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -102,6 +105,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigGas(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}gas";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Gas";
ret.device_class = BinarySensor.DeviceClass.gas;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -112,6 +116,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigAux(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}auxiliary";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Auxiliary";
ret.device_class = BinarySensor.DeviceClass.problem;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -122,6 +127,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigFreeze(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}freeze";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Freeze";
ret.device_class = BinarySensor.DeviceClass.cold;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -132,6 +138,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigWater(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}water";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Water";
ret.device_class = BinarySensor.DeviceClass.moisture;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -142,6 +149,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigDuress(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}duress";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Duress";
ret.device_class = BinarySensor.DeviceClass.safety;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -152,6 +160,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfigTemp(this clsArea area)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}area{area.Number.ToString()}temp";
ret.name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Temp";
ret.device_class = BinarySensor.DeviceClass.heat;
ret.state_topic = area.ToTopic(Topic.json_state);
@@ -211,6 +220,7 @@ namespace OmniLinkBridge.MQTT
public static Sensor ToConfigTemp(this clsZone zone, enuTempFormat format)
{
Sensor ret = new Sensor();
+ ret.unique_id = $"{Global.mqtt_prefix}zone{zone.Number.ToString()}temp";
ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Temp";
ret.device_class = Sensor.DeviceClass.temperature;
ret.state_topic = zone.ToTopic(Topic.current_temperature);
@@ -221,6 +231,7 @@ namespace OmniLinkBridge.MQTT
public static Sensor ToConfigHumidity(this clsZone zone)
{
Sensor ret = new Sensor();
+ ret.unique_id = $"{Global.mqtt_prefix}zone{zone.Number.ToString()}humidity";
ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Humidity";
ret.device_class = Sensor.DeviceClass.humidity;
ret.state_topic = zone.ToTopic(Topic.current_humidity);
@@ -231,6 +242,7 @@ namespace OmniLinkBridge.MQTT
public static Sensor ToConfigSensor(this clsZone zone)
{
Sensor ret = new Sensor();
+ ret.unique_id = $"{Global.mqtt_prefix}zone{zone.Number.ToString()}";
ret.name = Global.mqtt_discovery_name_prefix + zone.Name;
switch (zone.ZoneType)
@@ -270,6 +282,7 @@ namespace OmniLinkBridge.MQTT
public static BinarySensor ToConfig(this clsZone zone)
{
BinarySensor ret = new BinarySensor();
+ ret.unique_id = $"{Global.mqtt_prefix}zone{zone.Number.ToString()}binary";
ret.name = Global.mqtt_discovery_name_prefix + zone.Name;
Global.mqtt_discovery_override_zone.TryGetValue(zone.Number, out OverrideZone override_zone);
@@ -342,6 +355,7 @@ namespace OmniLinkBridge.MQTT
public static Light ToConfig(this clsUnit unit)
{
Light ret = new Light();
+ ret.unique_id = $"{Global.mqtt_prefix}unit{unit.Number.ToString()}light";
ret.name = Global.mqtt_discovery_name_prefix + unit.Name;
ret.state_topic = unit.ToTopic(Topic.state);
ret.command_topic = unit.ToTopic(Topic.command);
@@ -353,6 +367,7 @@ namespace OmniLinkBridge.MQTT
public static Switch ToConfigSwitch(this clsUnit unit)
{
Switch ret = new Switch();
+ ret.unique_id = $"{Global.mqtt_prefix}unit{unit.Number.ToString()}switch";
ret.name = Global.mqtt_discovery_name_prefix + unit.Name;
ret.state_topic = unit.ToTopic(Topic.state);
ret.command_topic = unit.ToTopic(Topic.command);
@@ -379,22 +394,24 @@ namespace OmniLinkBridge.MQTT
return $"{Global.mqtt_prefix}/thermostat{thermostat.Number.ToString()}/{topic.ToString()}";
}
- public static Sensor ToConfigTemp(this clsThermostat zone, enuTempFormat format)
+ public static Sensor ToConfigTemp(this clsThermostat thermostat, enuTempFormat format)
{
Sensor ret = new Sensor();
- ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Temp";
+ ret.unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number.ToString()}temp";
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Temp";
ret.device_class = Sensor.DeviceClass.temperature;
- ret.state_topic = zone.ToTopic(Topic.current_temperature);
+ ret.state_topic = thermostat.ToTopic(Topic.current_temperature);
ret.unit_of_measurement = (format == enuTempFormat.Fahrenheit ? "°F" : "°C");
return ret;
}
- public static Sensor ToConfigHumidity(this clsThermostat zone)
+ public static Sensor ToConfigHumidity(this clsThermostat thermostat)
{
Sensor ret = new Sensor();
- ret.name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Humidity";
+ ret.unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number.ToString()}humidity";
+ ret.name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Humidity";
ret.device_class = Sensor.DeviceClass.humidity;
- ret.state_topic = zone.ToTopic(Topic.current_humidity);
+ ret.state_topic = thermostat.ToTopic(Topic.current_humidity);
ret.unit_of_measurement = "%";
return ret;
}
@@ -409,6 +426,7 @@ namespace OmniLinkBridge.MQTT
ret.max_temp = "35";
}
+ ret.unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number.ToString()}";
ret.name = Global.mqtt_discovery_name_prefix + thermostat.Name;
ret.current_temperature_topic = thermostat.ToTopic(Topic.current_temperature);
@@ -449,6 +467,7 @@ namespace OmniLinkBridge.MQTT
public static Switch ToConfig(this clsButton button)
{
Switch ret = new Switch();
+ ret.unique_id = $"{Global.mqtt_prefix}button{button.Number.ToString()}";
ret.name = Global.mqtt_discovery_name_prefix + button.Name;
ret.state_topic = button.ToTopic(Topic.state);
ret.command_topic = button.ToTopic(Topic.command);
diff --git a/OmniLinkBridge/Modules/MQTTModule.cs b/OmniLinkBridge/Modules/MQTTModule.cs
index 3500d9e..be669d7 100644
--- a/OmniLinkBridge/Modules/MQTTModule.cs
+++ b/OmniLinkBridge/Modules/MQTTModule.cs
@@ -20,6 +20,8 @@ namespace OmniLinkBridge.Modules
{
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ public static DeviceRegistry MqttDeviceRegistry { get; set; }
+
private OmniLinkII OmniLink { get; set; }
private IManagedMqttClient MqttClient { get; set; }
private bool ControllerConnected { get; set; }
@@ -57,6 +59,15 @@ namespace OmniLinkBridge.Modules
{
log.Debug("Connected");
+ MqttDeviceRegistry = new DeviceRegistry()
+ {
+ identifiers = Global.mqtt_prefix,
+ name = Global.mqtt_prefix,
+ sw_version = $"{OmniLink.Controller.GetVersionText()} - OmniLinkBridge {Assembly.GetExecutingAssembly().GetName().Version.ToString()}",
+ model = OmniLink.Controller.GetModelText(),
+ manufacturer = "Leviton"
+ };
+
// For the initial connection wait for the controller connected event to publish config
// For subsequent connections publish config immediately
if(ControllerConnected)
diff --git a/OmniLinkBridge/OmniLinkBridge.csproj b/OmniLinkBridge/OmniLinkBridge.csproj
index e6e61f7..83abbd8 100644
--- a/OmniLinkBridge/OmniLinkBridge.csproj
+++ b/OmniLinkBridge/OmniLinkBridge.csproj
@@ -81,6 +81,7 @@
+
diff --git a/README.md b/README.md
index c4d6bd3..3c7f374 100644
--- a/README.md
+++ b/README.md
@@ -85,15 +85,7 @@ To test the API you can use your browser to view a page or PowerShell (see below
- Invoke-WebRequest -Uri "http://localhost:8000/SetUnit" -Method POST -ContentType "application/json" -Body (convertto-json -InputObject @{"id"=1;"value"=100}) -UseBasicParsing
## MQTT
-This module will also publish discovery topics for Home Assistant to auto configure devices. As of writing you will need to add a custom_component override in your Home Assistant config directory for the following pull requests.
-- [Add target temperature low high to MQTT climate](https://github.com/home-assistant/home-assistant/pull/17391/)
-- [Add night arm mode to MQTT alarm control panel](https://github.com/home-assistant/home-assistant/pull/17390/)
-
-```
-mkdir -p custom_components/mqtt
-wget https://raw.githubusercontent.com/home-assistant/home-assistant/dcfcca77d72b0c35cda9950a69f621b4e8cff81b/homeassistant/components/climate/mqtt.py -O custom_components/mqtt/climate.py
-wget https://raw.githubusercontent.com/home-assistant/home-assistant/fa2510f58b40cfea2974530658ee011d984db6c7/homeassistant/components/alarm_control_panel/mqtt.py -O custom_components/mqtt/alarm_control_panel.py
-```
+This module will also publish discovery topics for Home Assistant to auto configure devices.
### Areas
```
@@ -182,12 +174,14 @@ string ON
```
## Change Log
-Version 1.1.4 - 2019-10-28
+Version 1.1.4 - 2019-11-06
- Utilize controller temperature format
-- Ignore invalid temperature for thermostats
-- Always enable first area to fix Omni LTe and Omni IIe
-- Fix MQTT id validation and add notice for areas
+- Don't publish invalid thermostat temperatures
+- Always enable first area to support Omni LTe and Omni IIe
+- Fix MQTT id validation and add notice for publishing to area 0
+- Fix missing last area, zone, unit, thermostat, and button
- Fix compatibility with Home Assistant 0.95.4 MQTT extra keys
+- Add Home Assistant MQTT device registry support
Version 1.1.3 - 2019-02-10
- Publish config when reconnecting to MQTT