mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2024-12-22 10:42:24 +00:00
- Add Home Assistant MQTT device registry support
This commit is contained in:
parent
a1b15cd08b
commit
a891363539
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
17
OmniLinkBridge/MQTT/DeviceRegistry.cs
Normal file
17
OmniLinkBridge/MQTT/DeviceRegistry.cs
Normal file
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
<Compile Include="MQTT\BinarySensor.cs" />
|
||||
<Compile Include="MQTT\Device.cs" />
|
||||
<Compile Include="MQTT\Climate.cs" />
|
||||
<Compile Include="MQTT\DeviceRegistry.cs" />
|
||||
<Compile Include="MQTT\OverrideZone.cs" />
|
||||
<Compile Include="MQTT\Switch.cs" />
|
||||
<Compile Include="MQTT\Light.cs" />
|
||||
|
|
20
README.md
20
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
|
||||
|
|
Loading…
Reference in a new issue