- Update MQTT, add console messages and button presses

This commit is contained in:
Ryan Wagoner 2019-12-15 00:25:55 -05:00
parent c3aa88621d
commit 314ea42f64
13 changed files with 230 additions and 30 deletions

View file

@ -6,6 +6,7 @@
zone, zone,
unit, unit,
thermostat, thermostat,
button button,
message
} }
} }

View file

@ -140,7 +140,7 @@ namespace OmniLinkBridge.MQTT
ret.value_template = "{% if value_json.water_alarm %} ON {%- else -%} OFF {%- endif %}"; ret.value_template = "{% if value_json.water_alarm %} ON {%- else -%} OFF {%- endif %}";
return ret; return ret;
} }
public static BinarySensor ToConfigDuress(this clsArea area) public static BinarySensor ToConfigDuress(this clsArea area)
{ {
BinarySensor ret = new BinarySensor(); BinarySensor ret = new BinarySensor();
@ -468,5 +468,20 @@ namespace OmniLinkBridge.MQTT
ret.command_topic = button.ToTopic(Topic.command); ret.command_topic = button.ToTopic(Topic.command);
return ret; return ret;
} }
public static string ToTopic(this clsMessage message, Topic topic)
{
return $"{Global.mqtt_prefix}/message{message.Number.ToString()}/{topic.ToString()}";
}
public static string ToState(this clsMessage message)
{
if (message.Status == enuMessageStatus.Displayed)
return "displayed";
else if (message.Status == enuMessageStatus.NotAcked)
return "displayed_not_acknowledged";
else
return "off";
}
} }
} }

View file

@ -0,0 +1,10 @@
namespace OmniLinkBridge.MQTT
{
enum MessageCommands
{
show,
show_no_beep,
show_no_beep_or_led,
clear
}
}

View file

@ -10,7 +10,7 @@ namespace OmniLinkBridge.MQTT
{ {
public class MessageProcessor public class MessageProcessor
{ {
private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private readonly Regex regexTopic = new Regex(Global.mqtt_prefix + "/([A-Za-z]+)([0-9]+)/(.*)", RegexOptions.Compiled); private readonly Regex regexTopic = new Regex(Global.mqtt_prefix + "/([A-Za-z]+)([0-9]+)/(.*)", RegexOptions.Compiled);
@ -45,9 +45,11 @@ namespace OmniLinkBridge.MQTT
ProcessThermostatReceived(OmniLink.Controller.Thermostats[id], topic, payload); ProcessThermostatReceived(OmniLink.Controller.Thermostats[id], topic, payload);
else if (type == CommandTypes.button && id > 0 && id <= OmniLink.Controller.Buttons.Count) else if (type == CommandTypes.button && id > 0 && id <= OmniLink.Controller.Buttons.Count)
ProcessButtonReceived(OmniLink.Controller.Buttons[id], topic, payload); ProcessButtonReceived(OmniLink.Controller.Buttons[id], topic, payload);
else if (type == CommandTypes.message && id > 0 && id <= OmniLink.Controller.Messages.Count)
ProcessMessageReceived(OmniLink.Controller.Messages[id], topic, payload);
} }
private IDictionary<AreaCommands, enuUnitCommand> AreaMapping = new Dictionary<AreaCommands, enuUnitCommand> private static readonly IDictionary<AreaCommands, enuUnitCommand> AreaMapping = new Dictionary<AreaCommands, enuUnitCommand>
{ {
{ AreaCommands.disarm, enuUnitCommand.SecurityOff }, { AreaCommands.disarm, enuUnitCommand.SecurityOff },
{ AreaCommands.arm_home, enuUnitCommand.SecurityDay }, { AreaCommands.arm_home, enuUnitCommand.SecurityDay },
@ -71,7 +73,7 @@ namespace OmniLinkBridge.MQTT
} }
} }
private IDictionary<ZoneCommands, enuUnitCommand> ZoneMapping = new Dictionary<ZoneCommands, enuUnitCommand> private static readonly IDictionary<ZoneCommands, enuUnitCommand> ZoneMapping = new Dictionary<ZoneCommands, enuUnitCommand>
{ {
{ ZoneCommands.restore, enuUnitCommand.Restore }, { ZoneCommands.restore, enuUnitCommand.Restore },
{ ZoneCommands.bypass, enuUnitCommand.Bypass }, { ZoneCommands.bypass, enuUnitCommand.Bypass },
@ -86,7 +88,7 @@ namespace OmniLinkBridge.MQTT
} }
} }
private IDictionary<UnitCommands, enuUnitCommand> UnitMapping = new Dictionary<UnitCommands, enuUnitCommand> private static readonly IDictionary<UnitCommands, enuUnitCommand> UnitMapping = new Dictionary<UnitCommands, enuUnitCommand>
{ {
{ UnitCommands.OFF, enuUnitCommand.Off }, { UnitCommands.OFF, enuUnitCommand.Off },
{ UnitCommands.ON, enuUnitCommand.On } { UnitCommands.ON, enuUnitCommand.On }
@ -181,5 +183,29 @@ namespace OmniLinkBridge.MQTT
OmniLink.SendCommand(enuUnitCommand.Button, 0, (ushort)button.Number); OmniLink.SendCommand(enuUnitCommand.Button, 0, (ushort)button.Number);
} }
} }
private static readonly IDictionary<MessageCommands, enuUnitCommand> MessageMapping = new Dictionary<MessageCommands, enuUnitCommand>
{
{ MessageCommands.show, enuUnitCommand.ShowMsgWBeep },
{ MessageCommands.show_no_beep, enuUnitCommand.ShowMsgNoBeep },
{ MessageCommands.show_no_beep_or_led, enuUnitCommand.ShowMsgNoBeep },
{ MessageCommands.clear, enuUnitCommand.ClearMsg },
};
private void ProcessMessageReceived(clsMessage message, Topic command, string payload)
{
if (command == Topic.command && Enum.TryParse(payload, true, out MessageCommands cmd))
{
log.Debug("SetMessage: " + message.Number + " to " + cmd.ToString().Replace("_", " "));
byte par = 0;
if (cmd == MessageCommands.show_no_beep)
par = 1;
else if (cmd == MessageCommands.show_no_beep_or_led)
par = 2;
OmniLink.SendCommand(MessageMapping[cmd], par, (ushort)message.Number);
}
}
} }
} }

