mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2024-12-22 18:52:24 +00:00
- Switch to structured logging and add telemetry
This commit is contained in:
parent
7d87416915
commit
8e637db459
|
@ -28,4 +28,4 @@ EXPOSE 8000/tcp
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app .
|
COPY --from=build /app .
|
||||||
CMD [ "mono", "OmniLinkBridge.exe", "-i", "-c", "/config/OmniLinkBridge.ini", "-e", "-s", "/config/WebSubscriptions.json" ]
|
CMD [ "mono", "OmniLinkBridge.exe", "-i", "-c", "/config/OmniLinkBridge.ini", "-e", "-s", "/config/WebSubscriptions.json", "-lf", "disable" ]
|
|
@ -1,37 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<configSections>
|
|
||||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
|
|
||||||
</configSections>
|
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||||
</startup>
|
</startup>
|
||||||
<log4net>
|
|
||||||
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
|
|
||||||
<layout type="log4net.Layout.PatternLayout">
|
|
||||||
<param name="ConversionPattern" value="%date %-5level: %message%newline"/>
|
|
||||||
</layout>
|
|
||||||
</appender>
|
|
||||||
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
|
|
||||||
<file value="log.txt"/>
|
|
||||||
<appendToFile value="true"/>
|
|
||||||
<rollingStyle value="Composite"/>
|
|
||||||
<datePattern value="yyyyMMdd"/>
|
|
||||||
<maxSizeRollBackups value="10"/>
|
|
||||||
<maximumFileSize value="5MB"/>
|
|
||||||
<immediateFlush value="true"/>
|
|
||||||
<layout type="log4net.Layout.PatternLayout">
|
|
||||||
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
|
|
||||||
</layout>
|
|
||||||
<filter type="log4net.Filter.LevelRangeFilter">
|
|
||||||
<levelMin value="WARN"/>
|
|
||||||
<levelMax value="FATAL"/>
|
|
||||||
</filter>
|
|
||||||
</appender>
|
|
||||||
<root>
|
|
||||||
<level value="ALL"/>
|
|
||||||
<appender-ref ref="TraceAppender"/>
|
|
||||||
<appender-ref ref="RollingFileAppender"/>
|
|
||||||
</root>
|
|
||||||
</log4net>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using log4net;
|
using OmniLinkBridge.Modules;
|
||||||
using OmniLinkBridge.Modules;
|
using Serilog;
|
||||||
|
using Serilog.Context;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -9,11 +11,13 @@ namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
public class CoreServer
|
public class CoreServer
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private OmniLinkII omnilink;
|
private OmniLinkII omnilink;
|
||||||
private readonly List<IModule> modules = new List<IModule>();
|
private readonly List<IModule> modules = new List<IModule>();
|
||||||
private readonly List<Task> tasks = new List<Task>();
|
private readonly List<Task> tasks = new List<Task>();
|
||||||
|
private readonly ManualResetEvent quitEvent = new ManualResetEvent(false);
|
||||||
|
private DateTime startTime;
|
||||||
|
|
||||||
public CoreServer()
|
public CoreServer()
|
||||||
{
|
{
|
||||||
|
@ -23,11 +27,6 @@ namespace OmniLinkBridge
|
||||||
|
|
||||||
private void Server()
|
private void Server()
|
||||||
{
|
{
|
||||||
Global.running = true;
|
|
||||||
|
|
||||||
log.Debug("Starting up server " +
|
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
|
||||||
|
|
||||||
// Controller connection
|
// Controller connection
|
||||||
modules.Add(omnilink = new OmniLinkII(Global.controller_address, Global.controller_port, Global.controller_key1, Global.controller_key2));
|
modules.Add(omnilink = new OmniLinkII(Global.controller_address, Global.controller_port, Global.controller_key1, Global.controller_key2));
|
||||||
|
|
||||||
|
@ -43,6 +42,12 @@ namespace OmniLinkBridge
|
||||||
if(Global.mqtt_enabled)
|
if(Global.mqtt_enabled)
|
||||||
modules.Add(new MQTTModule(omnilink));
|
modules.Add(new MQTTModule(omnilink));
|
||||||
|
|
||||||
|
startTime = DateTime.Now;
|
||||||
|
|
||||||
|
using (LogContext.PushProperty("Telemetry", "Startup"))
|
||||||
|
log.Information("Started version {Version} on {OperatingSystem} with {Modules}",
|
||||||
|
Assembly.GetExecutingAssembly().GetName().Version, Environment.OSVersion, modules);
|
||||||
|
|
||||||
// Startup modules
|
// Startup modules
|
||||||
foreach (IModule module in modules)
|
foreach (IModule module in modules)
|
||||||
{
|
{
|
||||||
|
@ -52,14 +57,11 @@ namespace OmniLinkBridge
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for all threads to stop
|
quitEvent.WaitOne();
|
||||||
Task.WaitAll(tasks.ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
Global.running = false;
|
|
||||||
|
|
||||||
// Shutdown modules
|
// Shutdown modules
|
||||||
foreach (IModule module in modules)
|
foreach (IModule module in modules)
|
||||||
module.Shutdown();
|
module.Shutdown();
|
||||||
|
@ -68,7 +70,12 @@ namespace OmniLinkBridge
|
||||||
if (tasks != null)
|
if (tasks != null)
|
||||||
Task.WaitAll(tasks.ToArray());
|
Task.WaitAll(tasks.ToArray());
|
||||||
|
|
||||||
log.Debug("Shutdown completed");
|
using (LogContext.PushProperty("Telemetry", "Shutdown"))
|
||||||
|
log.Information("Shutdown completed with uptime {Uptime}", (DateTime.Now - startTime).ToString());
|
||||||
|
|
||||||
|
Log.CloseAndFlush();
|
||||||
|
|
||||||
|
quitEvent.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace OmniLinkBridge
|
namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
|
@ -23,6 +24,11 @@ namespace OmniLinkBridge
|
||||||
return (b & (1 << pos)) != 0;
|
return (b & (1 << pos)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ToSpaceTitleCase(this string phrase)
|
||||||
|
{
|
||||||
|
return Regex.Replace(phrase, "(\\B[A-Z])", " $1");
|
||||||
|
}
|
||||||
|
|
||||||
public static List<int> ParseRanges(this string ranges)
|
public static List<int> ParseRanges(this string ranges)
|
||||||
{
|
{
|
||||||
string[] groups = ranges.Split(',');
|
string[] groups = ranges.Split(',');
|
||||||
|
|
|
@ -7,10 +7,8 @@ namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
public abstract class Global
|
public abstract class Global
|
||||||
{
|
{
|
||||||
public static bool running;
|
public static bool DebugSettings { get; set; }
|
||||||
|
public static bool UseEnvironment { get; set; }
|
||||||
// Config File
|
|
||||||
public static string config_file;
|
|
||||||
|
|
||||||
// HAI / Leviton Omni Controller
|
// HAI / Leviton Omni Controller
|
||||||
public static string controller_address;
|
public static string controller_address;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using HAI_Shared;
|
using HAI_Shared;
|
||||||
using log4net;
|
|
||||||
using OmniLinkBridge.OmniLink;
|
using OmniLinkBridge.OmniLink;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -10,7 +10,7 @@ namespace OmniLinkBridge.MQTT
|
||||||
{
|
{
|
||||||
public class MessageProcessor
|
public class MessageProcessor
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(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);
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ namespace OmniLinkBridge.MQTT
|
||||||
|| !ushort.TryParse(match.Groups[2].Value, out ushort id))
|
|| !ushort.TryParse(match.Groups[2].Value, out ushort id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log.Debug($"Received: Type: {type.ToString()}, Id: {id}, Command: {topic.ToString()}, Value: {payload}");
|
log.Debug("Received: Type: {type}, Id: {id}, Command: {command}, Value: {value}",
|
||||||
|
type.ToString(), id, topic.ToString(), payload);
|
||||||
|
|
||||||
if (type == CommandTypes.area && id <= OmniLink.Controller.Areas.Count)
|
if (type == CommandTypes.area && id <= OmniLink.Controller.Areas.Count)
|
||||||
ProcessAreaReceived(OmniLink.Controller.Areas[id], topic, payload);
|
ProcessAreaReceived(OmniLink.Controller.Areas[id], topic, payload);
|
||||||
|
@ -68,7 +69,7 @@ namespace OmniLinkBridge.MQTT
|
||||||
if (area.Number == 0)
|
if (area.Number == 0)
|
||||||
log.Debug("SetArea: 0 implies all areas will be changed");
|
log.Debug("SetArea: 0 implies all areas will be changed");
|
||||||
|
|
||||||
log.Debug("SetArea: " + area.Number + " to " + cmd.ToString().Replace("arm_", "").Replace("_", " "));
|
log.Debug("SetArea: {id} to {value}", area.Number, cmd.ToString().Replace("arm_", "").Replace("_", " "));
|
||||||
OmniLink.SendCommand(AreaMapping[cmd], 0, (ushort)area.Number);
|
OmniLink.SendCommand(AreaMapping[cmd], 0, (ushort)area.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +84,7 @@ namespace OmniLinkBridge.MQTT
|
||||||
{
|
{
|
||||||
if (command == Topic.command && Enum.TryParse(payload, true, out ZoneCommands cmd))
|
if (command == Topic.command && Enum.TryParse(payload, true, out ZoneCommands cmd))
|
||||||
{
|
{
|
||||||
log.Debug("SetZone: " + zone.Number + " to " + payload);
|
log.Debug("SetZone: {id} to {value}", zone.Number, payload);
|
||||||
OmniLink.SendCommand(ZoneMapping[cmd], 0, (ushort)zone.Number);
|
OmniLink.SendCommand(ZoneMapping[cmd], 0, (ushort)zone.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,13 +101,13 @@ namespace OmniLinkBridge.MQTT
|
||||||
{
|
{
|
||||||
if (string.Compare(unit.ToState(), cmd.ToString()) != 0)
|
if (string.Compare(unit.ToState(), cmd.ToString()) != 0)
|
||||||
{
|
{
|
||||||
log.Debug("SetUnit: " + unit.Number + " to " + cmd.ToString());
|
log.Debug("SetUnit: {id} to {value}", unit.Number, cmd.ToString());
|
||||||
OmniLink.SendCommand(UnitMapping[cmd], 0, (ushort)unit.Number);
|
OmniLink.SendCommand(UnitMapping[cmd], 0, (ushort)unit.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (command == Topic.brightness_command && int.TryParse(payload, out int unitValue))
|
else if (command == Topic.brightness_command && int.TryParse(payload, out int unitValue))
|
||||||
{
|
{
|
||||||
log.Debug("SetUnit: " + unit.Number + " to " + payload + "%");
|
log.Debug("SetUnit: {id} to {value}%", unit.Number, payload);
|
||||||
|
|
||||||
OmniLink.SendCommand(enuUnitCommand.Level, BitConverter.GetBytes(unitValue)[0], (ushort)unit.Number);
|
OmniLink.SendCommand(enuUnitCommand.Level, BitConverter.GetBytes(unitValue)[0], (ushort)unit.Number);
|
||||||
|
|
||||||
|
@ -129,7 +130,8 @@ namespace OmniLinkBridge.MQTT
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = tempLow.ToOmniTemp();
|
int temp = tempLow.ToOmniTemp();
|
||||||
log.Debug("SetThermostatHeatSetpoint: " + thermostat.Number + " to " + payload + tempUnit + "(" + temp + ")");
|
log.Debug("SetThermostatHeatSetpoint: {id} to {value}{temperatureUnit} ({temp})",
|
||||||
|
thermostat.Number, payload, tempUnit, temp);
|
||||||
OmniLink.SendCommand(enuUnitCommand.SetLowSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.SetLowSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.temperature_cool_command && double.TryParse(payload, out double tempHigh))
|
else if (command == Topic.temperature_cool_command && double.TryParse(payload, out double tempHigh))
|
||||||
|
@ -142,35 +144,36 @@ namespace OmniLinkBridge.MQTT
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = tempHigh.ToOmniTemp();
|
int temp = tempHigh.ToOmniTemp();
|
||||||
log.Debug("SetThermostatCoolSetpoint: " + thermostat.Number + " to " + payload + tempUnit + "(" + temp + ")");
|
log.Debug("SetThermostatCoolSetpoint: {id} to {value}{temperatureUnit} ({temp})",
|
||||||
|
thermostat.Number, payload, tempUnit, temp);
|
||||||
OmniLink.SendCommand(enuUnitCommand.SetHighSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.SetHighSetPt, BitConverter.GetBytes(temp)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.humidify_command && double.TryParse(payload, out double humidify))
|
else if (command == Topic.humidify_command && double.TryParse(payload, out double humidify))
|
||||||
{
|
{
|
||||||
// Humidity is reported where Fahrenheit temperatures 0-100 correspond to 0-100% relative humidity
|
// Humidity is reported where Fahrenheit temperatures 0-100 correspond to 0-100% relative humidity
|
||||||
int level = humidify.ToCelsius().ToOmniTemp();
|
int level = humidify.ToCelsius().ToOmniTemp();
|
||||||
log.Debug("SetThermostatHumidifySetpoint: " + thermostat.Number + " to " + payload + "% (" + level + ")");
|
log.Debug("SetThermostatHumidifySetpoint: {id} to {value}% ({level})", thermostat.Number, payload, level);
|
||||||
OmniLink.SendCommand(enuUnitCommand.SetHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.SetHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.dehumidify_command && double.TryParse(payload, out double dehumidify))
|
else if (command == Topic.dehumidify_command && double.TryParse(payload, out double dehumidify))
|
||||||
{
|
{
|
||||||
int level = dehumidify.ToCelsius().ToOmniTemp();
|
int level = dehumidify.ToCelsius().ToOmniTemp();
|
||||||
log.Debug("SetThermostatDehumidifySetpoint: " + thermostat.Number + " to " + payload + "% (" + level + ")");
|
log.Debug("SetThermostatDehumidifySetpoint: {id} to {value}% ({level})", thermostat.Number, payload, level);
|
||||||
OmniLink.SendCommand(enuUnitCommand.SetDeHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.SetDeHumidifySetPt, BitConverter.GetBytes(level)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.mode_command && Enum.TryParse(payload, true, out enuThermostatMode mode))
|
else if (command == Topic.mode_command && Enum.TryParse(payload, true, out enuThermostatMode mode))
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatMode: " + thermostat.Number + " to " + payload);
|
log.Debug("SetThermostatMode: {id} to {value}", thermostat.Number, payload);
|
||||||
OmniLink.SendCommand(enuUnitCommand.Mode, BitConverter.GetBytes((int)mode)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.Mode, BitConverter.GetBytes((int)mode)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.fan_mode_command && Enum.TryParse(payload, true, out enuThermostatFanMode fanMode))
|
else if (command == Topic.fan_mode_command && Enum.TryParse(payload, true, out enuThermostatFanMode fanMode))
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatFanMode: " + thermostat.Number + " to " + payload);
|
log.Debug("SetThermostatFanMode: {id} to {value}", thermostat.Number, payload);
|
||||||
OmniLink.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes((int)fanMode)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes((int)fanMode)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
else if (command == Topic.hold_command && Enum.TryParse(payload, true, out enuThermostatHoldMode holdMode))
|
else if (command == Topic.hold_command && Enum.TryParse(payload, true, out enuThermostatHoldMode holdMode))
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatHold: " + thermostat.Number + " to " + payload);
|
log.Debug("SetThermostatHold: {id} to {value}", thermostat.Number, payload);
|
||||||
OmniLink.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes((int)holdMode)[0], (ushort)thermostat.Number);
|
OmniLink.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes((int)holdMode)[0], (ushort)thermostat.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,7 +182,7 @@ namespace OmniLinkBridge.MQTT
|
||||||
{
|
{
|
||||||
if (command == Topic.command && Enum.TryParse(payload, true, out UnitCommands cmd) && cmd == UnitCommands.ON)
|
if (command == Topic.command && Enum.TryParse(payload, true, out UnitCommands cmd) && cmd == UnitCommands.ON)
|
||||||
{
|
{
|
||||||
log.Debug("PushButton: " + button.Number);
|
log.Debug("PushButton: {id}", button.Number);
|
||||||
OmniLink.SendCommand(enuUnitCommand.Button, 0, (ushort)button.Number);
|
OmniLink.SendCommand(enuUnitCommand.Button, 0, (ushort)button.Number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +199,7 @@ namespace OmniLinkBridge.MQTT
|
||||||
{
|
{
|
||||||
if (command == Topic.command && Enum.TryParse(payload, true, out MessageCommands cmd))
|
if (command == Topic.command && Enum.TryParse(payload, true, out MessageCommands cmd))
|
||||||
{
|
{
|
||||||
log.Debug("SetMessage: " + message.Number + " to " + cmd.ToString().Replace("_", " "));
|
log.Debug("SetMessage: {id} to {value}", message.Number, cmd.ToString().Replace("_", " "));
|
||||||
|
|
||||||
byte par = 0;
|
byte par = 0;
|
||||||
if (cmd == MessageCommands.show_no_beep)
|
if (cmd == MessageCommands.show_no_beep)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using log4net;
|
using OmniLinkBridge.Notifications;
|
||||||
using OmniLinkBridge.Notifications;
|
|
||||||
using OmniLinkBridge.OmniLink;
|
using OmniLinkBridge.OmniLink;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
@ -12,7 +12,9 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
public class LoggerModule : IModule
|
public class LoggerModule : IModule
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private bool running = true;
|
||||||
|
|
||||||
private readonly OmniLinkII omnilink;
|
private readonly OmniLinkII omnilink;
|
||||||
private readonly List<string> alarms = new List<string>();
|
private readonly List<string> alarms = new List<string>();
|
||||||
|
@ -41,26 +43,22 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
if (Global.mysql_logging)
|
if (Global.mysql_logging)
|
||||||
{
|
{
|
||||||
log.Info("Connecting to database");
|
log.Information("Connecting to database");
|
||||||
|
|
||||||
mysql_conn = new OdbcConnection(Global.mysql_connection);
|
mysql_conn = new OdbcConnection(Global.mysql_connection);
|
||||||
|
|
||||||
// Must make an initial connection
|
|
||||||
if (!DBOpen())
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// End gracefully when not logging or database queue empty
|
// End gracefully when not logging or database queue empty
|
||||||
if (!Global.running && (!Global.mysql_logging || DBQueueCount() == 0))
|
if (!running && (!Global.mysql_logging || DBQueueCount() == 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Make sure database connection is active
|
// Make sure database connection is active
|
||||||
if (Global.mysql_logging && mysql_conn.State != ConnectionState.Open)
|
if (Global.mysql_logging && mysql_conn.State != ConnectionState.Open)
|
||||||
{
|
{
|
||||||
// Nothing we can do if shutting down
|
// Nothing we can do if shutting down
|
||||||
if (!Global.running)
|
if (!running)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (mysql_retry < DateTime.Now)
|
if (mysql_retry < DateTime.Now)
|
||||||
|
@ -100,11 +98,11 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
if (mysql_conn.State != ConnectionState.Open)
|
if (mysql_conn.State != ConnectionState.Open)
|
||||||
{
|
{
|
||||||
log.Warn("Lost connection to database");
|
log.Warning("Lost connection to database");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log.Error("Error executing query\r\n" + query, ex);
|
log.Error(ex, "Error executing {query}", query);
|
||||||
|
|
||||||
// Prevent an endless loop from failed query
|
// Prevent an endless loop from failed query
|
||||||
lock (mysql_lock)
|
lock (mysql_lock)
|
||||||
|
@ -119,6 +117,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
|
running = false;
|
||||||
trigger.Set();
|
trigger.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +197,7 @@ namespace OmniLinkBridge.Modules
|
||||||
e.Area.AreaDuressAlarmText + "','" + status + "')");
|
e.Area.AreaDuressAlarmText + "','" + status + "')");
|
||||||
|
|
||||||
if (Global.verbose_area)
|
if (Global.verbose_area)
|
||||||
log.Debug("AreaStatus " + e.ID + " " + e.Area.Name + ", Status: " + status);
|
log.Verbose("AreaStatus {id} {name}, Status: {status}", e.ID, e.Area.Name, status);
|
||||||
|
|
||||||
if (Global.notify_area && e.Area.LastMode != e.Area.AreaMode)
|
if (Global.notify_area && e.Area.LastMode != e.Area.AreaMode)
|
||||||
Notification.Notify("Security", e.Area.Name + " " + e.Area.ModeText());
|
Notification.Notify("Security", e.Area.Name + " " + e.Area.ModeText());
|
||||||
|
@ -213,9 +212,9 @@ namespace OmniLinkBridge.Modules
|
||||||
if (Global.verbose_zone)
|
if (Global.verbose_zone)
|
||||||
{
|
{
|
||||||
if (e.Zone.IsTemperatureZone())
|
if (e.Zone.IsTemperatureZone())
|
||||||
log.Debug("ZoneStatus " + e.ID + " " + e.Zone.Name + ", Temp: " + e.Zone.TempText());
|
log.Verbose("ZoneStatus {id} {name}, Temp: {temp}", e.ID, e.Zone.Name, e.Zone.TempText());
|
||||||
else
|
else
|
||||||
log.Debug("ZoneStatus " + e.ID + " " + e.Zone.Name + ", Status: " + e.Zone.StatusText());
|
log.Verbose("ZoneStatus {id} {name}, Status: {status}", e.ID, e.Zone.Name, e.Zone.StatusText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,13 +240,15 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
// Ignore events fired by thermostat polling
|
// Ignore events fired by thermostat polling
|
||||||
if (!e.EventTimer && Global.verbose_thermostat)
|
if (!e.EventTimer && Global.verbose_thermostat)
|
||||||
log.Debug("ThermostatStatus " + e.ID + " " + e.Thermostat.Name +
|
log.Verbose("ThermostatStatus {id} {name}, Status: {temp} {status}, " +
|
||||||
", Status: " + e.Thermostat.TempText() + " " + e.Thermostat.HorC_StatusText() +
|
"Heat {heat}, Cool: {cool}, Mode: {mode}, Fan: {fan}, Hold: {hold}",
|
||||||
", Heat: " + e.Thermostat.HeatSetpointText() +
|
e.ID, e.Thermostat.Name,
|
||||||
", Cool: " + e.Thermostat.CoolSetpointText() +
|
e.Thermostat.TempText(), e.Thermostat.HorC_StatusText(),
|
||||||
", Mode: " + e.Thermostat.ModeText() +
|
e.Thermostat.HeatSetpointText(),
|
||||||
", Fan: " + e.Thermostat.FanModeText() +
|
e.Thermostat.CoolSetpointText(),
|
||||||
", Hold: " + e.Thermostat.HoldStatusText());
|
e.Thermostat.ModeText(),
|
||||||
|
e.Thermostat.FanModeText(),
|
||||||
|
e.Thermostat.HoldStatusText());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Omnilink_OnUnitStatus(object sender, UnitStatusEventArgs e)
|
private void Omnilink_OnUnitStatus(object sender, UnitStatusEventArgs e)
|
||||||
|
@ -266,7 +267,7 @@ namespace OmniLinkBridge.Modules
|
||||||
status + "','" + e.Unit.Status + "','" + e.Unit.StatusTime + "')");
|
status + "','" + e.Unit.Status + "','" + e.Unit.StatusTime + "')");
|
||||||
|
|
||||||
if (Global.verbose_unit)
|
if (Global.verbose_unit)
|
||||||
log.Debug("UnitStatus " + e.ID + " " + e.Unit.Name + ", Status: " + status);
|
log.Verbose("UnitStatus {id} {name}, Status: {status}", e.ID, e.Unit.Name, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Omnilink_OnMessageStatus(object sender, MessageStatusEventArgs e)
|
private void Omnilink_OnMessageStatus(object sender, MessageStatusEventArgs e)
|
||||||
|
@ -276,7 +277,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.ID + " " + e.Message.Name + ", " + e.Message.StatusText());
|
log.Verbose("MessageStatus {id} {name}, Status: {status}", 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());
|
||||||
|
@ -289,7 +290,7 @@ namespace OmniLinkBridge.Modules
|
||||||
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + e.Type.ToString() + "','" + e.Value + "')");
|
VALUES ('" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "','" + e.Type.ToString() + "','" + e.Value + "')");
|
||||||
|
|
||||||
if (Global.verbose_event)
|
if (Global.verbose_event)
|
||||||
log.Debug("SystemEvent " + e.Type.ToString() + " " + e.Value);
|
log.Verbose("SystemEvent {name} {status}", e.Type.ToString(), e.Value);
|
||||||
|
|
||||||
if (e.SendNotification)
|
if (e.SendNotification)
|
||||||
Notification.Notify("SystemEvent", e.Type.ToString() + " " + e.Value);
|
Notification.Notify("SystemEvent", e.Type.ToString() + " " + e.Value);
|
||||||
|
@ -306,7 +307,7 @@ namespace OmniLinkBridge.Modules
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("Failed to connect to database", ex);
|
log.Error(ex, "Failed to connect to database");
|
||||||
mysql_retry = DateTime.Now.AddMinutes(1);
|
mysql_retry = DateTime.Now.AddMinutes(1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using HAI_Shared;
|
using HAI_Shared;
|
||||||
using log4net;
|
|
||||||
using MQTTnet;
|
using MQTTnet;
|
||||||
using MQTTnet.Client;
|
using MQTTnet.Client;
|
||||||
using MQTTnet.Client.Connecting;
|
using MQTTnet.Client.Connecting;
|
||||||
|
@ -11,6 +10,7 @@ using MQTTnet.Protocol;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OmniLinkBridge.MQTT;
|
using OmniLinkBridge.MQTT;
|
||||||
using OmniLinkBridge.OmniLink;
|
using OmniLinkBridge.OmniLink;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -22,7 +22,7 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
public class MQTTModule : IModule
|
public class MQTTModule : IModule
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public static DeviceRegistry MqttDeviceRegistry { get; set; }
|
public static DeviceRegistry MqttDeviceRegistry { get; set; }
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ namespace OmniLinkBridge.Modules
|
||||||
if (ControllerConnected)
|
if (ControllerConnected)
|
||||||
PublishConfig();
|
PublishConfig();
|
||||||
});
|
});
|
||||||
MqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate((e) => log.Debug("Error connecting " + e.Exception.Message));
|
MqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate((e) => log.Error("Error connecting {reason}", e.Exception.Message));
|
||||||
MqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate((e) => log.Debug("Disconnected"));
|
MqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate((e) => log.Debug("Disconnected"));
|
||||||
|
|
||||||
MqttClient.StartAsync(manoptions);
|
MqttClient.StartAsync(manoptions);
|
||||||
|
@ -118,8 +118,7 @@ namespace OmniLinkBridge.Modules
|
||||||
// Wait until shutdown
|
// Wait until shutdown
|
||||||
trigger.WaitOne();
|
trigger.WaitOne();
|
||||||
|
|
||||||
log.Debug("Publishing controller offline");
|
PublishControllerStatus("offline");
|
||||||
PublishAsync($"{Global.mqtt_prefix}/status", "offline");
|
|
||||||
|
|
||||||
MqttClient.StopAsync();
|
MqttClient.StopAsync();
|
||||||
}
|
}
|
||||||
|
@ -142,10 +141,13 @@ namespace OmniLinkBridge.Modules
|
||||||
ControllerConnected = false;
|
ControllerConnected = false;
|
||||||
|
|
||||||
if (MqttClient.IsConnected)
|
if (MqttClient.IsConnected)
|
||||||
{
|
PublishControllerStatus("offline");
|
||||||
log.Debug("Publishing controller offline");
|
}
|
||||||
PublishAsync($"{Global.mqtt_prefix}/status", "offline");
|
|
||||||
}
|
private void PublishControllerStatus(string status)
|
||||||
|
{
|
||||||
|
log.Information("Publishing controller {status}", status);
|
||||||
|
PublishAsync($"{Global.mqtt_prefix}/status", status);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PublishConfig()
|
private void PublishConfig()
|
||||||
|
@ -157,15 +159,14 @@ namespace OmniLinkBridge.Modules
|
||||||
PublishButtons();
|
PublishButtons();
|
||||||
PublishMessages();
|
PublishMessages();
|
||||||
|
|
||||||
log.Debug("Publishing controller online");
|
PublishControllerStatus("online");
|
||||||
PublishAsync($"{Global.mqtt_prefix}/status", "online");
|
|
||||||
PublishAsync($"{Global.mqtt_prefix}/model", OmniLink.Controller.GetModelText());
|
PublishAsync($"{Global.mqtt_prefix}/model", OmniLink.Controller.GetModelText());
|
||||||
PublishAsync($"{Global.mqtt_prefix}/version", OmniLink.Controller.GetVersionText());
|
PublishAsync($"{Global.mqtt_prefix}/version", OmniLink.Controller.GetVersionText());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PublishAreas()
|
private void PublishAreas()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing areas");
|
log.Debug("Publishing {type}", "areas");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Areas.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Areas.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -214,7 +215,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void PublishZones()
|
private void PublishZones()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing zones");
|
log.Debug("Publishing {type}", "zones");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Zones.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Zones.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -255,7 +256,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void PublishUnits()
|
private void PublishUnits()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing units");
|
log.Debug("Publishing {type}", "units");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Units.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Units.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -289,7 +290,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void PublishThermostats()
|
private void PublishThermostats()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing thermostats");
|
log.Debug("Publishing {type}", "thermostats");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Thermostats.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Thermostats.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -318,7 +319,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void PublishButtons()
|
private void PublishButtons()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing buttons");
|
log.Debug("Publishing {type}", "buttons");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -342,7 +343,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void PublishMessages()
|
private void PublishMessages()
|
||||||
{
|
{
|
||||||
log.Debug("Publishing messages");
|
log.Debug("Publishing {type}", "messages");
|
||||||
|
|
||||||
for (ushort i = 1; i <= OmniLink.Controller.Messages.Count; i++)
|
for (ushort i = 1; i <= OmniLink.Controller.Messages.Count; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using HAI_Shared;
|
using HAI_Shared;
|
||||||
using OmniLinkBridge.OmniLink;
|
using OmniLinkBridge.OmniLink;
|
||||||
using log4net;
|
using Serilog;
|
||||||
|
using Serilog.Context;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -12,7 +13,9 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
public class OmniLinkII : IModule, IOmniLinkII
|
public class OmniLinkII : IModule, IOmniLinkII
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private bool running = true;
|
||||||
|
|
||||||
// OmniLink Controller
|
// OmniLink Controller
|
||||||
public clsHAC Controller { get; private set; }
|
public clsHAC Controller { get; private set; }
|
||||||
|
@ -54,7 +57,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
public void Startup()
|
public void Startup()
|
||||||
{
|
{
|
||||||
while (Global.running)
|
while(running)
|
||||||
{
|
{
|
||||||
// Make sure controller connection is active
|
// Make sure controller connection is active
|
||||||
if (Controller.Connection.ConnectionState == enuOmniLinkConnectionState.Offline &&
|
if (Controller.Connection.ConnectionState == enuOmniLinkConnectionState.Offline &&
|
||||||
|
@ -71,6 +74,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
|
running = false;
|
||||||
trigger.Set();
|
trigger.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +96,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void Disconnect()
|
private void Disconnect()
|
||||||
{
|
{
|
||||||
log.Info("CONNECTION STATUS: Disconnecting");
|
log.Debug("Controller Status: {connectionStatus}", "Disconnecting");
|
||||||
|
|
||||||
if (Controller.Connection.ConnectionState != enuOmniLinkConnectionState.Offline)
|
if (Controller.Connection.ConnectionState != enuOmniLinkConnectionState.Offline)
|
||||||
Controller.Connection.Disconnect();
|
Controller.Connection.Disconnect();
|
||||||
|
@ -100,187 +104,86 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private void HandleConnectStatus(enuOmniLinkCommStatus CS)
|
private void HandleConnectStatus(enuOmniLinkCommStatus CS)
|
||||||
{
|
{
|
||||||
|
var status = CS.ToString().ToSpaceTitleCase();
|
||||||
|
|
||||||
switch (CS)
|
switch (CS)
|
||||||
{
|
{
|
||||||
case enuOmniLinkCommStatus.NoReply:
|
case enuOmniLinkCommStatus.Connecting:
|
||||||
log.Error("CONNECTION STATUS: No Reply");
|
log.Debug("Controller Status: {connectionStatus}", status);
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnrecognizedReply:
|
|
||||||
log.Error("CONNECTION STATUS: Unrecognized Reply");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnsupportedProtocol:
|
|
||||||
log.Error("CONNECTION STATUS: Unsupported Protocol");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ClientSessionTerminated:
|
|
||||||
log.Error("CONNECTION STATUS: Client Session Terminated");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ControllerSessionTerminated:
|
|
||||||
log.Error("CONNECTION STATUS: Controller Session Terminated");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.CannotStartNewSession:
|
|
||||||
log.Error("CONNECTION STATUS: Cannot Start New Session");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.LoginFailed:
|
|
||||||
log.Error("CONNECTION STATUS: Login Failed");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnableToOpenSocket:
|
|
||||||
log.Error("CONNECTION STATUS: Unable To Open Socket");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnableToConnect:
|
|
||||||
log.Error("CONNECTION STATUS: Unable To Connect");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.SocketClosed:
|
|
||||||
log.Error("CONNECTION STATUS: Socket Closed");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnexpectedError:
|
|
||||||
log.Error("CONNECTION STATUS: Unexpected Error");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnableToCreateSocket:
|
|
||||||
log.Error("CONNECTION STATUS: Unable To Create Socket");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.Retrying:
|
|
||||||
log.Warn("CONNECTION STATUS: Retrying");
|
|
||||||
break;
|
break;
|
||||||
case enuOmniLinkCommStatus.Connected:
|
case enuOmniLinkCommStatus.Connected:
|
||||||
IdentifyController();
|
IdentifyController();
|
||||||
break;
|
break;
|
||||||
case enuOmniLinkCommStatus.Connecting:
|
|
||||||
log.Info("CONNECTION STATUS: Connecting");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.Disconnected:
|
case enuOmniLinkCommStatus.Disconnected:
|
||||||
log.Info("CONNECTION STATUS: Disconnected");
|
log.Information("Controller Status: {connectionStatus}", status);
|
||||||
OnDisconnect?.Invoke(this, new EventArgs());
|
OnDisconnect?.Invoke(this, new EventArgs());
|
||||||
break;
|
break;
|
||||||
case enuOmniLinkCommStatus.InterruptedFunctionCall:
|
case enuOmniLinkCommStatus.InterruptedFunctionCall:
|
||||||
if (Global.running)
|
if (running)
|
||||||
log.Error("CONNECTION STATUS: Interrupted Function Call");
|
log.Error("Controller Status: {connectionStatus}", status);
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.PermissionDenied:
|
|
||||||
log.Error("CONNECTION STATUS: Permission Denied");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.BadAddress:
|
|
||||||
log.Error("CONNECTION STATUS: Bad Address");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.InvalidArgument:
|
|
||||||
log.Error("CONNECTION STATUS: Invalid Argument");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.TooManyOpenFiles:
|
|
||||||
log.Error("CONNECTION STATUS: Too Many Open Files");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ResourceTemporarilyUnavailable:
|
|
||||||
log.Error("CONNECTION STATUS: Resource Temporarily Unavailable");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case enuOmniLinkCommStatus.Retrying:
|
||||||
case enuOmniLinkCommStatus.OperationNowInProgress:
|
case enuOmniLinkCommStatus.OperationNowInProgress:
|
||||||
log.Warn("CONNECTION STATUS: Operation Now In Progress");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.OperationAlreadyInProgress:
|
case enuOmniLinkCommStatus.OperationAlreadyInProgress:
|
||||||
log.Warn("CONNECTION STATUS: Operation Already In Progress");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.SocketOperationOnNonSocket:
|
|
||||||
log.Error("CONNECTION STATUS: Socket Operation On Non Socket");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.DestinationAddressRequired:
|
|
||||||
log.Error("CONNECTION STATUS: Destination Address Required");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.MessgeTooLong:
|
|
||||||
log.Error("CONNECTION STATUS: Message Too Long");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.WrongProtocolType:
|
|
||||||
log.Error("CONNECTION STATUS: Wrong Protocol Type");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.BadProtocolOption:
|
|
||||||
log.Error("CONNECTION STATUS: Bad Protocol Option");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ProtocolNotSupported:
|
|
||||||
log.Error("CONNECTION STATUS: Protocol Not Supported");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.SocketTypeNotSupported:
|
|
||||||
log.Error("CONNECTION STATUS: Socket Type Not Supported");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.OperationNotSupported:
|
|
||||||
log.Error("CONNECTION STATUS: Operation Not Supported");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ProtocolFamilyNotSupported:
|
|
||||||
log.Error("CONNECTION STATUS: Protocol Family Not Supported");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.AddressFamilyNotSupported:
|
|
||||||
log.Error("CONNECTION STATUS: Address Family Not Supported");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.AddressInUse:
|
|
||||||
log.Error("CONNECTION STATUS: Address In Use");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.AddressNotAvailable:
|
|
||||||
log.Error("CONNECTION STATUS: Address Not Available");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NetworkIsDown:
|
|
||||||
log.Error("CONNECTION STATUS: Network Is Down");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NetworkIsUnreachable:
|
|
||||||
log.Error("CONNECTION STATUS: Network Is Unreachable");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NetworkReset:
|
|
||||||
log.Error("CONNECTION STATUS: Network Reset");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ConnectionAborted:
|
|
||||||
log.Error("CONNECTION STATUS: Connection Aborted");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ConnectionResetByPeer:
|
|
||||||
log.Error("CONNECTION STATUS: Connection Reset By Peer");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NoBufferSpaceAvailable:
|
|
||||||
log.Error("CONNECTION STATUS: No Buffer Space Available");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.AlreadyConnected:
|
case enuOmniLinkCommStatus.AlreadyConnected:
|
||||||
log.Warn("CONNECTION STATUS: Already Connected");
|
log.Warning("Controller Status: {connectionStatus}", status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case enuOmniLinkCommStatus.NoReply:
|
||||||
|
case enuOmniLinkCommStatus.UnrecognizedReply:
|
||||||
|
case enuOmniLinkCommStatus.UnsupportedProtocol:
|
||||||
|
case enuOmniLinkCommStatus.ClientSessionTerminated:
|
||||||
|
case enuOmniLinkCommStatus.ControllerSessionTerminated:
|
||||||
|
case enuOmniLinkCommStatus.CannotStartNewSession:
|
||||||
|
case enuOmniLinkCommStatus.LoginFailed:
|
||||||
|
case enuOmniLinkCommStatus.UnableToOpenSocket:
|
||||||
|
case enuOmniLinkCommStatus.UnableToConnect:
|
||||||
|
case enuOmniLinkCommStatus.SocketClosed:
|
||||||
|
case enuOmniLinkCommStatus.UnexpectedError:
|
||||||
|
case enuOmniLinkCommStatus.UnableToCreateSocket:
|
||||||
|
case enuOmniLinkCommStatus.PermissionDenied:
|
||||||
|
case enuOmniLinkCommStatus.BadAddress:
|
||||||
|
case enuOmniLinkCommStatus.InvalidArgument:
|
||||||
|
case enuOmniLinkCommStatus.TooManyOpenFiles:
|
||||||
|
case enuOmniLinkCommStatus.ResourceTemporarilyUnavailable:
|
||||||
|
case enuOmniLinkCommStatus.SocketOperationOnNonSocket:
|
||||||
|
case enuOmniLinkCommStatus.DestinationAddressRequired:
|
||||||
|
case enuOmniLinkCommStatus.MessgeTooLong:
|
||||||
|
case enuOmniLinkCommStatus.WrongProtocolType:
|
||||||
|
case enuOmniLinkCommStatus.BadProtocolOption:
|
||||||
|
case enuOmniLinkCommStatus.ProtocolNotSupported:
|
||||||
|
case enuOmniLinkCommStatus.SocketTypeNotSupported:
|
||||||
|
case enuOmniLinkCommStatus.OperationNotSupported:
|
||||||
|
case enuOmniLinkCommStatus.ProtocolFamilyNotSupported:
|
||||||
|
case enuOmniLinkCommStatus.AddressFamilyNotSupported:
|
||||||
|
case enuOmniLinkCommStatus.AddressInUse:
|
||||||
|
case enuOmniLinkCommStatus.AddressNotAvailable:
|
||||||
|
case enuOmniLinkCommStatus.NetworkIsDown:
|
||||||
|
case enuOmniLinkCommStatus.NetworkIsUnreachable:
|
||||||
|
case enuOmniLinkCommStatus.NetworkReset:
|
||||||
|
case enuOmniLinkCommStatus.ConnectionAborted:
|
||||||
|
case enuOmniLinkCommStatus.ConnectionResetByPeer:
|
||||||
|
case enuOmniLinkCommStatus.NoBufferSpaceAvailable:
|
||||||
case enuOmniLinkCommStatus.NotConnected:
|
case enuOmniLinkCommStatus.NotConnected:
|
||||||
log.Error("CONNECTION STATUS: Not Connected");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.CannotSendAfterShutdown:
|
case enuOmniLinkCommStatus.CannotSendAfterShutdown:
|
||||||
log.Error("CONNECTION STATUS: Cannot Send After Shutdown");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ConnectionTimedOut:
|
case enuOmniLinkCommStatus.ConnectionTimedOut:
|
||||||
log.Error("CONNECTION STATUS: Connection Timed Out");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ConnectionRefused:
|
case enuOmniLinkCommStatus.ConnectionRefused:
|
||||||
log.Error("CONNECTION STATUS: Connection Refused");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.HostIsDown:
|
case enuOmniLinkCommStatus.HostIsDown:
|
||||||
log.Error("CONNECTION STATUS: Host Is Down");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.HostUnreachable:
|
case enuOmniLinkCommStatus.HostUnreachable:
|
||||||
log.Error("CONNECTION STATUS: Host Unreachable");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.TooManyProcesses:
|
case enuOmniLinkCommStatus.TooManyProcesses:
|
||||||
log.Error("CONNECTION STATUS: Too Many Processes");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NetworkSubsystemIsUnavailable:
|
case enuOmniLinkCommStatus.NetworkSubsystemIsUnavailable:
|
||||||
log.Error("CONNECTION STATUS: Network Subsystem Is Unavailable");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.UnsupportedVersion:
|
case enuOmniLinkCommStatus.UnsupportedVersion:
|
||||||
log.Error("CONNECTION STATUS: Unsupported Version");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NotInitialized:
|
case enuOmniLinkCommStatus.NotInitialized:
|
||||||
log.Error("CONNECTION STATUS: Not Initialized");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ShutdownInProgress:
|
case enuOmniLinkCommStatus.ShutdownInProgress:
|
||||||
log.Error("CONNECTION STATUS: Shutdown In Progress");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.ClassTypeNotFound:
|
case enuOmniLinkCommStatus.ClassTypeNotFound:
|
||||||
log.Error("CONNECTION STATUS: Class Type Not Found");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.HostNotFound:
|
case enuOmniLinkCommStatus.HostNotFound:
|
||||||
log.Error("CONNECTION STATUS: Host Not Found");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.HostNotFoundTryAgain:
|
case enuOmniLinkCommStatus.HostNotFoundTryAgain:
|
||||||
log.Error("CONNECTION STATUS: Host Not Found Try Again");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NonRecoverableError:
|
case enuOmniLinkCommStatus.NonRecoverableError:
|
||||||
log.Error("CONNECTION STATUS: Non Recoverable Error");
|
|
||||||
break;
|
|
||||||
case enuOmniLinkCommStatus.NoDataOfRequestedType:
|
case enuOmniLinkCommStatus.NoDataOfRequestedType:
|
||||||
log.Error("CONNECTION STATUS: No Data Of Requested Type");
|
log.Error("Controller Status: {connectionStatus}", status);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -316,7 +219,10 @@ namespace OmniLinkBridge.Modules
|
||||||
if (Controller.Model == MSG.ModelNumber)
|
if (Controller.Model == MSG.ModelNumber)
|
||||||
{
|
{
|
||||||
Controller.CopySystemInformation(MSG);
|
Controller.CopySystemInformation(MSG);
|
||||||
log.Info("CONTROLLER IS: " + Controller.GetModelText() + " (" + Controller.GetVersionText() + ")");
|
|
||||||
|
using (LogContext.PushProperty("Telemetry", "Controller"))
|
||||||
|
log.Information("Controller is {ControllerModel} firmware {ControllerVersion}",
|
||||||
|
Controller.GetModelText(), Controller.GetVersionText());
|
||||||
|
|
||||||
_ = Connected();
|
_ = Connected();
|
||||||
|
|
||||||
|
@ -371,7 +277,7 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
private async Task GetNamed(enuObjectType type)
|
private async Task GetNamed(enuObjectType type)
|
||||||
{
|
{
|
||||||
log.Debug("Waiting for named units " + type.ToString());
|
log.Debug("Waiting for named units {unitType}", type.ToString());
|
||||||
|
|
||||||
GetNextNamed(type, 0);
|
GetNextNamed(type, 0);
|
||||||
|
|
||||||
|
@ -415,7 +321,9 @@ namespace OmniLinkBridge.Modules
|
||||||
Controller.TimeFormat = MSG2.Time;
|
Controller.TimeFormat = MSG2.Time;
|
||||||
Controller.TempFormat = MSG2.Temp;
|
Controller.TempFormat = MSG2.Temp;
|
||||||
|
|
||||||
log.Debug("Temperature format: " + (Controller.TempFormat == enuTempFormat.Fahrenheit ? "Fahrenheit" : "Celsius"));
|
using (LogContext.PushProperty("Telemetry", "TemperatureFormat"))
|
||||||
|
log.Debug("Temperature format is {TemperatureFormat}",
|
||||||
|
(Controller.TempFormat == enuTempFormat.Fahrenheit ? "Fahrenheit" : "Celsius"));
|
||||||
|
|
||||||
nameWait.Set();
|
nameWait.Set();
|
||||||
break;
|
break;
|
||||||
|
@ -443,7 +351,8 @@ namespace OmniLinkBridge.Modules
|
||||||
tstats[MSG.ObjectNumber] = DateTime.MinValue;
|
tstats[MSG.ObjectNumber] = DateTime.MinValue;
|
||||||
|
|
||||||
Controller.Connection.Send(new clsOL2MsgRequestExtendedStatus(Controller.Connection, enuObjectType.Thermostat, MSG.ObjectNumber, MSG.ObjectNumber), HandleRequestThermostatStatus);
|
Controller.Connection.Send(new clsOL2MsgRequestExtendedStatus(Controller.Connection, enuObjectType.Thermostat, MSG.ObjectNumber, MSG.ObjectNumber), HandleRequestThermostatStatus);
|
||||||
log.Debug("Added thermostat to watch list " + Controller.Thermostats[MSG.ObjectNumber].Name);
|
log.Debug("Added thermostat to watch list {thermostatName}",
|
||||||
|
Controller.Thermostats[MSG.ObjectNumber].Name);
|
||||||
break;
|
break;
|
||||||
case enuObjectType.Unit:
|
case enuObjectType.Unit:
|
||||||
Controller.Units.CopyProperties(MSG);
|
Controller.Units.CopyProperties(MSG);
|
||||||
|
@ -471,7 +380,7 @@ namespace OmniLinkBridge.Modules
|
||||||
#region Notifications
|
#region Notifications
|
||||||
private void UnsolicitedNotifications(bool enable)
|
private void UnsolicitedNotifications(bool enable)
|
||||||
{
|
{
|
||||||
log.Info("Unsolicited notifications " + (enable ? "enabled" : "disabled"));
|
log.Debug("Unsolicited notifications {status}", (enable ? "enabled" : "disabled"));
|
||||||
Controller.Connection.Send(new clsOL2EnableNotifications(Controller.Connection, enable), null);
|
Controller.Connection.Send(new clsOL2EnableNotifications(Controller.Connection, enable), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +585,7 @@ namespace OmniLinkBridge.Modules
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < MSG.MessageLength; i++)
|
for (int i = 0; i < MSG.MessageLength; i++)
|
||||||
sb.Append(MSG.Data[i].ToString() + " ");
|
sb.Append(MSG.Data[i].ToString() + " ");
|
||||||
log.Debug("Unhandled SystemEvent Raw: " + sb.ToString() + "Num: " + MSG.SystemEvent);
|
log.Debug("Unhandled SystemEvent Raw: {raw}, Num: {num}", sb.ToString(), MSG.SystemEvent);
|
||||||
|
|
||||||
int num = ((int)MSG.MessageLength - 1) / 2;
|
int num = ((int)MSG.MessageLength - 1) / 2;
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
|
@ -745,7 +654,8 @@ namespace OmniLinkBridge.Modules
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (Global.verbose_thermostat_timer)
|
else if (Global.verbose_thermostat_timer)
|
||||||
log.Warn("Ignoring unsolicited unknown temp for Thermostat " + Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
log.Debug("Ignoring unsolicited unknown temp for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
||||||
|
|
||||||
if (!tstats.ContainsKey(MSG.ObjectNumber(i)))
|
if (!tstats.ContainsKey(MSG.ObjectNumber(i)))
|
||||||
tstats.Add(MSG.ObjectNumber(i), DateTime.Now);
|
tstats.Add(MSG.ObjectNumber(i), DateTime.Now);
|
||||||
|
@ -753,7 +663,8 @@ namespace OmniLinkBridge.Modules
|
||||||
tstats[MSG.ObjectNumber(i)] = DateTime.Now;
|
tstats[MSG.ObjectNumber(i)] = DateTime.Now;
|
||||||
|
|
||||||
if (Global.verbose_thermostat_timer)
|
if (Global.verbose_thermostat_timer)
|
||||||
log.Debug("Unsolicited status received for Thermostat " + Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
log.Debug("Unsolicited status received for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -817,7 +728,8 @@ namespace OmniLinkBridge.Modules
|
||||||
Controller.Connection.Send(new clsOL2MsgRequestExtendedStatus(Controller.Connection, enuObjectType.Thermostat, tstat.Key, tstat.Key), HandleRequestThermostatStatus);
|
Controller.Connection.Send(new clsOL2MsgRequestExtendedStatus(Controller.Connection, enuObjectType.Thermostat, tstat.Key, tstat.Key), HandleRequestThermostatStatus);
|
||||||
|
|
||||||
if (Global.verbose_thermostat_timer)
|
if (Global.verbose_thermostat_timer)
|
||||||
log.Debug("Polling status for Thermostat " + Controller.Thermostats[tstat.Key].Name);
|
log.Debug("Polling status for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[tstat.Key].Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log every minute if update within 5 minutes and connected
|
// Log every minute if update within 5 minutes and connected
|
||||||
|
@ -836,10 +748,12 @@ namespace OmniLinkBridge.Modules
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (Global.verbose_thermostat_timer)
|
else if (Global.verbose_thermostat_timer)
|
||||||
log.Warn("Ignoring unknown temp for Thermostat " + Controller.Thermostats[tstat.Key].Name);
|
log.Warning("Ignoring unknown temp for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[tstat.Key].Name);
|
||||||
}
|
}
|
||||||
else if (Global.verbose_thermostat_timer)
|
else if (Global.verbose_thermostat_timer)
|
||||||
log.Warn("Not logging out of date status for Thermostat " + Controller.Thermostats[tstat.Key].Name);
|
log.Warning("Not logging out of date status for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[tstat.Key].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +780,8 @@ namespace OmniLinkBridge.Modules
|
||||||
tstats[MSG.ObjectNumber(i)] = DateTime.Now;
|
tstats[MSG.ObjectNumber(i)] = DateTime.Now;
|
||||||
|
|
||||||
if (Global.verbose_thermostat_timer)
|
if (Global.verbose_thermostat_timer)
|
||||||
log.Debug("Polling status received for Thermostat " + Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
log.Debug("Polling status received for Thermostat {thermostatName}",
|
||||||
|
Controller.Thermostats[MSG.ObjectNumber(i)].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using HAI_Shared;
|
using HAI_Shared;
|
||||||
using log4net;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Modules
|
||||||
{
|
{
|
||||||
public class TimeSyncModule : IModule
|
public class TimeSyncModule : IModule
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private OmniLinkII OmniLink { get; set; }
|
private OmniLinkII OmniLink { get; set; }
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ namespace OmniLinkBridge.Modules
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Warn("Controller time could not be parsed");
|
log.Warning("Controller time could not be parsed");
|
||||||
|
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
OmniLink.Controller.Connection.Send(new clsOL2MsgSetTime(OmniLink.Controller.Connection, (byte)(now.Year % 100), (byte)now.Month, (byte)now.Day, (byte)now.DayOfWeek,
|
OmniLink.Controller.Connection.Send(new clsOL2MsgSetTime(OmniLink.Controller.Connection, (byte)(now.Year % 100), (byte)now.Month, (byte)now.Day, (byte)now.DayOfWeek,
|
||||||
|
@ -91,7 +91,8 @@ namespace OmniLinkBridge.Modules
|
||||||
|
|
||||||
if (adj > Global.time_drift)
|
if (adj > Global.time_drift)
|
||||||
{
|
{
|
||||||
log.Warn("Controller time " + time.ToString("MM/dd/yyyy HH:mm:ss") + " out of sync by " + adj + " seconds");
|
log.Warning("Controller time {controllerTime} out of sync by {driftSeconds} seconds",
|
||||||
|
time.ToString("MM/dd/yyyy HH:mm:ss"), adj);
|
||||||
|
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
OmniLink.Controller.Connection.Send(new clsOL2MsgSetTime(OmniLink.Controller.Connection, (byte)(now.Year % 100), (byte)now.Month, (byte)now.Day, (byte)now.DayOfWeek,
|
OmniLink.Controller.Connection.Send(new clsOL2MsgSetTime(OmniLink.Controller.Connection, (byte)(now.Year % 100), (byte)now.Month, (byte)now.Day, (byte)now.DayOfWeek,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
using log4net;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using OmniLinkBridge.Modules;
|
using OmniLinkBridge.Modules;
|
||||||
using OmniLinkBridge.OmniLink;
|
using OmniLinkBridge.OmniLink;
|
||||||
using OmniLinkBridge.WebAPI;
|
using OmniLinkBridge.WebAPI;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
|
@ -14,7 +14,7 @@ namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
public class WebServiceModule : IModule
|
public class WebServiceModule : IModule
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public static OmniLinkII OmniLink { get; private set; }
|
public static OmniLinkII OmniLink { get; private set; }
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ namespace OmniLinkBridge
|
||||||
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IOmniLinkService), new WebHttpBinding(), "");
|
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IOmniLinkService), new WebHttpBinding(), "");
|
||||||
host.Open();
|
host.Open();
|
||||||
|
|
||||||
log.Info("Listening on " + uri.ToString());
|
log.Information("Listening on {url}", uri.ToString());
|
||||||
}
|
}
|
||||||
catch (CommunicationException ex)
|
catch (CommunicationException ex)
|
||||||
{
|
{
|
||||||
log.Error("An exception occurred starting web service", ex);
|
log.Error(ex, "An exception occurred starting web service");
|
||||||
host.Abort();
|
host.Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using log4net;
|
using OmniLinkBridge.Modules;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
|
@ -8,7 +9,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
{
|
{
|
||||||
public class EmailNotification : INotification
|
public class EmailNotification : INotification
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public void Notify(string source, string description, NotificationPriority priority)
|
public void Notify(string source, string description, NotificationPriority priority)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +41,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("An error occurred sending email notification", ex);
|
log.Error(ex, "An error occurred sending email notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using log4net;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
{
|
{
|
||||||
public static class Notification
|
public static class Notification
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static readonly List<INotification> providers = new List<INotification>()
|
private static readonly List<INotification> providers = new List<INotification>()
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("Failed to send notification", ex);
|
log.Error(ex, "Failed to send notification");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using log4net;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
{
|
{
|
||||||
public class ProwlNotification : INotification
|
public class ProwlNotification : INotification
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static readonly Uri URI = new Uri("https://api.prowlapp.com/publicapi/add");
|
private static readonly Uri URI = new Uri("https://api.prowlapp.com/publicapi/add");
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Error != null)
|
if (e.Error != null)
|
||||||
log.Error("An error occurred sending prowl notification", e.Error);
|
log.Error(e.Error, "An error occurred sending prowl notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using log4net;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
{
|
{
|
||||||
public class PushoverNotification : INotification
|
public class PushoverNotification : INotification
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static readonly Uri URI = new Uri("https://api.pushover.net/1/messages.json");
|
private static readonly Uri URI = new Uri("https://api.pushover.net/1/messages.json");
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace OmniLinkBridge.Notifications
|
||||||
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Error != null)
|
if (e.Error != null)
|
||||||
log.Error("An error occurred sending pushover notification", e.Error);
|
log.Error(e.Error, "An error occurred sending pushover notification");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,9 +161,6 @@
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="log4net">
|
|
||||||
<Version>2.0.8</Version>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Mono.Posix-4.5">
|
<PackageReference Include="Mono.Posix-4.5">
|
||||||
<Version>4.5.0</Version>
|
<Version>4.5.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
@ -173,6 +170,24 @@
|
||||||
<PackageReference Include="Newtonsoft.Json">
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
<Version>12.0.3</Version>
|
<Version>12.0.3</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog">
|
||||||
|
<Version>2.9.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog.Formatting.Compact">
|
||||||
|
<Version>1.1.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog.Sinks.Async">
|
||||||
|
<Version>1.4.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog.Sinks.Console">
|
||||||
|
<Version>3.1.1</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog.Sinks.File">
|
||||||
|
<Version>4.1.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Serilog.Sinks.Http">
|
||||||
|
<Version>5.2.0</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
|
7
OmniLinkBridge/OmniLinkBridge.csproj.user
Normal file
7
OmniLinkBridge/OmniLinkBridge.csproj.user
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||||
|
<StartArguments>
|
||||||
|
</StartArguments>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -1,7 +1,11 @@
|
||||||
using Mono.Unix;
|
using Mono.Unix;
|
||||||
|
using Serilog;
|
||||||
|
using Serilog.Events;
|
||||||
|
using Serilog.Filters;
|
||||||
|
using Serilog.Formatting.Compact;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -12,10 +16,15 @@ namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
static CoreServer server;
|
static CoreServer server;
|
||||||
|
|
||||||
static void Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
bool interactive = false;
|
bool interactive = false;
|
||||||
|
|
||||||
|
string config_file = "OmniLinkBridge.ini";
|
||||||
|
string log_file = "log.txt";
|
||||||
|
bool log_clef = false;
|
||||||
|
LogEventLevel log_level = LogEventLevel.Information;
|
||||||
|
|
||||||
for (int i = 0; i < args.Length; i++)
|
for (int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
switch (args[i])
|
switch (args[i])
|
||||||
|
@ -24,15 +33,27 @@ namespace OmniLinkBridge
|
||||||
case "-h":
|
case "-h":
|
||||||
case "-help":
|
case "-help":
|
||||||
ShowHelp();
|
ShowHelp();
|
||||||
return;
|
return 0;
|
||||||
case "-c":
|
case "-c":
|
||||||
Global.config_file = args[++i];
|
config_file = args[++i];
|
||||||
break;
|
break;
|
||||||
case "-e":
|
case "-e":
|
||||||
Settings.UseEnvironment = true;
|
Global.UseEnvironment = true;
|
||||||
break;
|
break;
|
||||||
case "-d":
|
case "-d":
|
||||||
Settings.ShowDebug = true;
|
Global.DebugSettings = true;
|
||||||
|
break;
|
||||||
|
case "-lf":
|
||||||
|
log_file = args[++i];
|
||||||
|
|
||||||
|
if (string.Compare(log_file, "disable", true) == 0)
|
||||||
|
log_file = null;
|
||||||
|
break;
|
||||||
|
case "-lj":
|
||||||
|
log_clef = true;
|
||||||
|
break;
|
||||||
|
case "-ll":
|
||||||
|
Enum.TryParse(args[++i], out log_level);
|
||||||
break;
|
break;
|
||||||
case "-s":
|
case "-s":
|
||||||
Global.webapi_subscriptions_file = args[++i];
|
Global.webapi_subscriptions_file = args[++i];
|
||||||
|
@ -43,27 +64,53 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Global.config_file))
|
config_file = GetFullPath(config_file);
|
||||||
Global.config_file = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
|
|
||||||
Path.DirectorySeparatorChar + "OmniLinkBridge.ini";
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Global.webapi_subscriptions_file))
|
Global.webapi_subscriptions_file = GetFullPath(Global.webapi_subscriptions_file ?? "WebSubscriptions.json");
|
||||||
Global.webapi_subscriptions_file = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
|
|
||||||
Path.DirectorySeparatorChar + "WebSubscriptions.json";
|
|
||||||
|
|
||||||
log4net.Config.XmlConfigurator.Configure();
|
// Use TLS 1.2 as default connection
|
||||||
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||||
|
|
||||||
if(Environment.UserInteractive || interactive)
|
string log_format = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{SourceContext} {Level:u3}] {Message:lj}{NewLine}{Exception}";
|
||||||
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
|
|
||||||
|
var log_config = new LoggerConfiguration()
|
||||||
|
.MinimumLevel.Verbose()
|
||||||
|
.Enrich.WithProperty("Application", "OmniLinkBridge")
|
||||||
|
.Enrich.WithProperty("Session", Guid.NewGuid())
|
||||||
|
.Enrich.WithProperty("User", (Environment.UserName + Environment.MachineName).GetHashCode())
|
||||||
|
.Enrich.FromLogContext();
|
||||||
|
|
||||||
|
if (log_file != null)
|
||||||
|
{
|
||||||
|
log_file = GetFullPath(log_file);
|
||||||
|
|
||||||
|
if (log_clef)
|
||||||
|
log_config = log_config.WriteTo.Async(a => a.File(new CompactJsonFormatter(), log_file, log_level,
|
||||||
|
rollingInterval: RollingInterval.Day, retainedFileCountLimit: 15));
|
||||||
|
else
|
||||||
|
log_config = log_config.WriteTo.Async(a => a.File(log_file, log_level, log_format,
|
||||||
|
rollingInterval: RollingInterval.Day, retainedFileCountLimit: 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UseTelemetry())
|
||||||
|
log_config = log_config.WriteTo.Logger(lc => lc
|
||||||
|
.Filter.ByIncludingOnly(Matching.WithProperty("Telemetry"))
|
||||||
|
.WriteTo.Http("https://telemetry.excalibur-partners.com"));
|
||||||
|
|
||||||
|
if (Environment.UserInteractive || interactive)
|
||||||
|
log_config = log_config.WriteTo.Console(outputTemplate: log_format);
|
||||||
|
|
||||||
|
Log.Logger = log_config.CreateLogger();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Settings.LoadSettings(Global.config_file);
|
Settings.LoadSettings(config_file);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// Errors are logged in LoadSettings();
|
// Errors are logged in LoadSettings();
|
||||||
Environment.Exit(1);
|
Log.CloseAndFlush();
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Environment.UserInteractive || interactive)
|
if (Environment.UserInteractive || interactive)
|
||||||
|
@ -104,6 +151,16 @@ namespace OmniLinkBridge
|
||||||
|
|
||||||
ServiceBase.Run(ServicesToRun);
|
ServiceBase.Run(ServicesToRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string GetFullPath(string file)
|
||||||
|
{
|
||||||
|
if (Path.IsPathRooted(file))
|
||||||
|
return file;
|
||||||
|
|
||||||
|
return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
|
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
|
||||||
|
@ -117,16 +174,28 @@ namespace OmniLinkBridge
|
||||||
return Type.GetType("Mono.Runtime") != null;
|
return Type.GetType("Mono.Runtime") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool UseTelemetry()
|
||||||
|
{
|
||||||
|
return string.Compare(Environment.GetEnvironmentVariable("TELEMETRY_OPTOUT"), "1") != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void ShowHelp()
|
static void ShowHelp()
|
||||||
{
|
{
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-s subscriptions_file] [-i]\n" +
|
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-j] [-s subscriptions_file]\n" +
|
||||||
"\t[-debug-config] [-ignore-env]\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-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" +
|
||||||
"\t-e Check environment variables for configuration settings\n" +
|
"\t-e Check environment variables for configuration settings\n" +
|
||||||
"\t-d Show debug output for configuration loading\n" +
|
"\t-d Show debug ouput for configuration loading\n" +
|
||||||
"\t-s Specifies the web api subscriptions file. Default is WebSubscriptions.json\n" +
|
"\t-s Specifies the web api subscriptions file. Default is WebSubscriptions.json\n" +
|
||||||
"\t-i Run in interactive mode");
|
"\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-i Run in interactive mode");
|
||||||
|
|
||||||
|
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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OmniLinkBridge")]
|
[assembly: AssemblyTitle("OmniLink Bridge")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
||||||
[assembly: AssemblyProduct("OmniLinkBridge")]
|
[assembly: AssemblyProduct("OmniLinkBridge")]
|
||||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2019")]
|
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2020")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using log4net;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,14 +7,13 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Mail;
|
using System.Net.Mail;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace OmniLinkBridge
|
namespace OmniLinkBridge
|
||||||
{
|
{
|
||||||
public static class Settings
|
public static class Settings
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
public static bool ShowDebug { get; set; }
|
|
||||||
public static bool UseEnvironment { get; set; }
|
|
||||||
|
|
||||||
public static void LoadSettings(string file)
|
public static void LoadSettings(string file)
|
||||||
{
|
{
|
||||||
|
@ -115,10 +114,10 @@ namespace OmniLinkBridge
|
||||||
|
|
||||||
private static string CheckEnv(this NameValueCollection settings, string name)
|
private static string CheckEnv(this NameValueCollection settings, string name)
|
||||||
{
|
{
|
||||||
string env = UseEnvironment ? Environment.GetEnvironmentVariable(name.ToUpper()) : null;
|
string env = Global.UseEnvironment ? Environment.GetEnvironmentVariable(name.ToUpper()) : null;
|
||||||
string value = !string.IsNullOrEmpty(env) ? env : settings[name];
|
string value = !string.IsNullOrEmpty(env) ? env : settings[name];
|
||||||
|
|
||||||
if (ShowDebug)
|
if (Global.DebugSettings)
|
||||||
log.Debug((!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(5) + $"{name}: {value}");
|
log.Debug((!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(5) + $"{name}: {value}");
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@ -170,7 +169,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("Invalid override zone specified for " + section, ex);
|
log.Error(ex, "Invalid override zone specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +180,7 @@ namespace OmniLinkBridge
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(value))
|
if(string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
log.Error("Empty string specified for " + section);
|
log.Error("Empty string specified for {section}", section);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +195,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid integer specified for " + section);
|
log.Error("Invalid integer specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +213,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid range specified for " + section);
|
log.Error("Invalid range specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +231,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid port specified for " + section);
|
log.Error("Invalid port specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +244,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid email specified for " + section);
|
log.Error("Invalid email specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +268,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid email specified for " + section);
|
log.Error("Invalid email specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,7 +284,7 @@ namespace OmniLinkBridge
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
log.Error("Invalid string specified for " + section);
|
log.Error("Invalid string specified for {section}", section);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +301,7 @@ namespace OmniLinkBridge
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log.Error("Invalid yes/no or true/false specified for " + section);
|
log.Error("Invalid yes/no or true/false specified for {section}", section);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,24 +329,24 @@ namespace OmniLinkBridge
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NameValueCollection LoadCollection(string sFile)
|
private static NameValueCollection LoadCollection(string file)
|
||||||
{
|
{
|
||||||
if (ShowDebug)
|
if (Global.DebugSettings)
|
||||||
log.Debug($"Using settings file {sFile}");
|
log.Debug("Using settings file {file}", file);
|
||||||
|
|
||||||
if(!File.Exists(sFile))
|
if(!File.Exists(file))
|
||||||
{
|
{
|
||||||
log.Warn($"Unable to locate settings file {sFile}");
|
log.Warning("Unable to locate settings file {file}", file);
|
||||||
return new NameValueCollection();
|
return new NameValueCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return LoadCollection(File.ReadAllLines(sFile));
|
return LoadCollection(File.ReadAllLines(file));
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException ex)
|
catch (FileNotFoundException ex)
|
||||||
{
|
{
|
||||||
log.Error("Error parsing settings file " + sFile, ex);
|
log.Error(ex, "Error parsing settings file {file}", file);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using HAI_Shared;
|
using HAI_Shared;
|
||||||
using log4net;
|
|
||||||
using OmniLinkBridge.WebAPI;
|
using OmniLinkBridge.WebAPI;
|
||||||
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -12,7 +12,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
|
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
|
||||||
public class OmniLinkService : IOmniLinkService
|
public class OmniLinkService : IOmniLinkService
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public void Subscribe(SubscribeContract contract)
|
public void Subscribe(SubscribeContract contract)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public AreaContract GetArea(ushort id)
|
public AreaContract GetArea(ushort id)
|
||||||
{
|
{
|
||||||
log.Debug("GetArea: " + id);
|
log.Debug("GetArea: {id}", id);
|
||||||
|
|
||||||
WebOperationContext ctx = WebOperationContext.Current;
|
WebOperationContext ctx = WebOperationContext.Current;
|
||||||
ctx.OutgoingResponse.Headers.Add("type", "area");
|
ctx.OutgoingResponse.Headers.Add("type", "area");
|
||||||
|
@ -139,7 +139,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public ZoneContract GetZone(ushort id)
|
public ZoneContract GetZone(ushort id)
|
||||||
{
|
{
|
||||||
log.Debug("GetZone: " + id);
|
log.Debug("GetZone: {id}", id);
|
||||||
|
|
||||||
WebOperationContext ctx = WebOperationContext.Current;
|
WebOperationContext ctx = WebOperationContext.Current;
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public UnitContract GetUnit(ushort id)
|
public UnitContract GetUnit(ushort id)
|
||||||
{
|
{
|
||||||
log.Debug("GetUnit: " + id);
|
log.Debug("GetUnit: {id}", id);
|
||||||
|
|
||||||
WebOperationContext ctx = WebOperationContext.Current;
|
WebOperationContext ctx = WebOperationContext.Current;
|
||||||
ctx.OutgoingResponse.Headers.Add("type", "unit");
|
ctx.OutgoingResponse.Headers.Add("type", "unit");
|
||||||
|
@ -183,7 +183,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public void SetUnit(CommandContract unit)
|
public void SetUnit(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("SetUnit: " + unit.id + " to " + unit.value + "%");
|
log.Debug("SetUnit: {id} to {value}%", unit.id, unit.value);
|
||||||
|
|
||||||
if (unit.value == 0)
|
if (unit.value == 0)
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Off, 0, unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Off, 0, unit.id);
|
||||||
|
@ -196,7 +196,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public void SetUnitKeypadPress(CommandContract unit)
|
public void SetUnitKeypadPress(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("SetUnitKeypadPress: " + unit.id + " to " + unit.value + " button");
|
log.Debug("SetUnitKeypadPress: {id} to {value}", unit.id, unit.value);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.LutronHomeWorksKeypadButtonPress, BitConverter.GetBytes(unit.value)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.LutronHomeWorksKeypadButtonPress, BitConverter.GetBytes(unit.value)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public ThermostatContract GetThermostat(ushort id)
|
public ThermostatContract GetThermostat(ushort id)
|
||||||
{
|
{
|
||||||
log.Debug("GetThermostat: " + id);
|
log.Debug("GetThermostat: {id}", id);
|
||||||
|
|
||||||
WebOperationContext ctx = WebOperationContext.Current;
|
WebOperationContext ctx = WebOperationContext.Current;
|
||||||
ctx.OutgoingResponse.Headers.Add("type", "thermostat");
|
ctx.OutgoingResponse.Headers.Add("type", "thermostat");
|
||||||
|
@ -236,7 +236,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = tempHigh.ToOmniTemp();
|
int temp = tempHigh.ToOmniTemp();
|
||||||
log.Debug("SetThermostatCoolSetpoint: " + unit.id + " to " + unit.value + tempUnit + "(" + temp + ")");
|
log.Debug("SetThermostatCoolSetpoint: {id} to {value}{tempUnit} {temp}", unit.id, unit.value, tempUnit, temp);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.SetHighSetPt, BitConverter.GetBytes(temp)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.SetHighSetPt, BitConverter.GetBytes(temp)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,25 +251,25 @@ namespace OmniLinkBridge.WebAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
int temp = tempLoad.ToOmniTemp();
|
int temp = tempLoad.ToOmniTemp();
|
||||||
log.Debug("SetThermostatHeatSetpoint: " + unit.id + " to " + unit.value + tempUnit + "(" + temp + ")");
|
log.Debug("SetThermostatHeatSetpoint: {id} to {value}{tempUnit} {temp}", unit.id, unit.value, tempUnit, temp);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.SetLowSetPt, BitConverter.GetBytes(temp)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.SetLowSetPt, BitConverter.GetBytes(temp)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetThermostatMode(CommandContract unit)
|
public void SetThermostatMode(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatMode: " + unit.id + " to " + unit.value);
|
log.Debug("SetThermostatMode: {id} to {value}", unit.id, unit.value);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Mode, BitConverter.GetBytes(unit.value)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Mode, BitConverter.GetBytes(unit.value)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetThermostatFanMode(CommandContract unit)
|
public void SetThermostatFanMode(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatFanMode: " + unit.id + " to " + unit.value);
|
log.Debug("SetThermostatFanMode: {id} to {value}", unit.id, unit.value);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes(unit.value)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Fan, BitConverter.GetBytes(unit.value)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetThermostatHold(CommandContract unit)
|
public void SetThermostatHold(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("SetThermostatHold: " + unit.id + " to " + unit.value);
|
log.Debug("SetThermostatHold: {id} to {value}", unit.id, unit.value);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes(unit.value)[0], unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Hold, BitConverter.GetBytes(unit.value)[0], unit.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
|
|
||||||
public void PushButton(CommandContract unit)
|
public void PushButton(CommandContract unit)
|
||||||
{
|
{
|
||||||
log.Debug("PushButton: " + unit.id);
|
log.Debug("PushButton: {id}", unit.id);
|
||||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Button, 0, unit.id);
|
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Button, 0, unit.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using log4net;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -10,7 +10,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
{
|
{
|
||||||
static class WebNotification
|
static class WebNotification
|
||||||
{
|
{
|
||||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static List<string> subscriptions = new List<string>();
|
private static List<string> subscriptions = new List<string>();
|
||||||
private static readonly object subscriptions_lock = new object();
|
private static readonly object subscriptions_lock = new object();
|
||||||
|
@ -52,7 +52,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("An error occurred sending notification to " + subscription, ex);
|
log.Error(ex, "An error occurred sending notification to {client}", subscription);
|
||||||
subscriptions.Remove(subscription);
|
subscriptions.Remove(subscription);
|
||||||
SaveSubscriptions();
|
SaveSubscriptions();
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
{
|
{
|
||||||
if (e.Error != null)
|
if (e.Error != null)
|
||||||
{
|
{
|
||||||
log.Error("An error occurred sending notification to " + e.UserState.ToString(), e.Error);
|
log.Error(e.Error, "An error occurred sending notification to {client}", e.UserState.ToString());
|
||||||
|
|
||||||
lock (subscriptions_lock)
|
lock (subscriptions_lock)
|
||||||
subscriptions.Remove(e.UserState.ToString());
|
subscriptions.Remove(e.UserState.ToString());
|
||||||
|
@ -88,7 +88,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("An error occurred restoring subscriptions", ex);
|
log.Error(ex, "An error occurred restoring subscriptions");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ namespace OmniLinkBridge.WebAPI
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Error("An error occurred saving subscriptions", ex);
|
log.Error(ex, "An error occurred saving subscriptions");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
[assembly: AssemblyTitle("OmniLinkBridgeTest")]
|
[assembly: AssemblyTitle("OmniLink Bridge Test")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
||||||
[assembly: AssemblyProduct("OmniLinkBridgeTest")]
|
[assembly: AssemblyProduct("OmniLinkBridgeTest")]
|
||||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2019")]
|
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2020")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ You can use docker to build an image from git or download the [binary here](http
|
||||||
- .NET Framework 4.5.2 (or Mono equivalent)
|
- .NET Framework 4.5.2 (or Mono equivalent)
|
||||||
|
|
||||||
## Operation
|
## Operation
|
||||||
OmniLinkBridge is divided into the following modules and configurable settings. Configuration settings can also be set as environment variables by using their name in uppercase. Refer to [OmniLinkBridge.ini](https://github.com/excaliburpartners/OmniLinkBridge/blob/master/OmniLinkBridge/OmniLinkBridge.ini) for specifics.
|
OmniLink Bridge is divided into the following modules and configurable settings. Configuration settings can also be set as environment variables by using their name in uppercase. Refer to [OmniLinkBridge.ini](https://github.com/excaliburpartners/OmniLinkBridge/blob/master/OmniLinkBridge/OmniLinkBridge.ini) for specifics.
|
||||||
|
|
||||||
- OmniLinkII: controller_
|
- OmniLinkII: controller_
|
||||||
- Maintains connection to the OmniLink controller
|
- Maintains connection to the OmniLink controller
|
||||||
|
@ -330,3 +330,6 @@ Configure mysql_connection in OmniLinkBridge.ini. For Windows change DRIVER={MyS
|
||||||
```
|
```
|
||||||
mysql_connection = DRIVER={MySQL};SERVER=localhost;DATABASE=OmniLinkBridge;USER=root;PASSWORD=myPassword;OPTION=3;
|
mysql_connection = DRIVER={MySQL};SERVER=localhost;DATABASE=OmniLinkBridge;USER=root;PASSWORD=myPassword;OPTION=3;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Telemetry
|
||||||
|
OmniLink Bridge collects anonymous telemetry data to help improve the software. You can opt of telemetry by setting a TELEMETRY_OPTOUT environment variable to 1.
|
Loading…
Reference in a new issue