mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2025-05-07 09:23:11 +00:00
- Improve area and zone MQTT support
This commit is contained in:
parent
ab57973fe1
commit
d690d6a830
|
@ -8,6 +8,8 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
public class Alarm : Device
|
||||
{
|
||||
public string basic_state_topic { get; set; }
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
//public string code { get; set; } = string.Empty;
|
||||
|
|
|
@ -18,12 +18,39 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
Alarm ret = new Alarm();
|
||||
ret.name = area.Name;
|
||||
ret.state_topic = area.ToTopic(Topic.state);
|
||||
ret.state_topic = area.ToTopic(Topic.basic_state);
|
||||
ret.command_topic = area.ToTopic(Topic.command);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToState(this clsArea area)
|
||||
{
|
||||
if (area.AreaBurglaryAlarmText != "OK")
|
||||
return "triggered";
|
||||
else if (area.ExitTimer > 0)
|
||||
return "pending";
|
||||
|
||||
switch (area.AreaMode)
|
||||
{
|
||||
case enuSecurityMode.Night:
|
||||
return "armed_night";
|
||||
case enuSecurityMode.NightDly:
|
||||
return "armed_night_delay";
|
||||
case enuSecurityMode.Day:
|
||||
return "armed_home";
|
||||
case enuSecurityMode.DayInst:
|
||||
return "armed_home_instant";
|
||||
case enuSecurityMode.Away:
|
||||
return "armed_away";
|
||||
case enuSecurityMode.Vacation:
|
||||
return "armed_vacation";
|
||||
case enuSecurityMode.Off:
|
||||
default:
|
||||
return "disarmed";
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToBasicState(this clsArea area)
|
||||
{
|
||||
if (area.AreaBurglaryAlarmText != "OK")
|
||||
return "triggered";
|
||||
|
@ -57,7 +84,7 @@ namespace OmniLinkBridge.MQTT
|
|||
Sensor ret = new Sensor();
|
||||
ret.name = zone.Name;
|
||||
ret.device_class = Sensor.DeviceClass.temperature;
|
||||
ret.state_topic = zone.ToTopic(Topic.state);
|
||||
ret.state_topic = zone.ToTopic(Topic.current_temperature);
|
||||
ret.unit_of_measurement = "°F";
|
||||
return ret;
|
||||
}
|
||||
|
@ -67,7 +94,7 @@ namespace OmniLinkBridge.MQTT
|
|||
Sensor ret = new Sensor();
|
||||
ret.name = zone.Name;
|
||||
ret.device_class = Sensor.DeviceClass.humidity;
|
||||
ret.state_topic = zone.ToTopic(Topic.state);
|
||||
ret.state_topic = zone.ToTopic(Topic.current_humidity);
|
||||
ret.unit_of_measurement = "%";
|
||||
return ret;
|
||||
}
|
||||
|
@ -114,16 +141,29 @@ namespace OmniLinkBridge.MQTT
|
|||
}
|
||||
}
|
||||
|
||||
ret.state_topic = zone.ToTopic(Topic.state);
|
||||
ret.state_topic = zone.ToTopic(Topic.basic_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToState(this clsZone zone)
|
||||
{
|
||||
if (zone.IsTemperatureZone() || zone.IsHumidityZone())
|
||||
return zone.TempText();
|
||||
if (zone.Status.IsBitSet(5))
|
||||
return "bypassed";
|
||||
else if (zone.Status.IsBitSet(2))
|
||||
return "tripped";
|
||||
else if (zone.Status.IsBitSet(4))
|
||||
return "armed";
|
||||
else if (zone.Status.IsBitSet(1))
|
||||
return "trouble";
|
||||
else if (zone.Status.IsBitSet(0))
|
||||
return "not_ready";
|
||||
else
|
||||
return zone.Status.IsBitSet(0) ? "ON" : "OFF";
|
||||
return "secure";
|
||||
}
|
||||
|
||||
public static string ToBasicState(this clsZone zone)
|
||||
{
|
||||
return zone.Status.IsBitSet(0) ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
public static string ToTopic(this clsUnit unit, Topic topic)
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace OmniLinkBridge.MQTT
|
|||
public static Topic state { get { return new Topic("state"); } }
|
||||
public static Topic command { get { return new Topic("command"); } }
|
||||
|
||||
public static Topic basic_state { get { return new Topic("basic_state"); } }
|
||||
|
||||
public static Topic brightness_state { get { return new Topic("brightness_state"); } }
|
||||
public static Topic brightness_command { get { return new Topic("brightness_command"); } }
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
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);
|
||||
|
@ -108,38 +112,58 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
if (string.Compare(command, Topic.command.ToString()) == 0)
|
||||
{
|
||||
switch(payload)
|
||||
if(string.Compare(payload, "arm_home", true) == 0)
|
||||
{
|
||||
case "ARM_HOME":
|
||||
log.Debug("SetArea: " + area.Number + " to home");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityDay, 0, (ushort)area.Number);
|
||||
break;
|
||||
case "ARM_AWAY":
|
||||
log.Debug("SetArea: " + area.Number + " to away");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityAway, 0, (ushort)area.Number);
|
||||
break;
|
||||
case "ARM_NIGHT":
|
||||
log.Debug("SetArea: " + area.Number + " to night");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityNight, 0, (ushort)area.Number);
|
||||
break;
|
||||
case "DISARM":
|
||||
log.Debug("SetArea: " + area.Number + " to disarm");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityOff, 0, (ushort)area.Number);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The below aren't supported by Home Assistant
|
||||
case "ARM_HOME_INSTANT":
|
||||
log.Debug("SetArea: " + area.Number + " to home instant");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityDyi, 0, (ushort)area.Number);
|
||||
break;
|
||||
case "ARM_NIGHT_DELAY":
|
||||
log.Debug("SetArea: " + area.Number + " to night delay");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityNtd, 0, (ushort)area.Number);
|
||||
break;
|
||||
case "ARM_VACATION":
|
||||
log.Debug("SetArea: " + area.Number + " to vacation");
|
||||
OmniLink.Controller.SendCommand(enuUnitCommand.SecurityVac, 0, (ushort)area.Number);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -282,21 +306,15 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
PublishZoneState(zone);
|
||||
|
||||
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/omnilink/zone{i.ToString()}/config",
|
||||
JsonConvert.SerializeObject(zone.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
||||
|
||||
if (zone.IsTemperatureZone())
|
||||
{
|
||||
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/omnilink/zone{i.ToString()}/config",
|
||||
JsonConvert.SerializeObject(zone.ToConfigTemp()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
||||
}
|
||||
else if (zone.IsHumidityZone())
|
||||
{
|
||||
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/omnilink/zone{i.ToString()}/config",
|
||||
JsonConvert.SerializeObject(zone.ToConfigHumidity()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
MqttClient.PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/omnilink/zone{i.ToString()}/config",
|
||||
JsonConvert.SerializeObject(zone.ToConfig()), MqttQualityOfServiceLevel.AtMostOnce, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,11 +408,18 @@ namespace OmniLinkBridge.Modules
|
|||
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)
|
||||
|
|
35
README.md
35
README.md
|
@ -86,12 +86,38 @@ To test the API you can use your browser to view a page or PowerShell (see below
|
|||
## MQTT
|
||||
This module will also publish discovery topics for Home Assistant to auto configure devices.
|
||||
|
||||
### Areas
|
||||
```
|
||||
SUB omnilink/areaX/state
|
||||
string triggered, pending, armed_night, armed_night_delay, armed_home, armed_home_instant, armed_away, armed_vacation, disarmed
|
||||
|
||||
SUB omnilink/areaX/basic_state
|
||||
string triggered, pending, armed_night, armed_home, armed_away, disarmed
|
||||
|
||||
PUB omnilink/areaX/command
|
||||
string ARM_HOME, ARM_AWAY, ARM_NIGHT, DISARM, ARM_HOME_INSTANT, ARM_NIGHT_DELAY, ARM_VACATION
|
||||
string(insensitive) arm_home, arm_away, arm_night, disarm, arm_home_instant, arm_night_delay, arm_vacation
|
||||
```
|
||||
|
||||
### Zones
|
||||
```
|
||||
SUB omnilink/zoneX/state
|
||||
string secure, not_ready, trouble, armed, tripped, bypassed
|
||||
|
||||
SUB omnilink/zoneX/basic_state
|
||||
string OFF, ON
|
||||
|
||||
SUB omnilink/zoneX/current_temperature (optional)
|
||||
int Current temperature in degrees fahrenheit
|
||||
|
||||
SUB omnilink/zoneX/current_humidity (optional)
|
||||
int Current relative humidity
|
||||
|
||||
PUB omnilink/zoneX/command
|
||||
string(insensitive) bypass, restore
|
||||
```
|
||||
|
||||
### Units
|
||||
```
|
||||
SUB omnilink/unitX/state
|
||||
PUB omnilink/unitX/command
|
||||
string OFF, ON
|
||||
|
@ -99,7 +125,10 @@ string OFF, ON
|
|||
SUB omnilink/unitX/brightness_state
|
||||
PUB omnilink/unitX/brightness_command
|
||||
int Level from 0 to 100 percent
|
||||
```
|
||||
|
||||
### Thermostats
|
||||
```
|
||||
SUB omnilink/thermostatX/current_operation
|
||||
string idle, cool, heat
|
||||
|
||||
|
@ -132,12 +161,16 @@ string auto, on, cycle
|
|||
SUB omnilink/thermostatX/hold_state
|
||||
PUB omnilink/thermostatX/hold_command
|
||||
string off, hold
|
||||
```
|
||||
|
||||
### Buttons
|
||||
```
|
||||
SUB omnilink/buttonX/state
|
||||
string OFF
|
||||
|
||||
PUB omnilink/buttonX/command
|
||||
string ON
|
||||
```
|
||||
|
||||
## Change Log
|
||||
Version 1.1.1 - 2018-10-18
|
||||
|
|
Loading…
Reference in a new issue