View file

@ -2,6 +2,7 @@
{ {
public enum Topic public enum Topic
{ {
name,
state, state,
command, command,
basic_state, basic_state,

View file

@ -276,7 +276,7 @@ namespace OmniLinkBridge.Modules
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + e.ID + "','" + e.Message.Name + "','" + e.Message.StatusText() + "')"); VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + e.ID + "','" + e.Message.Name + "','" + e.Message.StatusText() + "')");
if (Global.verbose_message) if (Global.verbose_message)
log.Debug("MessageStatus " + e.Message.Name + ", " + e.Message.StatusText()); log.Debug("MessageStatus " + e.ID + " " + e.Message.Name + ", " + e.Message.StatusText());
if (Global.notify_message) if (Global.notify_message)
Notification.Notify("Message", e.ID + " " + e.Message.Name + ", " + e.Message.StatusText()); Notification.Notify("Message", e.ID + " " + e.Message.Name + ", " + e.Message.StatusText());

View file

@ -2,6 +2,10 @@
using log4net; using log4net;
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient; using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol; using MQTTnet.Protocol;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -38,6 +42,8 @@ namespace OmniLinkBridge.Modules
OmniLink.OnZoneStatus += Omnilink_OnZoneStatus; OmniLink.OnZoneStatus += Omnilink_OnZoneStatus;
OmniLink.OnUnitStatus += Omnilink_OnUnitStatus; OmniLink.OnUnitStatus += Omnilink_OnUnitStatus;
OmniLink.OnThermostatStatus += Omnilink_OnThermostatStatus; OmniLink.OnThermostatStatus += Omnilink_OnThermostatStatus;
OmniLink.OnButtonStatus += OmniLink_OnButtonStatus;
OmniLink.OnMessageStatus += OmniLink_OnMessageStatus;
MessageProcessor = new MessageProcessor(omni); MessageProcessor = new MessageProcessor(omni);
} }
@ -66,7 +72,7 @@ namespace OmniLinkBridge.Modules
.Build(); .Build();
MqttClient = new MqttFactory().CreateManagedMqttClient(); MqttClient = new MqttFactory().CreateManagedMqttClient();
MqttClient.Connected += (sender, e) => MqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate((e) =>
{ {
log.Debug("Connected"); log.Debug("Connected");
@ -83,13 +89,14 @@ namespace OmniLinkBridge.Modules
// For subsequent connections publish config immediately // For subsequent connections publish config immediately
if (ControllerConnected) if (ControllerConnected)
PublishConfig(); PublishConfig();
}; });
MqttClient.ConnectingFailed += (sender, e) => { log.Debug("Error connecting " + e.Exception.Message); }; MqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate((e) => log.Debug("Error connecting " + e.Exception.Message));
MqttClient.Disconnected += (sender, e) => { log.Debug("Disconnected"); }; MqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate((e) => log.Debug("Disconnected"));
MqttClient.StartAsync(manoptions); MqttClient.StartAsync(manoptions);
MqttClient.ApplicationMessageReceived += MqttClient_ApplicationMessageReceived; MqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate((e) =>
MessageProcessor.Process(e.ApplicationMessage.Topic, Encoding.UTF8.GetString(e.ApplicationMessage.Payload)));
// Subscribe to notifications for these command topics // Subscribe to notifications for these command topics
List<Topic> toSubscribe = new List<Topic>() List<Topic> toSubscribe = new List<Topic>()
@ -117,11 +124,6 @@ namespace OmniLinkBridge.Modules
MqttClient.StopAsync(); MqttClient.StopAsync();
} }
private void MqttClient_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
MessageProcessor.Process(e.ApplicationMessage.Topic, Encoding.UTF8.GetString(e.ApplicationMessage.Payload));
}
public void Shutdown() public void Shutdown()
{ {
trigger.Set(); trigger.Set();
@ -153,6 +155,7 @@ namespace OmniLinkBridge.Modules
PublishUnits(); PublishUnits();
PublishThermostats(); PublishThermostats();
PublishButtons(); PublishButtons();
PublishMessages();
log.Debug("Publishing controller online"); log.Debug("Publishing controller online");
PublishAsync($"{Global.mqtt_prefix}/status", "online"); PublishAsync($"{Global.mqtt_prefix}/status", "online");
@ -172,6 +175,7 @@ namespace OmniLinkBridge.Modules
// (configured for 1 area). To workaround ignore default properties for the first area. // (configured for 1 area). To workaround ignore default properties for the first area.
if (i > 1 && area.DefaultProperties == true) if (i > 1 && area.DefaultProperties == true)
{ {
PublishAsync(area.ToTopic(Topic.name), null);
PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}fire/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}fire/config", null);
@ -186,6 +190,7 @@ namespace OmniLinkBridge.Modules
PublishAreaState(area); PublishAreaState(area);
PublishAsync(area.ToTopic(Topic.name), area.Name);
PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/alarm_control_panel/{Global.mqtt_prefix}/area{i.ToString()}/config",
JsonConvert.SerializeObject(area.ToConfig())); JsonConvert.SerializeObject(area.ToConfig()));
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config", PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/area{i.ToString()}burglary/config",
@ -215,8 +220,18 @@ namespace OmniLinkBridge.Modules
{ {
clsZone zone = OmniLink.Controller.Zones[i]; clsZone zone = OmniLink.Controller.Zones[i];
if (zone.DefaultProperties == true || Global.mqtt_discovery_ignore_zones.Contains(zone.Number)) if (zone.DefaultProperties == true)
{ {
PublishAsync(zone.ToTopic(Topic.name), null);
}
else
{
PublishZoneState(zone);
PublishAsync(zone.ToTopic(Topic.name), zone.Name);
}
if (zone.DefaultProperties == true || Global.mqtt_discovery_ignore_zones.Contains(zone.Number))
{
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}temp/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}temp/config", null);
@ -224,8 +239,6 @@ namespace OmniLinkBridge.Modules
continue; continue;
} }
PublishZoneState(zone);
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config",
JsonConvert.SerializeObject(zone.ToConfig())); JsonConvert.SerializeObject(zone.ToConfig()));
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/zone{i.ToString()}/config",
@ -247,7 +260,17 @@ namespace OmniLinkBridge.Modules
for (ushort i = 1; i <= OmniLink.Controller.Units.Count; i++) for (ushort i = 1; i <= OmniLink.Controller.Units.Count; i++)
{ {
clsUnit unit = OmniLink.Controller.Units[i]; clsUnit unit = OmniLink.Controller.Units[i];
if (unit.DefaultProperties == true)
{
PublishAsync(unit.ToTopic(Topic.name), null);
}
else
{
PublishUnitState(unit);
PublishAsync(unit.ToTopic(Topic.name), unit.Name);
}
if (unit.DefaultProperties == true || Global.mqtt_discovery_ignore_units.Contains(unit.Number)) if (unit.DefaultProperties == true || Global.mqtt_discovery_ignore_units.Contains(unit.Number))
{ {
string type = i < 385 ? "light" : "switch"; string type = i < 385 ? "light" : "switch";
@ -255,9 +278,7 @@ namespace OmniLinkBridge.Modules
continue; continue;
} }
PublishUnitState(unit); if (i < 385)
if(i < 385)
PublishAsync($"{Global.mqtt_discovery_prefix}/light/{Global.mqtt_prefix}/unit{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/light/{Global.mqtt_prefix}/unit{i.ToString()}/config",
JsonConvert.SerializeObject(unit.ToConfig())); JsonConvert.SerializeObject(unit.ToConfig()));
else else
@ -276,6 +297,7 @@ namespace OmniLinkBridge.Modules
if (thermostat.DefaultProperties == true) if (thermostat.DefaultProperties == true)
{ {
PublishAsync(thermostat.ToTopic(Topic.name), null);
PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}temp/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}temp/config", null);
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}humidity/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}humidity/config", null);
@ -284,6 +306,7 @@ namespace OmniLinkBridge.Modules
PublishThermostatState(thermostat); PublishThermostatState(thermostat);
PublishAsync(thermostat.ToTopic(Topic.name), thermostat.Name);
PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/climate/{Global.mqtt_prefix}/thermostat{i.ToString()}/config",
JsonConvert.SerializeObject(thermostat.ToConfig(OmniLink.Controller.TempFormat))); JsonConvert.SerializeObject(thermostat.ToConfig(OmniLink.Controller.TempFormat)));
PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}temp/config", PublishAsync($"{Global.mqtt_discovery_prefix}/sensor/{Global.mqtt_prefix}/thermostat{i.ToString()}temp/config",
@ -303,18 +326,40 @@ namespace OmniLinkBridge.Modules
if (button.DefaultProperties == true) if (button.DefaultProperties == true)
{ {
PublishAsync(button.ToTopic(Topic.name), null);
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config", null); PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config", null);
continue; continue;
} }
// Buttons are always off // Buttons are off unless momentarily pressed
PublishAsync(button.ToTopic(Topic.state), "OFF"); PublishAsync(button.ToTopic(Topic.state), "OFF");
PublishAsync(button.ToTopic(Topic.name), button.Name);
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config", PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i.ToString()}/config",
JsonConvert.SerializeObject(button.ToConfig())); JsonConvert.SerializeObject(button.ToConfig()));
} }
} }
private void PublishMessages()
{
log.Debug("Publishing messages");
for (ushort i = 1; i <= OmniLink.Controller.Messages.Count; i++)
{
clsMessage message = OmniLink.Controller.Messages[i];
if (message.DefaultProperties == true)
{
PublishAsync(message.ToTopic(Topic.name), null);
continue;
}
PublishMessageState(message);
PublishAsync(message.ToTopic(Topic.name), message.Name);
}
}
private void Omnilink_OnAreaStatus(object sender, AreaStatusEventArgs e) private void Omnilink_OnAreaStatus(object sender, AreaStatusEventArgs e)
{ {
if (!MqttClient.IsConnected) if (!MqttClient.IsConnected)
@ -375,6 +420,22 @@ namespace OmniLinkBridge.Modules
PublishThermostatState(e.Thermostat); PublishThermostatState(e.Thermostat);
} }
private async void OmniLink_OnButtonStatus(object sender, ButtonStatusEventArgs e)
{
if (!MqttClient.IsConnected)
return;
await PublishButtonState(e.Button);
}
private void OmniLink_OnMessageStatus(object sender, MessageStatusEventArgs e)
{
if (!MqttClient.IsConnected)
return;
PublishMessageState(e.Message);
}
private void PublishAreaState(clsArea area) private void PublishAreaState(clsArea area)
{ {
PublishAsync(area.ToTopic(Topic.state), area.ToState()); PublishAsync(area.ToTopic(Topic.state), area.ToState());
@ -415,6 +476,19 @@ namespace OmniLinkBridge.Modules
PublishAsync(thermostat.ToTopic(Topic.hold_state), thermostat.HoldStatusText().ToLower()); PublishAsync(thermostat.ToTopic(Topic.hold_state), thermostat.HoldStatusText().ToLower());
} }
private async Task PublishButtonState(clsButton button)
{
// Simulate a momentary press
await PublishAsync(button.ToTopic(Topic.state), "ON");
await Task.Delay(1000);
await PublishAsync(button.ToTopic(Topic.state), "OFF");
}
private void PublishMessageState(clsMessage message)
{
PublishAsync(message.ToTopic(Topic.state), message.ToState());
}
private Task PublishAsync(string topic, string payload) private Task PublishAsync(string topic, string payload)
{ {
return MqttClient.PublishAsync(topic, payload, MqttQualityOfServiceLevel.AtMostOnce, true); return MqttClient.PublishAsync(topic, payload, MqttQualityOfServiceLevel.AtMostOnce, true);

View file

@ -30,6 +30,7 @@ namespace OmniLinkBridge.Modules
public event EventHandler<ZoneStatusEventArgs> OnZoneStatus; public event EventHandler<ZoneStatusEventArgs> OnZoneStatus;
public event EventHandler<ThermostatStatusEventArgs> OnThermostatStatus; public event EventHandler<ThermostatStatusEventArgs> OnThermostatStatus;
public event EventHandler<UnitStatusEventArgs> OnUnitStatus; public event EventHandler<UnitStatusEventArgs> OnUnitStatus;
public event EventHandler<ButtonStatusEventArgs> OnButtonStatus;
public event EventHandler<MessageStatusEventArgs> OnMessageStatus; public event EventHandler<MessageStatusEventArgs> OnMessageStatus;
public event EventHandler<SystemStatusEventArgs> OnSystemStatus; public event EventHandler<SystemStatusEventArgs> OnSystemStatus;
@ -567,6 +568,12 @@ namespace OmniLinkBridge.Modules
eventargs.Value = ((int)MSG.SystemEvent).ToString() + " " + Controller.Buttons[MSG.SystemEvent].Name; eventargs.Value = ((int)MSG.SystemEvent).ToString() + " " + Controller.Buttons[MSG.SystemEvent].Name;
OnSystemStatus?.Invoke(this, eventargs); OnSystemStatus?.Invoke(this, eventargs);
OnButtonStatus?.Invoke(this, new ButtonStatusEventArgs()
{
ID = MSG.SystemEvent,
Button = Controller.Buttons[MSG.SystemEvent]
});
} }
else if (MSG.SystemEvent >= 768 && MSG.SystemEvent <= 771) else if (MSG.SystemEvent >= 768 && MSG.SystemEvent <= 771)
{ {

View file

@ -0,0 +1,11 @@
using HAI_Shared;
using System;
namespace OmniLinkBridge.OmniLink
{
public class ButtonStatusEventArgs : EventArgs
{
public ushort ID { get; set; }
public clsButton Button { get; set; }
}
}

View file

@ -84,6 +84,7 @@
<Compile Include="MQTT\Device.cs" /> <Compile Include="MQTT\Device.cs" />
<Compile Include="MQTT\Climate.cs" /> <Compile Include="MQTT\Climate.cs" />
<Compile Include="MQTT\DeviceRegistry.cs" /> <Compile Include="MQTT\DeviceRegistry.cs" />
<Compile Include="MQTT\MessageCommands.cs" />
<Compile Include="MQTT\MessageProcessor.cs" /> <Compile Include="MQTT\MessageProcessor.cs" />
<Compile Include="MQTT\OverrideZone.cs" /> <Compile Include="MQTT\OverrideZone.cs" />
<Compile Include="MQTT\Switch.cs" /> <Compile Include="MQTT\Switch.cs" />
@ -98,6 +99,7 @@
<Compile Include="Notifications\Notification.cs" /> <Compile Include="Notifications\Notification.cs" />
<Compile Include="Notifications\NotificationPriority.cs" /> <Compile Include="Notifications\NotificationPriority.cs" />
<Compile Include="Notifications\PushoverNotification.cs" /> <Compile Include="Notifications\PushoverNotification.cs" />
<Compile Include="OmniLink\ButtonStatusEventArgs.cs" />
<Compile Include="OmniLink\IOmniLinkII.cs" /> <Compile Include="OmniLink\IOmniLinkII.cs" />
<Compile Include="OmniLink\UnitStatusEventArgs.cs" /> <Compile Include="OmniLink\UnitStatusEventArgs.cs" />
<Compile Include="OmniLink\ThermostatStatusEventArgs.cs" /> <Compile Include="OmniLink\ThermostatStatusEventArgs.cs" />
@ -166,10 +168,10 @@
<Version>4.5.0</Version> <Version>4.5.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="MQTTnet.Extensions.ManagedClient"> <PackageReference Include="MQTTnet.Extensions.ManagedClient">
<Version>2.8.4</Version> <Version>3.0.8</Version>
</PackageReference> </PackageReference>
<PackageReference Include="Newtonsoft.Json"> <PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version> <Version>12.0.3</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View file

@ -153,6 +153,31 @@ namespace OmniLinkBridgeTest
check(1, "ON", enuUnitCommand.Button); check(1, "ON", enuUnitCommand.Button);
check(1, "on", enuUnitCommand.Button); check(1, "on", enuUnitCommand.Button);
} }
[TestMethod]
public void MessageCommand()
{
void check(ushort id, string payload, enuUnitCommand command, byte par)
{
SendCommandEventArgs actual = null;
omniLink.OnSendCommand += (sender, e) => { actual = e; };
messageProcessor.Process($"omnilink/message{id}/command", payload);
SendCommandEventArgs expected = new SendCommandEventArgs()
{
Cmd = command,
Par = par,
Pr2 = id
};
Assert.AreEqual(expected, actual);
}
check(1, "show", enuUnitCommand.ShowMsgWBeep, 0);
check(1, "show_no_beep", enuUnitCommand.ShowMsgNoBeep, 1);
check(1, "show_no_beep_or_led", enuUnitCommand.ShowMsgNoBeep, 2);
check(1, "clear", enuUnitCommand.ClearMsg, 0);
check(2, "SHOW", enuUnitCommand.ShowMsgWBeep, 0);
}
} }
} }

