mirror of
https://github.com/excaliburpartners/OmniLinkBridge.git
synced 2025-04-19 21:07:20 +00:00
Compare commits
No commits in common. "master" and "1.1.15" have entirely different histories.
@ -44,11 +44,9 @@ namespace OmniLinkBridge
|
||||
|
||||
startTime = DateTime.Now;
|
||||
|
||||
Program.ShowSendLogsWarning();
|
||||
|
||||
using (LogContext.PushProperty("Telemetry", "Startup"))
|
||||
log.Information("Started version {Version} in {Environment} on {OperatingSystem} with {Modules}",
|
||||
Assembly.GetExecutingAssembly().GetName().Version, Program.GetEnvironment(), Environment.OSVersion, modules);
|
||||
log.Information("Started version {Version} on {OperatingSystem} with {Modules}",
|
||||
Assembly.GetExecutingAssembly().GetName().Version, Environment.OSVersion, modules);
|
||||
|
||||
// Startup modules
|
||||
foreach (IModule module in modules)
|
||||
|
@ -9,11 +9,6 @@ namespace OmniLinkBridge
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string Truncate(this string value, int maxLength)
|
||||
{
|
||||
return value?.Length > maxLength ? value.Substring(0, maxLength) : value;
|
||||
}
|
||||
|
||||
public static double ToCelsius(this double f)
|
||||
{
|
||||
// Convert to celsius
|
||||
|
@ -10,8 +10,6 @@ namespace OmniLinkBridge
|
||||
{
|
||||
public static bool DebugSettings { get; set; }
|
||||
public static bool UseEnvironment { get; set; }
|
||||
public static bool SendLogs { get; set; }
|
||||
public static Guid SessionID { get; } = Guid.NewGuid();
|
||||
|
||||
// HAI / Leviton Omni Controller
|
||||
public static string controller_address;
|
||||
@ -36,7 +34,6 @@ namespace OmniLinkBridge
|
||||
public static bool verbose_unit;
|
||||
public static bool verbose_message;
|
||||
public static bool verbose_lock;
|
||||
public static bool verbose_audio;
|
||||
|
||||
// mySQL Logging
|
||||
public static bool mysql_logging;
|
||||
@ -59,12 +56,9 @@ namespace OmniLinkBridge
|
||||
public static string mqtt_discovery_name_prefix;
|
||||
public static HashSet<int> mqtt_discovery_ignore_zones;
|
||||
public static HashSet<int> mqtt_discovery_ignore_units;
|
||||
public static ConcurrentDictionary<int, MQTT.OverrideArea> mqtt_discovery_override_area;
|
||||
public static HashSet<int> mqtt_discovery_area_code_required;
|
||||
public static ConcurrentDictionary<int, MQTT.OverrideZone> mqtt_discovery_override_zone;
|
||||
public static ConcurrentDictionary<int, MQTT.OverrideUnit> mqtt_discovery_override_unit;
|
||||
public static Type mqtt_discovery_button_type;
|
||||
public static bool mqtt_audio_local_mute;
|
||||
public static bool mqtt_audio_volume_media_player;
|
||||
|
||||
// Notifications
|
||||
public static bool notify_area;
|
||||
|
@ -1,4 +1,9 @@
|
||||
using HAI_Shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
@ -23,13 +28,7 @@ namespace OmniLinkBridge.MQTT
|
||||
}
|
||||
else if (supportValidate && payloads.Length == 3)
|
||||
{
|
||||
// Special case for Home Assistant when code not required
|
||||
if (string.Compare(payloads[1], "validate", true) == 0 &&
|
||||
string.Compare(payloads[2], "None", true) == 0)
|
||||
{
|
||||
ret.Success = true;
|
||||
}
|
||||
else if (string.Compare(payloads[1], "validate", true) == 0)
|
||||
if (string.Compare(payloads[1], "validate", true) == 0)
|
||||
{
|
||||
ret.Validate = true;
|
||||
ret.Success = int.TryParse(payloads[2], out code);
|
||||
|
@ -1,15 +1,10 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Alarm : Device
|
||||
{
|
||||
public Alarm(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
@ -17,14 +12,5 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string code { get; set; }
|
||||
|
||||
public bool code_arm_required { get; set; } = false;
|
||||
|
||||
public bool code_disarm_required { get; set; } = false;
|
||||
|
||||
public bool code_trigger_required { get; set; } = false;
|
||||
|
||||
public List<string> supported_features { get; set; } = new List<string>(new string[] {
|
||||
"arm_home", "arm_away", "arm_night", "arm_vacation" });
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class BinarySensor : Device
|
||||
{
|
||||
public BinarySensor(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum DeviceClass
|
||||
{
|
||||
|
@ -1,17 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Button : Device
|
||||
{
|
||||
public Button(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string payload_press { get; set; }
|
||||
}
|
||||
}
|
@ -4,11 +4,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Climate : Device
|
||||
{
|
||||
public Climate(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string status { get; set; }
|
||||
|
||||
public string action_topic { get; set; }
|
||||
|
@ -1,16 +1,12 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using OmniLinkBridge.Modules;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Device
|
||||
{
|
||||
public Device(DeviceRegistry deviceRegistry)
|
||||
{
|
||||
device = deviceRegistry;
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum AvailabilityMode
|
||||
{
|
||||
@ -23,9 +19,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
|
||||
public string name { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string icon { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string state_topic { get; set; }
|
||||
|
||||
@ -39,6 +32,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
public AvailabilityMode? availability_mode { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public DeviceRegistry device { get; set; }
|
||||
public DeviceRegistry device { get; set; } = MQTTModule.MqttDeviceRegistry;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,6 @@
|
||||
{
|
||||
public class Light : Device
|
||||
{
|
||||
public Light(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
public string brightness_state_topic { get; set; }
|
||||
|
@ -4,11 +4,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Lock : Device
|
||||
{
|
||||
public Lock(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
|
@ -4,20 +4,15 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Number : Device
|
||||
{
|
||||
public Number(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? min { get; set; }
|
||||
public string icon { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? min { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? max { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public double? step { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Select : Device
|
||||
{
|
||||
public Select(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
public List<string> options { get; set; } = null;
|
||||
}
|
||||
}
|
@ -5,11 +5,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Sensor : Device
|
||||
{
|
||||
public Sensor(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum DeviceClass
|
||||
{
|
||||
@ -20,6 +15,9 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public DeviceClass? device_class { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string icon { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string unit_of_measurement { get; set; }
|
||||
|
||||
|
@ -4,11 +4,6 @@ namespace OmniLinkBridge.MQTT.HomeAssistant
|
||||
{
|
||||
public class Switch : Device
|
||||
{
|
||||
public Switch(DeviceRegistry deviceRegistry) : base(deviceRegistry)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string command_topic { get; set; }
|
||||
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
|
@ -3,7 +3,6 @@ using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using OmniLinkBridge.MQTT.HomeAssistant;
|
||||
using OmniLinkBridge.MQTT.Parser;
|
||||
using OmniLinkBridge.Modules;
|
||||
|
||||
namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
@ -16,7 +15,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Alarm ToConfig(this clsArea area)
|
||||
{
|
||||
Alarm ret = new Alarm(MQTTModule.MqttDeviceRegistry)
|
||||
Alarm ret = new Alarm
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + area.Name,
|
||||
@ -25,27 +24,10 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
};
|
||||
|
||||
Global.mqtt_discovery_override_area.TryGetValue(area.Number, out OverrideArea override_area);
|
||||
|
||||
if (override_area != null)
|
||||
if(Global.mqtt_discovery_area_code_required.Contains(area.Number))
|
||||
{
|
||||
if(override_area.code_arm || override_area.code_disarm)
|
||||
{
|
||||
ret.command_template = "{{ action }},validate,{{ code }}";
|
||||
ret.code = "REMOTE_CODE";
|
||||
}
|
||||
ret.code_arm_required = override_area.code_arm;
|
||||
ret.code_disarm_required = override_area.code_disarm;
|
||||
|
||||
ret.supported_features.Clear();
|
||||
if (override_area.arm_home)
|
||||
ret.supported_features.Add("arm_home");
|
||||
if (override_area.arm_away)
|
||||
ret.supported_features.Add("arm_away");
|
||||
if (override_area.arm_night)
|
||||
ret.supported_features.Add("arm_night");
|
||||
if (override_area.arm_vacation)
|
||||
ret.supported_features.Add("arm_vacation");
|
||||
ret.command_template = "{{ action }},validate,{{ code }}";
|
||||
ret.code = "REMOTE_CODE";
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -101,7 +83,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigBurglary(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}burglary",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Burglary",
|
||||
@ -114,7 +96,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigFire(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}fire",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Fire",
|
||||
@ -127,7 +109,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigGas(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}gas",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Gas",
|
||||
@ -140,7 +122,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigAux(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}auxiliary",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Auxiliary",
|
||||
@ -153,7 +135,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigFreeze(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}freeze",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Freeze",
|
||||
@ -166,7 +148,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigWater(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}water",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Water",
|
||||
@ -179,7 +161,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigDuress(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}duress",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Duress",
|
||||
@ -192,7 +174,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfigTemp(this clsArea area)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}area{area.Number}temp",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{area.Name} Temp",
|
||||
@ -237,7 +219,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Sensor ToConfigTemp(this clsZone zone, enuTempFormat format)
|
||||
{
|
||||
Sensor ret = new Sensor(MQTTModule.MqttDeviceRegistry)
|
||||
Sensor ret = new Sensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}zone{zone.Number}temp",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Temp",
|
||||
@ -250,7 +232,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Sensor ToConfigHumidity(this clsZone zone)
|
||||
{
|
||||
Sensor ret = new Sensor(MQTTModule.MqttDeviceRegistry)
|
||||
Sensor ret = new Sensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}zone{zone.Number}humidity",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Humidity",
|
||||
@ -263,7 +245,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Sensor ToConfigSensor(this clsZone zone)
|
||||
{
|
||||
Sensor ret = new Sensor(MQTTModule.MqttDeviceRegistry)
|
||||
Sensor ret = new Sensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}zone{zone.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + zone.Name
|
||||
@ -305,7 +287,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Switch ToConfigSwitch(this clsZone zone)
|
||||
{
|
||||
Switch ret = new Switch(MQTTModule.MqttDeviceRegistry)
|
||||
Switch ret = new Switch
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}zone{zone.Number}switch",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{zone.Name} Bypass",
|
||||
@ -320,7 +302,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static BinarySensor ToConfig(this clsZone zone)
|
||||
{
|
||||
BinarySensor ret = new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
BinarySensor ret = new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}zone{zone.Number}binary",
|
||||
name = Global.mqtt_discovery_name_prefix + zone.Name
|
||||
@ -395,7 +377,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Light ToConfig(this clsUnit unit)
|
||||
{
|
||||
Light ret = new Light(MQTTModule.MqttDeviceRegistry)
|
||||
Light ret = new Light
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}unit{unit.Number}light",
|
||||
name = Global.mqtt_discovery_name_prefix + unit.Name,
|
||||
@ -409,7 +391,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Switch ToConfigSwitch(this clsUnit unit)
|
||||
{
|
||||
Switch ret = new Switch(MQTTModule.MqttDeviceRegistry)
|
||||
Switch ret = new Switch
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}unit{unit.Number}switch",
|
||||
name = Global.mqtt_discovery_name_prefix + unit.Name,
|
||||
@ -421,7 +403,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Number ToConfigNumber(this clsUnit unit)
|
||||
{
|
||||
Number ret = new Number(MQTTModule.MqttDeviceRegistry)
|
||||
Number ret = new Number
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}unit{unit.Number}number",
|
||||
name = Global.mqtt_discovery_name_prefix + unit.Name,
|
||||
@ -464,7 +446,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Sensor ToConfigTemp(this clsThermostat thermostat, enuTempFormat format)
|
||||
{
|
||||
Sensor ret = new Sensor(MQTTModule.MqttDeviceRegistry)
|
||||
Sensor ret = new Sensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number}temp",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Temp",
|
||||
@ -477,7 +459,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Number ToConfigHumidify(this clsThermostat thermostat)
|
||||
{
|
||||
Number ret = new Number(MQTTModule.MqttDeviceRegistry)
|
||||
Number ret = new Number
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number}humidify",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Humidify",
|
||||
@ -490,7 +472,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Number ToConfigDehumidify(this clsThermostat thermostat)
|
||||
{
|
||||
Number ret = new Number(MQTTModule.MqttDeviceRegistry)
|
||||
Number ret = new Number
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number}dehumidify",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Dehumidify",
|
||||
@ -503,7 +485,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Sensor ToConfigHumidity(this clsThermostat thermostat)
|
||||
{
|
||||
Sensor ret = new Sensor(MQTTModule.MqttDeviceRegistry)
|
||||
Sensor ret = new Sensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number}humidity",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{thermostat.Name} Humidity",
|
||||
@ -516,7 +498,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Climate ToConfig(this clsThermostat thermostat, enuTempFormat format)
|
||||
{
|
||||
Climate ret = new Climate(MQTTModule.MqttDeviceRegistry)
|
||||
Climate ret = new Climate
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}thermostat{thermostat.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + thermostat.Name,
|
||||
@ -597,9 +579,9 @@ namespace OmniLinkBridge.MQTT
|
||||
return $"{Global.mqtt_prefix}/button{button.Number}/{topic}";
|
||||
}
|
||||
|
||||
public static Switch ToConfigSwitch(this clsButton button)
|
||||
public static Switch ToConfig(this clsButton button)
|
||||
{
|
||||
Switch ret = new Switch(MQTTModule.MqttDeviceRegistry)
|
||||
Switch ret = new Switch
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}button{button.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + button.Name,
|
||||
@ -609,18 +591,6 @@ namespace OmniLinkBridge.MQTT
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Button ToConfigButton(this clsButton button)
|
||||
{
|
||||
Button ret = new Button(MQTTModule.MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}button{button.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + button.Name,
|
||||
command_topic = button.ToTopic(Topic.command),
|
||||
payload_press = "ON"
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToTopic(this clsMessage message, Topic topic)
|
||||
{
|
||||
return $"{Global.mqtt_prefix}/message{message.Number}/{topic}";
|
||||
@ -643,7 +613,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
public static Lock ToConfig(this clsAccessControlReader reader)
|
||||
{
|
||||
Lock ret = new Lock(MQTTModule.MqttDeviceRegistry)
|
||||
Lock ret = new Lock
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}lock{reader.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + reader.Name,
|
||||
@ -665,105 +635,5 @@ namespace OmniLinkBridge.MQTT
|
||||
else
|
||||
return "unlocked";
|
||||
}
|
||||
|
||||
public static string ToTopic(this clsAudioSource audioSource, Topic topic)
|
||||
{
|
||||
return $"{Global.mqtt_prefix}/source{audioSource.Number}/{topic}";
|
||||
}
|
||||
|
||||
public static string ToTopic(this clsAudioZone audioZone, Topic topic)
|
||||
{
|
||||
return $"{Global.mqtt_prefix}/audio{audioZone.Number}/{topic}";
|
||||
}
|
||||
|
||||
public static Switch ToConfig(this clsAudioZone audioZone)
|
||||
{
|
||||
Switch ret = new Switch(MQTTModule.MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}audio{audioZone.Number}",
|
||||
name = Global.mqtt_discovery_name_prefix + audioZone.rawName,
|
||||
icon = "mdi:speaker",
|
||||
state_topic = audioZone.ToTopic(Topic.state),
|
||||
command_topic = audioZone.ToTopic(Topic.command)
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToState(this clsAudioZone audioZone)
|
||||
{
|
||||
return audioZone.Power ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
public static Switch ToConfigMute(this clsAudioZone audioZone)
|
||||
{
|
||||
Switch ret = new Switch(MQTTModule.MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}audio{audioZone.Number}mute",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{audioZone.rawName} Mute",
|
||||
icon = "mdi:volume-mute",
|
||||
state_topic = audioZone.ToTopic(Topic.mute_state),
|
||||
command_topic = audioZone.ToTopic(Topic.mute_command)
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string ToMuteState(this clsAudioZone audioZone)
|
||||
{
|
||||
if(Global.mqtt_audio_local_mute)
|
||||
return audioZone.Volume == 0 ? "ON" : "OFF";
|
||||
else
|
||||
return audioZone.Mute ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
public static Select ToConfigSource(this clsAudioZone audioZone, List<string> audioSources)
|
||||
{
|
||||
Select ret = new Select(MQTTModule.MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}audio{audioZone.Number}source",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{audioZone.rawName} Source",
|
||||
icon = "mdi:volume-source",
|
||||
state_topic = audioZone.ToTopic(Topic.source_state),
|
||||
command_topic = audioZone.ToTopic(Topic.source_command),
|
||||
options = audioSources
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static int ToSourceState(this clsAudioZone audioZone)
|
||||
{
|
||||
return audioZone.Source;
|
||||
}
|
||||
|
||||
public static Number ToConfigVolume(this clsAudioZone audioZone)
|
||||
{
|
||||
Number ret = new Number(MQTTModule.MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}audio{audioZone.Number}volume",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}{audioZone.rawName} Volume",
|
||||
icon = "mdi:volume-low",
|
||||
state_topic = audioZone.ToTopic(Topic.volume_state),
|
||||
command_topic = audioZone.ToTopic(Topic.volume_command),
|
||||
min = 0,
|
||||
max = 100,
|
||||
step = 1,
|
||||
};
|
||||
|
||||
if(Global.mqtt_audio_volume_media_player)
|
||||
{
|
||||
ret.min = 0;
|
||||
ret.max = 1;
|
||||
ret.step = 0.01;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static double ToVolumeState(this clsAudioZone audioZone)
|
||||
{
|
||||
if (Global.mqtt_audio_volume_media_player)
|
||||
return audioZone.Volume * 0.01;
|
||||
else
|
||||
return audioZone.Volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
@ -16,18 +15,11 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
private readonly Regex regexTopic = new Regex(Global.mqtt_prefix + "/([A-Za-z]+)([0-9]+)/(.*)", RegexOptions.Compiled);
|
||||
|
||||
private readonly int[] audioMuteVolumes;
|
||||
private const int VOLUME_DEFAULT = 10;
|
||||
private IOmniLinkII OmniLink { get; set; }
|
||||
|
||||
private IOmniLinkII OmniLink { get; }
|
||||
private Dictionary<string, int> AudioSources { get; }
|
||||
|
||||
public MessageProcessor(IOmniLinkII omni, Dictionary<string, int> audioSources, int numAudioZones)
|
||||
public MessageProcessor(IOmniLinkII omni)
|
||||
{
|
||||
OmniLink = omni;
|
||||
AudioSources = audioSources;
|
||||
|
||||
audioMuteVolumes = new int[numAudioZones];
|
||||
}
|
||||
|
||||
public void Process(string messageTopic, string payload)
|
||||
@ -37,8 +29,8 @@ namespace OmniLinkBridge.MQTT
|
||||
if (!match.Success)
|
||||
return;
|
||||
|
||||
if (!Enum.TryParse(match.Groups[1].Value, true, out CommandTypes type)
|
||||
|| !Enum.TryParse(match.Groups[3].Value, true, out Topic topic)
|
||||
if (!Enum.TryParse(match.Groups[1].Value, true, out CommandTypes type)
|
||||
|| !Enum.TryParse(match.Groups[3].Value, true, out Topic topic)
|
||||
|| !ushort.TryParse(match.Groups[2].Value, out ushort id))
|
||||
return;
|
||||
|
||||
@ -59,8 +51,6 @@ namespace OmniLinkBridge.MQTT
|
||||
ProcessMessageReceived(OmniLink.Controller.Messages[id], topic, payload);
|
||||
else if (type == CommandTypes.@lock && id <= OmniLink.Controller.AccessControlReaders.Count)
|
||||
ProcessLockReceived(OmniLink.Controller.AccessControlReaders[id], topic, payload);
|
||||
else if (type == CommandTypes.audio && id <= OmniLink.Controller.AudioZones.Count)
|
||||
ProcessAudioReceived(OmniLink.Controller.AudioZones[id], topic, payload);
|
||||
}
|
||||
|
||||
private static readonly IDictionary<AreaCommands, enuUnitCommand> AreaMapping = new Dictionary<AreaCommands, enuUnitCommand>
|
||||
@ -88,7 +78,7 @@ namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
string sCode = parser.Code.ToString();
|
||||
|
||||
if (sCode.Length != 4)
|
||||
if(sCode.Length != 4)
|
||||
{
|
||||
log.Warning("SetArea: {id}, Invalid security code: must be 4 digits", area.Number);
|
||||
return;
|
||||
@ -108,7 +98,7 @@ namespace OmniLinkBridge.MQTT
|
||||
|
||||
var validateCode = new clsOL2MsgValidateCode(OmniLink.Controller.Connection, B);
|
||||
|
||||
if (validateCode.AuthorityLevel == 0)
|
||||
if(validateCode.AuthorityLevel == 0)
|
||||
{
|
||||
log.Warning("SetArea: {id}, Invalid security code: validation failed", area.Number);
|
||||
return;
|
||||
@ -153,7 +143,7 @@ namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
AreaCommandCode parser = payload.ToCommandCode();
|
||||
|
||||
if (parser.Success && command == Topic.command && Enum.TryParse(parser.Command, true, out ZoneCommands cmd) &&
|
||||
if (parser.Success && command == Topic.command && Enum.TryParse(parser.Command, true, out ZoneCommands cmd) &&
|
||||
!(zone.Number == 0 && cmd == ZoneCommands.bypass))
|
||||
{
|
||||
if (zone.Number == 0)
|
||||
@ -186,7 +176,7 @@ namespace OmniLinkBridge.MQTT
|
||||
log.Debug("SetUnit: {id} to {value}", unit.Number, payload);
|
||||
OmniLink.SendCommand(enuUnitCommand.Set, BitConverter.GetBytes(flagValue)[0], (ushort)unit.Number);
|
||||
}
|
||||
else if (unit.Type != enuOL2UnitType.Output &&
|
||||
else if (unit.Type != enuOL2UnitType.Output &&
|
||||
command == Topic.brightness_command && int.TryParse(payload, out int unitValue))
|
||||
{
|
||||
log.Debug("SetUnit: {id} to {value}%", unit.Number, payload);
|
||||
@ -197,7 +187,7 @@ namespace OmniLinkBridge.MQTT
|
||||
// which will cause light to go to 100% brightness
|
||||
unit.Status = (byte)(100 + unitValue);
|
||||
}
|
||||
else if (unit.Type != enuOL2UnitType.Output &&
|
||||
else if (unit.Type != enuOL2UnitType.Output &&
|
||||
command == Topic.scene_command && char.TryParse(payload, out char scene))
|
||||
{
|
||||
log.Debug("SetUnit: {id} to {value}", unit.Number, payload);
|
||||
@ -325,92 +315,5 @@ namespace OmniLinkBridge.MQTT
|
||||
OmniLink.SendCommand(LockMapping[cmd], 0, (ushort)reader.Number);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessAudioReceived(clsAudioZone audioZone, Topic command, string payload)
|
||||
{
|
||||
if (command == Topic.command && Enum.TryParse(payload, true, out UnitCommands cmd))
|
||||
{
|
||||
if (audioZone.Number == 0)
|
||||
log.Debug("SetAudio: 0 implies all audio zones will be changed");
|
||||
|
||||
log.Debug("SetAudio: {id} to {value}", audioZone.Number, payload);
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioZone, (byte)cmd, (ushort)audioZone.Number);
|
||||
|
||||
// Send power ON twice to workaround Russound standby
|
||||
if(cmd == UnitCommands.ON)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioZone, (byte)cmd, (ushort)audioZone.Number);
|
||||
}
|
||||
}
|
||||
else if (command == Topic.mute_command && Enum.TryParse(payload, true, out UnitCommands mute))
|
||||
{
|
||||
if (audioZone.Number == 0)
|
||||
{
|
||||
if (Global.mqtt_audio_local_mute)
|
||||
{
|
||||
log.Warning("SetAudioMute: 0 not supported with local mute");
|
||||
return;
|
||||
}
|
||||
else
|
||||
log.Debug("SetAudioMute: 0 implies all audio zones will be changed");
|
||||
}
|
||||
|
||||
if (Global.mqtt_audio_local_mute)
|
||||
{
|
||||
if (mute == UnitCommands.ON)
|
||||
{
|
||||
log.Debug("SetAudioMute: {id} local mute, previous volume {level}",
|
||||
audioZone.Number, audioZone.Volume);
|
||||
audioMuteVolumes[audioZone.Number] = audioZone.Volume;
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioVolume, 0, (ushort)audioZone.Number);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (audioMuteVolumes[audioZone.Number] == 0)
|
||||
{
|
||||
log.Debug("SetAudioMute: {id} local mute, defaulting to volume {level}",
|
||||
audioZone.Number, VOLUME_DEFAULT);
|
||||
audioMuteVolumes[audioZone.Number] = VOLUME_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Debug("SetAudioMute: {id} local mute, restoring to volume {level}",
|
||||
audioZone.Number, audioMuteVolumes[audioZone.Number]);
|
||||
}
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioVolume, (byte)audioMuteVolumes[audioZone.Number], (ushort)audioZone.Number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Debug("SetAudioMute: {id} to {value}", audioZone.Number, payload);
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioZone, (byte)(mute + 2), (ushort)audioZone.Number);
|
||||
}
|
||||
}
|
||||
else if (command == Topic.source_command && AudioSources.TryGetValue(payload, out int source))
|
||||
{
|
||||
log.Debug("SetAudioSource: {id} to {value}", audioZone.Number, payload);
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioSource, (byte)source, (ushort)audioZone.Number);
|
||||
}
|
||||
else if (command == Topic.volume_command && double.TryParse(payload, out double volume))
|
||||
{
|
||||
if (Global.mqtt_audio_volume_media_player)
|
||||
volume *= 100;
|
||||
|
||||
if (volume > 100)
|
||||
volume = 100;
|
||||
else if (volume < 0)
|
||||
volume = 0;
|
||||
|
||||
log.Debug("SetAudioVolume: {id} to {value}", audioZone.Number, volume);
|
||||
|
||||
OmniLink.SendCommand(enuUnitCommand.AudioVolume, (byte)volume, (ushort)audioZone.Number);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniLinkBridge.MQTT
|
||||
{
|
||||
public class OverrideArea
|
||||
{
|
||||
public bool code_arm { get; set; }
|
||||
|
||||
public bool code_disarm { get; set; }
|
||||
|
||||
public bool arm_home { get; set; } = true;
|
||||
|
||||
public bool arm_away { get; set; } = true;
|
||||
|
||||
public bool arm_night { get; set; } = true;
|
||||
|
||||
public bool arm_vacation { get; set; } = true;
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
thermostat,
|
||||
button,
|
||||
message,
|
||||
@lock,
|
||||
audio
|
||||
@lock
|
||||
}
|
||||
}
|
||||
|
@ -33,11 +33,5 @@
|
||||
fan_mode_command,
|
||||
hold_state,
|
||||
hold_command,
|
||||
mute_state,
|
||||
mute_command,
|
||||
source_state,
|
||||
source_command,
|
||||
volume_state,
|
||||
volume_command,
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ namespace OmniLinkBridge.Modules
|
||||
omnilink.OnUnitStatus += Omnilink_OnUnitStatus;
|
||||
omnilink.OnMessageStatus += Omnilink_OnMessageStatus;
|
||||
omnilink.OnLockStatus += Omnilink_OnLockStatus;
|
||||
omnilink.OnAudioZoneStatus += Omnilink_OnAudioZoneStatus;
|
||||
omnilink.OnSystemStatus += Omnilink_OnSystemStatus;
|
||||
}
|
||||
|
||||
@ -225,9 +224,6 @@ namespace OmniLinkBridge.Modules
|
||||
continue;
|
||||
|
||||
audioSourceUsage++;
|
||||
|
||||
if (Global.verbose_audio)
|
||||
log.Verbose("Initial AudioSource {id} {name}", i, audioSource.rawName);
|
||||
}
|
||||
|
||||
ushort audioZoneUsage = 0;
|
||||
@ -239,10 +235,6 @@ namespace OmniLinkBridge.Modules
|
||||
continue;
|
||||
|
||||
audioZoneUsage++;
|
||||
|
||||
if (Global.verbose_audio)
|
||||
log.Verbose("Initial AudioZoneStatus {id} {name}, Power: {power}, Source: {source}, Volume: {volume}, Mute: {mute}",
|
||||
i, audioZone.rawName, audioZone.Power, audioZone.Source, audioZone.Volume, audioZone.Mute);
|
||||
}
|
||||
|
||||
using (LogContext.PushProperty("Telemetry", "ControllerUsage"))
|
||||
@ -278,7 +270,7 @@ namespace OmniLinkBridge.Modules
|
||||
e.Area.AreaDuressAlarmText + "','" + status + "')");
|
||||
|
||||
if (Global.verbose_area)
|
||||
log.Verbose("AreaStatus {id} {name}, Status: {status}, Alarms: {alarms}", e.ID, e.Area.Name, status, e.Area.AreaAlarms);
|
||||
log.Verbose("AreaStatus {id} {name}, Status: {status}, Alarams: {alarms}", e.ID, e.Area.Name, status, e.Area.AreaAlarms);
|
||||
|
||||
if (Global.notify_area && e.Area.LastMode != e.Area.AreaMode)
|
||||
Notification.Notify("Security", e.Area.Name + " " + e.Area.ModeText());
|
||||
@ -391,13 +383,6 @@ namespace OmniLinkBridge.Modules
|
||||
log.Verbose("LockStatus {id} {name}, Status: {status}", e.ID, e.Reader.Name, e.Reader.LockStatusText());
|
||||
}
|
||||
|
||||
private void Omnilink_OnAudioZoneStatus(object sender, AudioZoneStatusEventArgs e)
|
||||
{
|
||||
if (Global.verbose_audio)
|
||||
log.Verbose("AudioZoneStatus {id} {name}, Power: {power}, Source: {source}, Volume: {volume}, Mute: {mute}",
|
||||
e.ID, e.AudioZone.rawName, e.AudioZone.Power, e.AudioZone.Source, e.AudioZone.Volume, e.AudioZone.Mute);
|
||||
}
|
||||
|
||||
private void Omnilink_OnSystemStatus(object sender, SystemStatusEventArgs e)
|
||||
{
|
||||
DBQueue(@"
|
||||
|
@ -34,16 +34,11 @@ namespace OmniLinkBridge.Modules
|
||||
private bool ControllerConnected { get; set; }
|
||||
private MessageProcessor MessageProcessor { get; set; }
|
||||
|
||||
private Dictionary<string, int> AudioSources { get; set; } = new Dictionary<string, int>();
|
||||
|
||||
private readonly AutoResetEvent trigger = new AutoResetEvent(false);
|
||||
|
||||
private const string ONLINE = "online";
|
||||
private const string OFFLINE = "offline";
|
||||
|
||||
private const string SECURE = "secure";
|
||||
private const string TROUBLE = "trouble";
|
||||
|
||||
public MQTTModule(OmniLinkII omni)
|
||||
{
|
||||
OmniLink = omni;
|
||||
@ -56,10 +51,9 @@ namespace OmniLinkBridge.Modules
|
||||
OmniLink.OnButtonStatus += OmniLink_OnButtonStatus;
|
||||
OmniLink.OnMessageStatus += OmniLink_OnMessageStatus;
|
||||
OmniLink.OnLockStatus += OmniLink_OnLockStatus;
|
||||
OmniLink.OnAudioZoneStatus += OmniLink_OnAudioZoneStatus;
|
||||
OmniLink.OnSystemStatus += OmniLink_OnSystemStatus;
|
||||
|
||||
MessageProcessor = new MessageProcessor(omni, AudioSources, omni.Controller.CAP.numAudioZones);
|
||||
MessageProcessor = new MessageProcessor(omni);
|
||||
}
|
||||
|
||||
public void Startup()
|
||||
@ -126,10 +120,7 @@ namespace OmniLinkBridge.Modules
|
||||
Topic.dehumidify_command,
|
||||
Topic.mode_command,
|
||||
Topic.fan_mode_command,
|
||||
Topic.hold_command,
|
||||
Topic.mute_command,
|
||||
Topic.source_command,
|
||||
Topic.volume_command
|
||||
Topic.hold_command
|
||||
};
|
||||
|
||||
toSubscribe.ForEach((command) => MqttClient.SubscribeAsync(
|
||||
@ -180,8 +171,6 @@ namespace OmniLinkBridge.Modules
|
||||
PublishButtons();
|
||||
PublishMessages();
|
||||
PublishLocks();
|
||||
PublishAudioSources();
|
||||
PublishAudioZones();
|
||||
|
||||
PublishControllerStatus(ONLINE);
|
||||
PublishAsync($"{Global.mqtt_prefix}/model", OmniLink.Controller.GetModelText());
|
||||
@ -201,10 +190,10 @@ namespace OmniLinkBridge.Modules
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/binary_sensor/{Global.mqtt_prefix}/system_dcm/config",
|
||||
JsonConvert.SerializeObject(SystemTroubleConfig("dcm", "DCM")));
|
||||
|
||||
PublishAsync(SystemTroubleTopic("phone"), OmniLink.TroublePhone ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("ac"), OmniLink.TroubleAC ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("battery"), OmniLink.TroubleBattery ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("dcm"), OmniLink.TroubleDCM ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("phone"), OmniLink.TroublePhone ? "trouble" : "secure");
|
||||
PublishAsync(SystemTroubleTopic("ac"), OmniLink.TroubleAC ? "trouble" : "secure");
|
||||
PublishAsync(SystemTroubleTopic("battery"), OmniLink.TroubleBattery ? "trouble" : "secure");
|
||||
PublishAsync(SystemTroubleTopic("dcm"), OmniLink.TroubleDCM ? "trouble" : "secure");
|
||||
}
|
||||
|
||||
public string SystemTroubleTopic(string type)
|
||||
@ -214,14 +203,14 @@ namespace OmniLinkBridge.Modules
|
||||
|
||||
public BinarySensor SystemTroubleConfig(string type, string name)
|
||||
{
|
||||
return new BinarySensor(MQTTModule.MqttDeviceRegistry)
|
||||
return new BinarySensor
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}system{type}",
|
||||
name = $"{Global.mqtt_discovery_name_prefix}System {name}",
|
||||
state_topic = SystemTroubleTopic(type),
|
||||
device_class = BinarySensor.DeviceClass.problem,
|
||||
payload_off = SECURE,
|
||||
payload_on = TROUBLE
|
||||
payload_off = "secure",
|
||||
payload_on = "trouble"
|
||||
};
|
||||
}
|
||||
|
||||
@ -402,9 +391,6 @@ namespace OmniLinkBridge.Modules
|
||||
{
|
||||
log.Debug("Publishing {type}", "buttons");
|
||||
|
||||
if (Global.mqtt_discovery_button_type == typeof(Switch))
|
||||
log.Information("See {setting} for new option when publishing {type}", "mqtt_discovery_button_type", "buttons");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++)
|
||||
{
|
||||
clsButton button = OmniLink.Controller.Buttons[i];
|
||||
@ -413,7 +399,6 @@ namespace OmniLinkBridge.Modules
|
||||
{
|
||||
PublishAsync(button.ToTopic(Topic.name), null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/button{i}/config", null);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -421,19 +406,8 @@ namespace OmniLinkBridge.Modules
|
||||
PublishAsync(button.ToTopic(Topic.state), "OFF");
|
||||
|
||||
PublishAsync(button.ToTopic(Topic.name), button.Name);
|
||||
|
||||
if (Global.mqtt_discovery_button_type == typeof(Switch))
|
||||
{
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/button{i}/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config",
|
||||
JsonConvert.SerializeObject(button.ToConfigSwitch()));
|
||||
}
|
||||
else if (Global.mqtt_discovery_button_type == typeof(Button))
|
||||
{
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/button{i}/config",
|
||||
JsonConvert.SerializeObject(button.ToConfigButton()));
|
||||
}
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/button{i}/config",
|
||||
JsonConvert.SerializeObject(button.ToConfig()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,74 +454,6 @@ namespace OmniLinkBridge.Modules
|
||||
}
|
||||
}
|
||||
|
||||
private void PublishAudioSources()
|
||||
{
|
||||
log.Debug("Publishing {type}", "audio sources");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.AudioSources.Count; i++)
|
||||
{
|
||||
clsAudioSource audioSource = OmniLink.Controller.AudioSources[i];
|
||||
|
||||
if (audioSource.DefaultProperties == true)
|
||||
{
|
||||
PublishAsync(audioSource.ToTopic(Topic.name), null);
|
||||
continue;
|
||||
}
|
||||
|
||||
PublishAsync(audioSource.ToTopic(Topic.name), audioSource.rawName);
|
||||
|
||||
if (AudioSources.ContainsKey(audioSource.rawName))
|
||||
{
|
||||
log.Warning("Duplicate audio source name {name}", audioSource.rawName);
|
||||
continue;
|
||||
}
|
||||
|
||||
AudioSources.Add(audioSource.rawName, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void PublishAudioZones()
|
||||
{
|
||||
log.Debug("Publishing {type}", "audio zones");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.AudioZones.Count; i++)
|
||||
{
|
||||
clsAudioZone audioZone = OmniLink.Controller.AudioZones[i];
|
||||
|
||||
if (audioZone.DefaultProperties == true)
|
||||
{
|
||||
PublishAsync(audioZone.ToTopic(Topic.name), null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/audio{i}/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/audio{i}mute/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/select/{Global.mqtt_prefix}/audio{i}source/config", null);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/number/{Global.mqtt_prefix}/audio{i}volume/config", null);
|
||||
continue;
|
||||
}
|
||||
|
||||
PublishAudioZoneStateAsync(audioZone);
|
||||
|
||||
PublishAsync(audioZone.ToTopic(Topic.name), audioZone.rawName);
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/audio{i}/config",
|
||||
JsonConvert.SerializeObject(audioZone.ToConfig()));
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/switch/{Global.mqtt_prefix}/audio{i}mute/config",
|
||||
JsonConvert.SerializeObject(audioZone.ToConfigMute()));
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/select/{Global.mqtt_prefix}/audio{i}source/config",
|
||||
JsonConvert.SerializeObject(audioZone.ToConfigSource(new List<string>(AudioSources.Keys))));
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/number/{Global.mqtt_prefix}/audio{i}volume/config",
|
||||
JsonConvert.SerializeObject(audioZone.ToConfigVolume()));
|
||||
}
|
||||
|
||||
PublishAsync($"{Global.mqtt_discovery_prefix}/button/{Global.mqtt_prefix}/audio0/config",
|
||||
JsonConvert.SerializeObject(new Button(MqttDeviceRegistry)
|
||||
{
|
||||
unique_id = $"{Global.mqtt_prefix}audio0",
|
||||
name = Global.mqtt_discovery_name_prefix + "Audio All Off",
|
||||
icon = "mdi:speaker",
|
||||
command_topic = $"{Global.mqtt_prefix}/audio0/{Topic.command}",
|
||||
payload_press = "OFF"
|
||||
}));
|
||||
}
|
||||
|
||||
private void Omnilink_OnAreaStatus(object sender, AreaStatusEventArgs e)
|
||||
{
|
||||
if (!MqttClient.IsConnected)
|
||||
@ -641,27 +547,19 @@ namespace OmniLinkBridge.Modules
|
||||
PublishLockStateAsync(e.Reader);
|
||||
}
|
||||
|
||||
private void OmniLink_OnAudioZoneStatus(object sender, AudioZoneStatusEventArgs e)
|
||||
{
|
||||
if (!MqttClient.IsConnected)
|
||||
return;
|
||||
|
||||
PublishAudioZoneStateAsync(e.AudioZone);
|
||||
}
|
||||
|
||||
private void OmniLink_OnSystemStatus(object sender, SystemStatusEventArgs e)
|
||||
{
|
||||
if (!MqttClient.IsConnected)
|
||||
return;
|
||||
|
||||
if(e.Type == SystemEventType.Phone)
|
||||
PublishAsync(SystemTroubleTopic("phone"), e.Trouble ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("phone"), e.Trouble ? "trouble" : "secure");
|
||||
else if (e.Type == SystemEventType.AC)
|
||||
PublishAsync(SystemTroubleTopic("ac"), e.Trouble ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("ac"), e.Trouble ? "trouble" : "secure");
|
||||
else if (e.Type == SystemEventType.Button)
|
||||
PublishAsync(SystemTroubleTopic("battery"), e.Trouble ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("battery"), e.Trouble ? "trouble" : "secure");
|
||||
else if (e.Type == SystemEventType.DCM)
|
||||
PublishAsync(SystemTroubleTopic("dcm"), e.Trouble ? TROUBLE : SECURE);
|
||||
PublishAsync(SystemTroubleTopic("dcm"), e.Trouble ? "trouble" : "secure");
|
||||
}
|
||||
|
||||
private void PublishAreaState(clsArea area)
|
||||
@ -730,15 +628,6 @@ namespace OmniLinkBridge.Modules
|
||||
return PublishAsync(reader.ToTopic(Topic.state), reader.ToState());
|
||||
}
|
||||
|
||||
private void PublishAudioZoneStateAsync(clsAudioZone audioZone)
|
||||
{
|
||||
PublishAsync(audioZone.ToTopic(Topic.state), audioZone.ToState());
|
||||
PublishAsync(audioZone.ToTopic(Topic.mute_state), audioZone.ToMuteState());
|
||||
PublishAsync(audioZone.ToTopic(Topic.source_state),
|
||||
OmniLink.Controller.AudioSources[audioZone.ToSourceState()].rawName);
|
||||
PublishAsync(audioZone.ToTopic(Topic.volume_state), audioZone.ToVolumeState().ToString());
|
||||
}
|
||||
|
||||
private Task PublishAsync(string topic, string payload)
|
||||
{
|
||||
return MqttClient.PublishAsync(topic, payload, MqttQualityOfServiceLevel.AtMostOnce, true);
|
||||
|
@ -41,7 +41,6 @@ namespace OmniLinkBridge.Modules
|
||||
public event EventHandler<ButtonStatusEventArgs> OnButtonStatus;
|
||||
public event EventHandler<MessageStatusEventArgs> OnMessageStatus;
|
||||
public event EventHandler<LockStatusEventArgs> OnLockStatus;
|
||||
public event EventHandler<AudioZoneStatusEventArgs> OnAudioZoneStatus;
|
||||
public event EventHandler<SystemStatusEventArgs> OnSystemStatus;
|
||||
|
||||
private readonly AutoResetEvent trigger = new AutoResetEvent(false);
|
||||
@ -87,7 +86,6 @@ namespace OmniLinkBridge.Modules
|
||||
|
||||
public bool SendCommand(enuUnitCommand Cmd, byte Par, ushort Pr2)
|
||||
{
|
||||
log.Verbose("Sending: {command}, Par1: {par1}, Par2: {par2}", Cmd, Par, Pr2);
|
||||
return Controller.SendCommand(Cmd, Par, Pr2);
|
||||
}
|
||||
|
||||
@ -201,8 +199,6 @@ namespace OmniLinkBridge.Modules
|
||||
tstat_timer.Start();
|
||||
|
||||
OnConnect?.Invoke(this, new EventArgs());
|
||||
|
||||
Program.ShowSendLogsWarning();
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -220,8 +216,6 @@ namespace OmniLinkBridge.Modules
|
||||
await GetNamed(enuObjectType.Message);
|
||||
await GetNamed(enuObjectType.Button);
|
||||
await GetNamed(enuObjectType.AccessControlReader);
|
||||
await GetNamed(enuObjectType.AudioSource);
|
||||
await GetNamed(enuObjectType.AudioZone);
|
||||
}
|
||||
|
||||
private async Task GetSystemFormats()
|
||||
@ -233,8 +227,7 @@ namespace OmniLinkBridge.Modules
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if(!nameWait.WaitOne(new TimeSpan(0, 0, 10)))
|
||||
log.Error("Timeout occurred waiting system formats");
|
||||
nameWait.WaitOne(new TimeSpan(0, 0, 10));
|
||||
});
|
||||
}
|
||||
|
||||
@ -247,8 +240,7 @@ namespace OmniLinkBridge.Modules
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if(!nameWait.WaitOne(new TimeSpan(0, 0, 10)))
|
||||
log.Error("Timeout occurred waiting for system troubles");
|
||||
nameWait.WaitOne(new TimeSpan(0, 0, 10));
|
||||
});
|
||||
}
|
||||
|
||||
@ -260,8 +252,7 @@ namespace OmniLinkBridge.Modules
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (!nameWait.WaitOne(new TimeSpan(0, 0, 30)))
|
||||
log.Error("Timeout occurred waiting for named units {unitType}", type.ToString());
|
||||
nameWait.WaitOne(new TimeSpan(0, 0, 10));
|
||||
});
|
||||
}
|
||||
|
||||
@ -356,14 +347,6 @@ namespace OmniLinkBridge.Modules
|
||||
case enuObjectType.AccessControlReader:
|
||||
Controller.AccessControlReaders.CopyProperties(MSG);
|
||||
break;
|
||||
case enuObjectType.AudioSource:
|
||||
Controller.AudioSources.CopyProperties(MSG);
|
||||
Controller.AudioSources[MSG.ObjectNumber].rawName = MSG.ObjectName;
|
||||
break;
|
||||
case enuObjectType.AudioZone:
|
||||
Controller.AudioZones.CopyProperties(MSG);
|
||||
Controller.AudioZones[MSG.ObjectNumber].rawName = MSG.ObjectName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -444,8 +427,6 @@ namespace OmniLinkBridge.Modules
|
||||
case enuOmniLink2MessageType.CmdExtSecurity:
|
||||
break;
|
||||
case enuOmniLink2MessageType.AudioSourceStatus:
|
||||
// Ignore audio source metadata status updates
|
||||
handled = true;
|
||||
break;
|
||||
case enuOmniLink2MessageType.SystemEvents:
|
||||
HandleUnsolicitedSystemEvent(B);
|
||||
@ -714,17 +695,6 @@ namespace OmniLinkBridge.Modules
|
||||
});
|
||||
}
|
||||
break;
|
||||
case enuObjectType.AudioZone:
|
||||
for (byte i = 0; i < MSG.AudioZoneStatusCount(); i++)
|
||||
{
|
||||
Controller.AudioZones[MSG.ObjectNumber(i)].CopyExtendedStatus(MSG, i);
|
||||
OnAudioZoneStatus?.Invoke(this, new AudioZoneStatusEventArgs()
|
||||
{
|
||||
ID = MSG.ObjectNumber(i),
|
||||
AudioZone = Controller.AudioZones[MSG.ObjectNumber(i)]
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (Global.verbose_unhandled)
|
||||
{
|
||||
|
@ -1,11 +0,0 @@
|
||||
using HAI_Shared;
|
||||
using System;
|
||||
|
||||
namespace OmniLinkBridge.OmniLink
|
||||
{
|
||||
public class AudioZoneStatusEventArgs : EventArgs
|
||||
{
|
||||
public ushort ID { get; set; }
|
||||
public clsAudioZone AudioZone { get; set; }
|
||||
}
|
||||
}
|
@ -1,4 +1,10 @@
|
||||
namespace OmniLinkBridge.OmniLink
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge.OmniLink
|
||||
{
|
||||
public enum SystemEventType
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using HAI_Shared;
|
||||
using System;
|
||||
|
||||
namespace OmniLinkBridge.OmniLink
|
||||
{
|
||||
|
@ -83,11 +83,8 @@
|
||||
<Compile Include="ControllerEnricher.cs" />
|
||||
<Compile Include="CoreServer.cs" />
|
||||
<Compile Include="Modules\TimeSyncModule.cs" />
|
||||
<Compile Include="MQTT\HomeAssistant\Button.cs" />
|
||||
<Compile Include="MQTT\HomeAssistant\Alarm.cs" />
|
||||
<Compile Include="MQTT\HomeAssistant\Lock.cs" />
|
||||
<Compile Include="MQTT\HomeAssistant\Select.cs" />
|
||||
<Compile Include="MQTT\OverrideArea.cs" />
|
||||
<Compile Include="MQTT\OverrideUnit.cs" />
|
||||
<Compile Include="MQTT\Parser\AlarmCommands.cs" />
|
||||
<Compile Include="MQTT\AreaCommandCode.cs" />
|
||||
@ -120,7 +117,6 @@
|
||||
<Compile Include="Notifications\PushoverNotification.cs" />
|
||||
<Compile Include="OmniLink\ButtonStatusEventArgs.cs" />
|
||||
<Compile Include="OmniLink\IOmniLinkII.cs" />
|
||||
<Compile Include="OmniLink\AudioZoneStatusEventArgs.cs" />
|
||||
<Compile Include="OmniLink\SystemEventType.cs" />
|
||||
<Compile Include="OmniLink\LockStatusEventArgs.cs" />
|
||||
<Compile Include="OmniLink\UnitStatusEventArgs.cs" />
|
||||
|
@ -23,7 +23,6 @@ verbose_thermostat = yes
|
||||
verbose_unit = yes
|
||||
verbose_message = yes
|
||||
verbose_lock = yes
|
||||
verbose_audio = yes
|
||||
|
||||
# mySQL Logging (yes/no)
|
||||
mysql_logging = no
|
||||
@ -55,24 +54,14 @@ mqtt_discovery_name_prefix =
|
||||
# Specify a range of numbers 1,2,3,5-10
|
||||
mqtt_discovery_ignore_zones =
|
||||
mqtt_discovery_ignore_units =
|
||||
|
||||
# Override the area Home Assistant alarm control panel
|
||||
# Prompt for user code
|
||||
# code_arm: true or false, defaults to false
|
||||
# code_disarm: true or false, defaults to false
|
||||
# Show these modes
|
||||
# arm_home: true or false, defaults to true
|
||||
# arm_away: true or false, defaults to true
|
||||
# arm_night: true or false, defaults to true
|
||||
# arm_vacation: true or false, defaults to true
|
||||
#mqtt_discovery_override_area = id=1;code_disarm=true;arm_vacation=false
|
||||
|
||||
# Require Home Assistant to prompt for user code when arming/disarming area
|
||||
# Specify a range of numbers 1,2,3,5-10
|
||||
mqtt_discovery_area_code_required =
|
||||
# Override the zone Home Assistant binary sensor device_class
|
||||
# device_class: must be battery, cold, door, garage_door, gas,
|
||||
# heat, moisture, motion, problem, safety, smoke, or window
|
||||
#mqtt_discovery_override_zone = id=5;device_class=garage_door
|
||||
#mqtt_discovery_override_zone = id=6;device_class=garage_door
|
||||
|
||||
# Override the unit Home Assistant device type
|
||||
# type:
|
||||
# Units (LTe 1-32, IIe 1-64, Pro 1-256) light or switch, defaults to light
|
||||
@ -80,15 +69,6 @@ mqtt_discovery_ignore_units =
|
||||
#mqtt_discovery_override_unit = id=1;type=switch
|
||||
#mqtt_discovery_override_unit = id=395;type=number
|
||||
|
||||
# Publish buttons as this Home Assistant device type
|
||||
# must be button (recommended) or switch (default, previous behavior)
|
||||
mqtt_discovery_button_type = switch
|
||||
# Handle mute locally by setting volume to 0 and restoring to previous value
|
||||
mqtt_audio_local_mute = no
|
||||
# Change audio volume scaling for Home Assistant media player
|
||||
# yes 0.00-1.00, no 0-100 (default, previous behavior)
|
||||
mqtt_audio_volume_media_player = no
|
||||
|
||||
# Notifications (yes/no)
|
||||
# Always sent for area alarms and critical system events
|
||||
# Optionally enable for area status changes and console messages
|
||||
|
@ -4,9 +4,7 @@ using Serilog.Events;
|
||||
using Serilog.Filters;
|
||||
using Serilog.Formatting.Compact;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.ServiceProcess;
|
||||
@ -14,11 +12,11 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge
|
||||
{
|
||||
internal class Program
|
||||
class Program
|
||||
{
|
||||
private static CoreServer server;
|
||||
static CoreServer server;
|
||||
|
||||
private static int Main(string[] args)
|
||||
static int Main(string[] args)
|
||||
{
|
||||
bool interactive = false;
|
||||
|
||||
@ -57,10 +55,6 @@ namespace OmniLinkBridge
|
||||
case "-ll":
|
||||
Enum.TryParse(args[++i], out log_level);
|
||||
break;
|
||||
case "-ld":
|
||||
Global.DebugSettings = true;
|
||||
Global.SendLogs = true;
|
||||
break;
|
||||
case "-s":
|
||||
Global.webapi_subscriptions_file = args[++i];
|
||||
break;
|
||||
@ -70,12 +64,6 @@ namespace OmniLinkBridge
|
||||
}
|
||||
}
|
||||
|
||||
if (string.Compare(Environment.GetEnvironmentVariable("SEND_LOGS"), "1") == 0)
|
||||
{
|
||||
Global.DebugSettings = true;
|
||||
Global.SendLogs = true;
|
||||
}
|
||||
|
||||
config_file = GetFullPath(config_file);
|
||||
|
||||
Global.webapi_subscriptions_file = GetFullPath(Global.webapi_subscriptions_file ?? "WebSubscriptions.json");
|
||||
@ -88,7 +76,7 @@ namespace OmniLinkBridge
|
||||
var log_config = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.Enrich.WithProperty("Application", "OmniLinkBridge")
|
||||
.Enrich.WithProperty("Session", Global.SessionID)
|
||||
.Enrich.WithProperty("Session", Guid.NewGuid())
|
||||
.Enrich.With<ControllerEnricher>()
|
||||
.Enrich.FromLogContext();
|
||||
|
||||
@ -104,10 +92,7 @@ namespace OmniLinkBridge
|
||||
rollingInterval: RollingInterval.Day, retainedFileCountLimit: 15));
|
||||
}
|
||||
|
||||
if (Global.SendLogs)
|
||||
log_config = log_config.WriteTo.Logger(lc => lc
|
||||
.WriteTo.Http("https://telemetry.excalibur-partners.com"));
|
||||
else if (UseTelemetry())
|
||||
if (UseTelemetry())
|
||||
log_config = log_config.WriteTo.Logger(lc => lc
|
||||
.Filter.ByIncludingOnly(Matching.WithProperty("Telemetry"))
|
||||
.WriteTo.Http("https://telemetry.excalibur-partners.com"));
|
||||
@ -170,7 +155,7 @@ namespace OmniLinkBridge
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static string GetFullPath(string file)
|
||||
static string GetFullPath(string file)
|
||||
{
|
||||
if (Path.IsPathRooted(file))
|
||||
return file;
|
||||
@ -184,38 +169,21 @@ namespace OmniLinkBridge
|
||||
args.Cancel = true;
|
||||
}
|
||||
|
||||
private static bool IsRunningOnMono()
|
||||
static bool IsRunningOnMono()
|
||||
{
|
||||
return Type.GetType("Mono.Runtime") != null;
|
||||
}
|
||||
|
||||
public static string GetEnvironment()
|
||||
{
|
||||
if (Environment.GetEnvironmentVariable("HASSIO_TOKEN") != null)
|
||||
return "Home Assistant";
|
||||
else if (IsRunningOnMono())
|
||||
return Process.GetProcesses().Any(w => w.Id == 2) ? "Mono" : "Docker";
|
||||
else
|
||||
return "Native";
|
||||
}
|
||||
|
||||
private static bool UseTelemetry()
|
||||
static bool UseTelemetry()
|
||||
{
|
||||
return string.Compare(Environment.GetEnvironmentVariable("TELEMETRY_OPTOUT"), "1") != 0;
|
||||
}
|
||||
|
||||
public static void ShowSendLogsWarning()
|
||||
{
|
||||
if (Global.SendLogs)
|
||||
Log.Warning("SENDING LOGS TO DEVELOPER Controller: {ControllerID}, Session: {Session}",
|
||||
Global.controller_id, Global.SessionID);
|
||||
}
|
||||
|
||||
private static void ShowHelp()
|
||||
static void ShowHelp()
|
||||
{
|
||||
Console.WriteLine(
|
||||
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-j] [-s subscriptions_file]\n" +
|
||||
"\t[-lf log_file|disable] [-lj [-ll verbose|debug|information|warning|error] [-ld] [-i]\n" +
|
||||
"\t[-lf log_file|disable] [-lj [-ll verbose|debug|information|warning|error] [-i]\n" +
|
||||
"\t-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" +
|
||||
"\t-e Check environment variables for configuration settings\n" +
|
||||
"\t-d Show debug ouput for configuration loading\n" +
|
||||
@ -223,14 +191,8 @@ namespace OmniLinkBridge
|
||||
"\t-lf Specifies the rolling log file. Retention is 15 days. Default is log.txt.\n" +
|
||||
"\t-lj Write logs as CLEF (compact log event format) JSON.\n" +
|
||||
"\t-ll Minimum level at which events will be logged. Default is information.\n" +
|
||||
"\t-ld Send logs to developer. ONLY USE WHEN ASKED.\n" +
|
||||
"\t Also enabled by setting a SEND_LOGS environment variable to 1.\n" +
|
||||
"\t-i Run in interactive mode");
|
||||
|
||||
Console.WriteLine(
|
||||
"\nVersion: " + Assembly.GetExecutingAssembly().GetName().Version +
|
||||
"\nEnvironment: " + GetEnvironment());
|
||||
|
||||
Console.WriteLine(
|
||||
"\nOmniLink Bridge collects anonymous telemetry data to help improve the software.\n" +
|
||||
"You can opt of telemetry by setting a TELEMETRY_OPTOUT environment variable to 1.");
|
||||
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.1.19.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.19.0")]
|
||||
[assembly: AssemblyVersion("1.1.15.0")]
|
||||
[assembly: AssemblyFileVersion("1.1.15.0")]
|
||||
|
@ -1,4 +1,3 @@
|
||||
using OmniLinkBridge.MQTT.HomeAssistant;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
@ -55,11 +54,10 @@ namespace OmniLinkBridge
|
||||
Global.verbose_unit = settings.ValidateBool("verbose_unit");
|
||||
Global.verbose_message = settings.ValidateBool("verbose_message");
|
||||
Global.verbose_lock = settings.ValidateBool("verbose_lock");
|
||||
Global.verbose_audio = settings.ValidateBool("verbose_audio");
|
||||
|
||||
// mySQL Logging
|
||||
Global.mysql_logging = settings.ValidateBool("mysql_logging");
|
||||
Global.mysql_connection = settings.CheckEnv("mysql_connection", true);
|
||||
Global.mysql_connection = settings.CheckEnv("mysql_connection");
|
||||
|
||||
// Web Service
|
||||
Global.webapi_enabled = settings.ValidateBool("webapi_enabled");
|
||||
@ -77,8 +75,8 @@ namespace OmniLinkBridge
|
||||
{
|
||||
Global.mqtt_server = settings.CheckEnv("mqtt_server");
|
||||
Global.mqtt_port = settings.ValidatePort("mqtt_port");
|
||||
Global.mqtt_username = settings.CheckEnv("mqtt_username", true);
|
||||
Global.mqtt_password = settings.CheckEnv("mqtt_password", true);
|
||||
Global.mqtt_username = settings.CheckEnv("mqtt_username");
|
||||
Global.mqtt_password = settings.CheckEnv("mqtt_password");
|
||||
Global.mqtt_prefix = settings.CheckEnv("mqtt_prefix") ?? "omnilink";
|
||||
Global.mqtt_discovery_prefix = settings.CheckEnv("mqtt_discovery_prefix") ?? "homeassistant";
|
||||
Global.mqtt_discovery_name_prefix = settings.CheckEnv("mqtt_discovery_name_prefix") ?? string.Empty;
|
||||
@ -88,12 +86,9 @@ namespace OmniLinkBridge
|
||||
|
||||
Global.mqtt_discovery_ignore_zones = settings.ValidateRange("mqtt_discovery_ignore_zones");
|
||||
Global.mqtt_discovery_ignore_units = settings.ValidateRange("mqtt_discovery_ignore_units");
|
||||
Global.mqtt_discovery_override_area = settings.LoadOverrideArea<MQTT.OverrideArea>("mqtt_discovery_override_area");
|
||||
Global.mqtt_discovery_area_code_required = settings.ValidateRange("mqtt_discovery_area_code_required");
|
||||
Global.mqtt_discovery_override_zone = settings.LoadOverrideZone<MQTT.OverrideZone>("mqtt_discovery_override_zone");
|
||||
Global.mqtt_discovery_override_unit = settings.LoadOverrideUnit<MQTT.OverrideUnit>("mqtt_discovery_override_unit");
|
||||
Global.mqtt_discovery_button_type = settings.ValidateType("mqtt_discovery_button_type", typeof(Switch), typeof(Button));
|
||||
Global.mqtt_audio_local_mute = settings.ValidateBool("mqtt_audio_local_mute");
|
||||
Global.mqtt_audio_volume_media_player = settings.ValidateBool("mqtt_audio_volume_media_player");
|
||||
}
|
||||
|
||||
// Notifications
|
||||
@ -107,113 +102,31 @@ namespace OmniLinkBridge
|
||||
{
|
||||
Global.mail_tls = settings.ValidateBool("mail_tls");
|
||||
Global.mail_port = settings.ValidatePort("mail_port");
|
||||
Global.mail_username = settings.CheckEnv("mail_username", true);
|
||||
Global.mail_password = settings.CheckEnv("mail_password", true);
|
||||
Global.mail_username = settings.CheckEnv("mail_username");
|
||||
Global.mail_password = settings.CheckEnv("mail_password");
|
||||
Global.mail_from = settings.ValidateMailFrom("mail_from");
|
||||
Global.mail_to = settings.ValidateMailTo("mail_to");
|
||||
}
|
||||
|
||||
// Prowl Notifications
|
||||
Global.prowl_key = settings.ValidateMultipleStrings("prowl_key", true);
|
||||
Global.prowl_key = settings.ValidateMultipleStrings("prowl_key");
|
||||
|
||||
// Pushover Notifications
|
||||
Global.pushover_token = settings.CheckEnv("pushover_token", true);
|
||||
Global.pushover_user = settings.ValidateMultipleStrings("pushover_user", true);
|
||||
Global.pushover_token = settings.CheckEnv("pushover_token");
|
||||
Global.pushover_user = settings.ValidateMultipleStrings("pushover_user");
|
||||
}
|
||||
|
||||
private static string CheckEnv(this NameValueCollection settings, string name, bool sensitive = false)
|
||||
private static string CheckEnv(this NameValueCollection settings, string name)
|
||||
{
|
||||
string env = Global.UseEnvironment ? Environment.GetEnvironmentVariable(name.ToUpper()) : null;
|
||||
string value = !string.IsNullOrEmpty(env) ? env : settings[name];
|
||||
|
||||
if (Global.DebugSettings)
|
||||
log.Debug("{ConfigType} {ConfigName}: {ConfigValue}",
|
||||
(!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(4), name,
|
||||
sensitive && value != null ? value.Truncate(3) + "***MASKED***" : value);
|
||||
log.Debug((!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(5) + $"{name}: {value}");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static ConcurrentDictionary<int, T> LoadOverrideArea<T>(this NameValueCollection settings, string section) where T : new()
|
||||
{
|
||||
try
|
||||
{
|
||||
ConcurrentDictionary<int, T> ret = new ConcurrentDictionary<int, T>();
|
||||
|
||||
string value = settings.CheckEnv(section);
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return ret;
|
||||
|
||||
string[] ids = value.Split(',');
|
||||
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
Dictionary<string, string> attributes = ids[i].TrimEnd(new char[] { ';' }).Split(';')
|
||||
.Select(s => s.Split('='))
|
||||
.ToDictionary(a => a[0].Trim(), a => a[1].Trim(), StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
if (!attributes.ContainsKey("id") || !int.TryParse(attributes["id"], out int attrib_id))
|
||||
throw new Exception("Missing or invalid id attribute");
|
||||
|
||||
T override_area = new T();
|
||||
|
||||
if (override_area is MQTT.OverrideArea mqtt_area)
|
||||
{
|
||||
foreach (string attribute in attributes.Keys)
|
||||
{
|
||||
switch(attribute)
|
||||
{
|
||||
case "id":
|
||||
continue;
|
||||
case "code_arm":
|
||||
if (!bool.TryParse(attributes["code_arm"], out bool code_arm))
|
||||
throw new Exception("Invalid code_arm attribute");
|
||||
mqtt_area.code_arm = code_arm;
|
||||
break;
|
||||
case "code_disarm":
|
||||
if (!bool.TryParse(attributes["code_disarm"], out bool code_disarm))
|
||||
throw new Exception("Invalid code_disarm attribute");
|
||||
mqtt_area.code_disarm = code_disarm;
|
||||
break;
|
||||
case "arm_home":
|
||||
if (!bool.TryParse(attributes["arm_home"], out bool arm_home))
|
||||
throw new Exception("Invalid arm_home attribute");
|
||||
mqtt_area.arm_home = arm_home;
|
||||
break;
|
||||
case "arm_away":
|
||||
if (!bool.TryParse(attributes["arm_away"], out bool arm_away))
|
||||
throw new Exception("Invalid arm_away attribute");
|
||||
mqtt_area.arm_away = arm_away;
|
||||
break;
|
||||
case "arm_night":
|
||||
if (!bool.TryParse(attributes["arm_night"], out bool arm_night))
|
||||
throw new Exception("Invalid arm_night attribute");
|
||||
mqtt_area.arm_night = arm_night;
|
||||
break;
|
||||
case "arm_vacation":
|
||||
if (!bool.TryParse(attributes["arm_vacation"], out bool arm_vacation))
|
||||
throw new Exception("Invalid arm_vacation attribute");
|
||||
mqtt_area.arm_vacation = arm_vacation;
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Unknown attribute {attribute}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret.TryAdd(attrib_id, override_area);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(ex, "Invalid override area specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static ConcurrentDictionary<int, T> LoadOverrideZone<T>(this NameValueCollection settings, string section) where T : new()
|
||||
{
|
||||
try
|
||||
@ -324,7 +237,7 @@ namespace OmniLinkBridge
|
||||
|
||||
private static string ValidateEncryptionKey(this NameValueCollection settings, string section)
|
||||
{
|
||||
string value = settings.CheckEnv(section, true).Replace("-","");
|
||||
string value = settings.CheckEnv(section).Replace("-","");
|
||||
|
||||
if (string.IsNullOrEmpty(value) || value.Length != 16)
|
||||
{
|
||||
@ -421,14 +334,14 @@ namespace OmniLinkBridge
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] ValidateMultipleStrings(this NameValueCollection settings, string section, bool sensitive = false)
|
||||
private static string[] ValidateMultipleStrings(this NameValueCollection settings, string section)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (settings.CheckEnv(section, true) == null)
|
||||
if (settings.CheckEnv(section) == null)
|
||||
return new string[] { };
|
||||
|
||||
return settings.CheckEnv(section, sensitive).Split(',');
|
||||
return settings.CheckEnv(section).Split(',');
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -454,21 +367,6 @@ namespace OmniLinkBridge
|
||||
}
|
||||
}
|
||||
|
||||
private static Type ValidateType(this NameValueCollection settings, string section, params Type[] types)
|
||||
{
|
||||
string value = settings.CheckEnv(section);
|
||||
|
||||
if (value == null)
|
||||
return types[0];
|
||||
|
||||
foreach (Type type in types)
|
||||
if (string.Compare(value, type.Name, true) == 0)
|
||||
return type;
|
||||
|
||||
log.Error("Invalid type specified for {section}", section);
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
private static NameValueCollection LoadCollection(string[] lines)
|
||||
{
|
||||
NameValueCollection settings = new NameValueCollection();
|
||||
|
@ -1,4 +1,10 @@
|
||||
namespace OmniLinkBridge.WebAPI
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge.WebAPI
|
||||
{
|
||||
public enum DeviceType
|
||||
{
|
||||
|
@ -1,4 +1,9 @@
|
||||
using HAI_Shared;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge.WebAPI
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using HAI_Shared;
|
||||
using OmniLinkBridge.WebAPI;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -1,4 +1,10 @@
|
||||
namespace OmniLinkBridge.WebAPI
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniLinkBridge.WebAPI
|
||||
{
|
||||
public class OverrideZone
|
||||
{
|
||||
|
@ -64,14 +64,6 @@ namespace OmniLinkBridgeTest
|
||||
Assert.AreEqual(parser.Validate, true);
|
||||
Assert.AreEqual(parser.Code, 1234);
|
||||
|
||||
// Special case for Home Assistant when code not required
|
||||
payload = "disarm,validate,None";
|
||||
parser = payload.ToCommandCode(supportValidate: true);
|
||||
Assert.AreEqual(parser.Success, true);
|
||||
Assert.AreEqual(parser.Command, "disarm");
|
||||
Assert.AreEqual(parser.Validate, false);
|
||||
Assert.AreEqual(parser.Code, 0);
|
||||
|
||||
// Falures
|
||||
payload = "disarm,1a";
|
||||
parser = payload.ToCommandCode(supportValidate: true);
|
||||
|
@ -1,13 +1,9 @@
|
||||
using HAI_Shared;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OmniLinkBridge;
|
||||
using OmniLinkBridge.Modules;
|
||||
using OmniLinkBridge.MQTT;
|
||||
using OmniLinkBridgeTest.Mock;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OmniLinkBridgeTest
|
||||
{
|
||||
@ -20,24 +16,8 @@ namespace OmniLinkBridgeTest
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
string log_format = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{SourceContext} {Level:u3}] {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
var log_config = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Console(outputTemplate: log_format);
|
||||
|
||||
Log.Logger = log_config.CreateLogger();
|
||||
|
||||
Dictionary<string, int> audioSources = new Dictionary<string, int>
|
||||
{
|
||||
{ "Radio", 1 },
|
||||
{ "Streaming", 2 },
|
||||
{ "TV", 4 }
|
||||
};
|
||||
|
||||
omniLink = new MockOmniLinkII();
|
||||
messageProcessor = new MessageProcessor(omniLink, audioSources, 8);
|
||||
messageProcessor = new MessageProcessor(omniLink);
|
||||
|
||||
omniLink.Controller.Units[395].Type = enuOL2UnitType.Flag;
|
||||
}
|
||||
@ -333,113 +313,6 @@ namespace OmniLinkBridgeTest
|
||||
// Check case insensitivity
|
||||
check(2, "LOCK", enuUnitCommand.Lock);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AudioCommand()
|
||||
{
|
||||
void check(ushort id, string payload, enuUnitCommand command, int value)
|
||||
{
|
||||
SendCommandEventArgs actual = null;
|
||||
omniLink.OnSendCommand += (sender, e) => { actual = e; };
|
||||
messageProcessor.Process($"omnilink/audio{id}/command", payload);
|
||||
SendCommandEventArgs expected = new SendCommandEventArgs()
|
||||
{
|
||||
Cmd = command,
|
||||
Par = (byte)value,
|
||||
Pr2 = id
|
||||
};
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
check(1, "ON", enuUnitCommand.AudioZone, 1);
|
||||
check(1, "OFF", enuUnitCommand.AudioZone, 0);
|
||||
|
||||
check(2, "on", enuUnitCommand.AudioZone, 1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AudioMuteCommand()
|
||||
{
|
||||
void check(ushort id, string payload, enuUnitCommand command, int value)
|
||||
{
|
||||
SendCommandEventArgs actual = null;
|
||||
omniLink.OnSendCommand += (sender, e) => { actual = e; };
|
||||
messageProcessor.Process($"omnilink/audio{id}/mute_command", payload);
|
||||
SendCommandEventArgs expected = new SendCommandEventArgs()
|
||||
{
|
||||
Cmd = command,
|
||||
Par = (byte)value,
|
||||
Pr2 = id
|
||||
};
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
check(1, "ON", enuUnitCommand.AudioZone, 3);
|
||||
check(1, "OFF", enuUnitCommand.AudioZone, 2);
|
||||
|
||||
Global.mqtt_audio_local_mute = true;
|
||||
omniLink.Controller.AudioZones[2].Volume = 50;
|
||||
|
||||
check(2, "on", enuUnitCommand.AudioVolume, 0);
|
||||
check(2, "off", enuUnitCommand.AudioVolume, 50);
|
||||
|
||||
omniLink.Controller.AudioZones[2].Volume = 0;
|
||||
|
||||
check(2, "on", enuUnitCommand.AudioVolume, 0);
|
||||
check(2, "off", enuUnitCommand.AudioVolume, 10);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AudioSourceCommand()
|
||||
{
|
||||
void check(ushort id, string payload, enuUnitCommand command, int value)
|
||||
{
|
||||
SendCommandEventArgs actual = null;
|
||||
omniLink.OnSendCommand += (sender, e) => { actual = e; };
|
||||
messageProcessor.Process($"omnilink/audio{id}/source_command", payload);
|
||||
SendCommandEventArgs expected = new SendCommandEventArgs()
|
||||
{
|
||||
Cmd = command,
|
||||
Par = (byte)value,
|
||||
Pr2 = id
|
||||
};
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
check(1, "Radio", enuUnitCommand.AudioSource, 1);
|
||||
check(1, "Streaming", enuUnitCommand.AudioSource, 2);
|
||||
|
||||
check(2, "TV", enuUnitCommand.AudioSource, 4);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AudioVolumeCommand()
|
||||
{
|
||||
void check(ushort id, string payload, enuUnitCommand command, int value)
|
||||
{
|
||||
SendCommandEventArgs actual = null;
|
||||
omniLink.OnSendCommand += (sender, e) => { actual = e; };
|
||||
messageProcessor.Process($"omnilink/audio{id}/volume_command", payload);
|
||||
SendCommandEventArgs expected = new SendCommandEventArgs()
|
||||
{
|
||||
Cmd = command,
|
||||
Par = (byte)value,
|
||||
Pr2 = id
|
||||
};
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
check(1, "100", enuUnitCommand.AudioVolume, 100);
|
||||
check(1, "75", enuUnitCommand.AudioVolume, 75);
|
||||
|
||||
check(2, "0", enuUnitCommand.AudioVolume, 0);
|
||||
|
||||
Global.mqtt_audio_volume_media_player = true;
|
||||
|
||||
check(2, "1", enuUnitCommand.AudioVolume, 100);
|
||||
check(2, "0.75", enuUnitCommand.AudioVolume, 75);
|
||||
check(2, "0", enuUnitCommand.AudioVolume, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,11 @@
|
||||
using HAI_Shared;
|
||||
using OmniLinkBridge.OmniLink;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OmniLinkBridgeTest.Mock
|
||||
{
|
||||
class MockOmniLinkII : IOmniLinkII
|
||||
{
|
||||
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public clsHAC Controller { get; private set; }
|
||||
|
||||
public event EventHandler<SendCommandEventArgs> OnSendCommand;
|
||||
@ -25,7 +21,6 @@ namespace OmniLinkBridgeTest.Mock
|
||||
|
||||
public bool SendCommand(enuUnitCommand Cmd, byte Par, ushort Pr2)
|
||||
{
|
||||
log.Verbose("Sending: {command}, Par1: {par1}, Par2: {par2}", Cmd, Par, Pr2);
|
||||
OnSendCommand?.Invoke(null, new SendCommandEventArgs() { Cmd = Cmd, Par = Par, Pr2 = Pr2 });
|
||||
return true;
|
||||
}
|
||||
|
@ -9,18 +9,6 @@ namespace OmniLinkBridgeTest.Mock
|
||||
public byte Par;
|
||||
public ushort Pr2;
|
||||
|
||||
public SendCommandEventArgs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public SendCommandEventArgs(enuUnitCommand cmd, byte par, ushort pr2)
|
||||
{
|
||||
Cmd = cmd;
|
||||
Par = par;
|
||||
Pr2 = pr2;
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (!(other is SendCommandEventArgs toCompareWith))
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OmniLinkBridge;
|
||||
using OmniLinkBridge.MQTT.HomeAssistant;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ha = OmniLinkBridge.MQTT.HomeAssistant;
|
||||
@ -37,8 +36,8 @@ namespace OmniLinkBridgeTest
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
Assert.AreEqual("1.1.1.1", Global.controller_address);
|
||||
Assert.AreEqual(4369, Global.controller_port);
|
||||
Assert.AreEqual("0000000000000001", Global.controller_key1);
|
||||
Assert.AreEqual("0000000000000002", Global.controller_key2);
|
||||
Assert.AreEqual("00-00-00-00-00-00-00-01", Global.controller_key1);
|
||||
Assert.AreEqual("00-00-00-00-00-00-00-02", Global.controller_key2);
|
||||
Assert.AreEqual("MyController", Global.controller_name);
|
||||
}
|
||||
|
||||
@ -157,8 +156,7 @@ namespace OmniLinkBridgeTest
|
||||
"mqtt_discovery_name_prefix = mynameprefix",
|
||||
"mqtt_discovery_ignore_zones = 1,2-3,4",
|
||||
"mqtt_discovery_ignore_units = 2-5,7",
|
||||
"mqtt_discovery_override_area = id=1",
|
||||
"mqtt_discovery_override_area = id=2;code_arm=true;code_disarm=true;arm_home=false;arm_away=false;arm_night=false;arm_vacation=false",
|
||||
"mqtt_discovery_area_code_required = 1",
|
||||
"mqtt_discovery_override_zone = id=5;device_class=garage_door",
|
||||
"mqtt_discovery_override_zone = id=7;device_class=motion",
|
||||
"mqtt_discovery_override_unit = id=1;type=switch",
|
||||
@ -172,25 +170,7 @@ namespace OmniLinkBridgeTest
|
||||
Assert.AreEqual("mynameprefix ", Global.mqtt_discovery_name_prefix);
|
||||
Assert.IsTrue(Global.mqtt_discovery_ignore_zones.SetEquals(new int[] { 1, 2, 3, 4 }));
|
||||
Assert.IsTrue(Global.mqtt_discovery_ignore_units.SetEquals(new int[] { 2, 3, 4, 5, 7 }));
|
||||
|
||||
Dictionary<int, OmniLinkBridge.MQTT.OverrideArea> override_area = new Dictionary<int, OmniLinkBridge.MQTT.OverrideArea>()
|
||||
{
|
||||
{ 1, new OmniLinkBridge.MQTT.OverrideArea { }},
|
||||
{ 2, new OmniLinkBridge.MQTT.OverrideArea { code_arm = true, code_disarm = true,
|
||||
arm_home = false, arm_away = false, arm_night = false, arm_vacation = false }},
|
||||
};
|
||||
|
||||
Assert.AreEqual(override_area.Count, Global.mqtt_discovery_override_area.Count);
|
||||
foreach (KeyValuePair<int, OmniLinkBridge.MQTT.OverrideArea> pair in override_area)
|
||||
{
|
||||
Global.mqtt_discovery_override_area.TryGetValue(pair.Key, out OmniLinkBridge.MQTT.OverrideArea value);
|
||||
Assert.AreEqual(override_area[pair.Key].code_arm, value.code_arm);
|
||||
Assert.AreEqual(override_area[pair.Key].code_disarm, value.code_disarm);
|
||||
Assert.AreEqual(override_area[pair.Key].arm_home, value.arm_home);
|
||||
Assert.AreEqual(override_area[pair.Key].arm_away, value.arm_away);
|
||||
Assert.AreEqual(override_area[pair.Key].arm_night, value.arm_night);
|
||||
Assert.AreEqual(override_area[pair.Key].arm_vacation, value.arm_vacation);
|
||||
}
|
||||
Assert.IsTrue(Global.mqtt_discovery_area_code_required.SetEquals(new int[] { 1 }));
|
||||
|
||||
Dictionary<int, OmniLinkBridge.MQTT.OverrideZone> override_zone = new Dictionary<int, OmniLinkBridge.MQTT.OverrideZone>()
|
||||
{
|
||||
@ -217,17 +197,6 @@ namespace OmniLinkBridgeTest
|
||||
Global.mqtt_discovery_override_unit.TryGetValue(pair.Key, out OmniLinkBridge.MQTT.OverrideUnit value);
|
||||
Assert.AreEqual(override_unit[pair.Key].type, value.type);
|
||||
}
|
||||
|
||||
Assert.AreEqual(Global.mqtt_discovery_button_type, typeof(Switch));
|
||||
|
||||
// Test additional settings
|
||||
lines.AddRange(new string[]
|
||||
{
|
||||
"mqtt_discovery_button_type = button"
|
||||
});
|
||||
Settings.LoadSettings(lines.ToArray());
|
||||
|
||||
Assert.AreEqual(Global.mqtt_discovery_button_type, typeof(Button));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
32
README.md
32
README.md
@ -326,38 +326,6 @@ PUB omnilink/lockX/command
|
||||
string lock, unlock
|
||||
```
|
||||
|
||||
### Audio Sources
|
||||
```
|
||||
SUB omnilink/sourceXX/name
|
||||
string Audio source name
|
||||
```
|
||||
|
||||
### Audio Zones
|
||||
```
|
||||
SUB omnilink/audioXX/name
|
||||
string Audio zone name
|
||||
|
||||
SUB omnilink/audioXX/state
|
||||
PUB omnilink/audioXX/command
|
||||
string OFF, ON
|
||||
note Use audio 0 to change all audio zones
|
||||
|
||||
SUB omnilink/audioXX/mute_state
|
||||
PUB omnilink/audioXX/mute_command
|
||||
string OFF, ON
|
||||
note Use audio 0 to change all audio zones
|
||||
|
||||
SUB omnilink/audioXX/source_state
|
||||
PUB omnilink/audioXX/source_command
|
||||
string Source name
|
||||
note Refer to omnilink/sourceXX/name
|
||||
|
||||
SUB omnilink/audioXX/volume_state
|
||||
PUB omnilink/audioXX/volume_command
|
||||
int Level from 0 to 100 percent
|
||||
double Level from 0.00 to 1.00 (mqtt_audio_volume_media_player = yes)
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user