View file

@ -57,10 +57,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MSTest.TestAdapter"> <PackageReference Include="MSTest.TestAdapter">
<Version>1.3.2</Version> <Version>2.0.0</Version>
</PackageReference> </PackageReference>
<PackageReference Include="MSTest.TestFramework"> <PackageReference Include="MSTest.TestFramework">
<Version>1.3.2</Version> <Version>2.0.0</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -132,6 +132,9 @@ systemctl start omnilinkbridge.service
### Areas ### Areas
``` ```
SUB omnilink/areaX/name
string Area name
SUB omnilink/areaX/state SUB omnilink/areaX/state
string triggered, pending, armed_night, armed_night_delay, armed_home, armed_home_instant, armed_away, armed_vacation, disarmed string triggered, pending, armed_night, armed_night_delay, armed_home, armed_home_instant, armed_away, armed_vacation, disarmed
@ -144,6 +147,9 @@ string(insensitive) arm_home, arm_away, arm_night, disarm, arm_home_instant, arm
### Zones ### Zones
``` ```
SUB omnilink/zoneX/name
string Zone name
SUB omnilink/zoneX/state SUB omnilink/zoneX/state
string secure, not_ready, trouble, armed, tripped, bypassed string secure, not_ready, trouble, armed, tripped, bypassed
@ -162,6 +168,9 @@ string(insensitive) bypass, restore
### Units ### Units
``` ```
SUB omnilink/unitX/name
string Unit name
SUB omnilink/unitX/state SUB omnilink/unitX/state
PUB omnilink/unitX/command PUB omnilink/unitX/command
string OFF, ON string OFF, ON
@ -173,6 +182,9 @@ int Level from 0 to 100 percent
### Thermostats ### Thermostats
``` ```
SUB omnilink/thermostatX/name
string Thermostat name
SUB omnilink/thermostatX/current_operation SUB omnilink/thermostatX/current_operation
string idle, cool, heat string idle, cool, heat
@ -209,13 +221,29 @@ string off, hold
### Buttons ### Buttons
``` ```
SUB omnilink/buttonX/name
string Button name
SUB omnilink/buttonX/state SUB omnilink/buttonX/state
string OFF string OFF, ON
PUB omnilink/buttonX/command PUB omnilink/buttonX/command
string ON string ON
``` ```
### Messages
```
SUB omnilink/messageX/name
string Message name
SUB omnilink/messageX/state
string off, displayed, displayed_not_acknowledged
PUB omnilink/messageX/command
string show, show_no_beep, show_no_beep_or_led, clear
```
## Web API ## Web API
To test the web service API you can use your browser to view a page or PowerShell (see below) to change a value. To test the web service API you can use your browser to view a page or PowerShell (see below) to change a value.