mirror of
https://github.com/excaliburpartners/OmniLinkBridge
synced 2024-12-22 10:42: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
|
||||
WORKDIR /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"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||
</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>
|
||||
|
|
|
@ -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.Reflection;
|
||||
using System.Threading;
|
||||
|
@ -9,11 +11,13 @@ namespace OmniLinkBridge
|
|||
{
|
||||
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 readonly List<IModule> modules = new List<IModule>();
|
||||
private readonly List<Task> tasks = new List<Task>();
|
||||
private readonly ManualResetEvent quitEvent = new ManualResetEvent(false);
|
||||
private DateTime startTime;
|
||||
|
||||
public CoreServer()
|
||||
{
|
||||
|
@ -23,11 +27,6 @@ namespace OmniLinkBridge
|
|||
|
||||
private void Server()
|
||||
{
|
||||
Global.running = true;
|
||||
|
||||
log.Debug("Starting up server " +
|
||||
Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
|
||||
// Controller connection
|
||||
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)
|
||||
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
|
||||
foreach (IModule module in modules)
|
||||
{
|
||||
|
@ -52,14 +57,11 @@ namespace OmniLinkBridge
|
|||
}));
|
||||
}
|
||||
|
||||
// Wait for all threads to stop
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
quitEvent.WaitOne();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
Global.running = false;
|
||||
|
||||
// Shutdown modules
|
||||
foreach (IModule module in modules)
|
||||
module.Shutdown();
|
||||
|
@ -68,7 +70,12 @@ namespace OmniLinkBridge
|
|||
if (tasks != null)
|
||||
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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace OmniLinkBridge
|
||||
{
|
||||
|
@ -23,6 +24,11 @@ namespace OmniLinkBridge
|
|||
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)
|
||||
{
|
||||
string[] groups = ranges.Split(',');
|
||||
|
|
|
@ -7,10 +7,8 @@ namespace OmniLinkBridge
|
|||
{
|
||||
public abstract class Global
|
||||
{
|
||||
public static bool running;
|
||||
|
||||
// Config File
|
||||
public static string config_file;
|
||||
public static bool DebugSettings { get; set; }
|
||||
public static bool UseEnvironment { get; set; }
|
||||
|
||||
// HAI / Leviton Omni Controller
|
||||
public static string controller_address;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using HAI_Shared;
|
||||
using log4net;
|
||||
using OmniLinkBridge.OmniLink;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
@ -10,7 +10,7 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
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);
|
||||
|
||||
|
@ -33,7 +33,8 @@ namespace OmniLinkBridge.MQTT
|
|||
|| !ushort.TryParse(match.Groups[2].Value, out ushort id))
|
||||
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)
|
||||
ProcessAreaReceived(OmniLink.Controller.Areas[id], topic, payload);
|
||||
|
@ -68,7 +69,7 @@ namespace OmniLinkBridge.MQTT
|
|||
if (area.Number == 0)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -100,13 +101,13 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -129,7 +130,8 @@ namespace OmniLinkBridge.MQTT
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
else if (command == Topic.temperature_cool_command && double.TryParse(payload, out double tempHigh))
|
||||
|
@ -142,35 +144,36 @@ namespace OmniLinkBridge.MQTT
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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
|
||||
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);
|
||||
}
|
||||
else if (command == Topic.dehumidify_command && double.TryParse(payload, out double dehumidify))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +182,7 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +199,7 @@ namespace OmniLinkBridge.MQTT
|
|||
{
|
||||
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;
|
||||
if (cmd == MessageCommands.show_no_beep)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using log4net;
|
||||
using OmniLinkBridge.Notifications;
|
||||
using OmniLinkBridge.Notifications;
|
||||
using OmniLinkBridge.OmniLink;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
@ -12,7 +12,9 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
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 List<string> alarms = new List<string>();
|
||||
|
@ -41,26 +43,22 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
if (Global.mysql_logging)
|
||||
{
|
||||
log.Info("Connecting to database");
|
||||
log.Information("Connecting to database");
|
||||
|
||||
mysql_conn = new OdbcConnection(Global.mysql_connection);
|
||||
|
||||
// Must make an initial connection
|
||||
if (!DBOpen())
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// Make sure database connection is active
|
||||
if (Global.mysql_logging && mysql_conn.State != ConnectionState.Open)
|
||||
{
|
||||
// Nothing we can do if shutting down
|
||||
if (!Global.running)
|
||||
if (!running)
|
||||
break;
|
||||
|
||||
if (mysql_retry < DateTime.Now)
|
||||
|
@ -100,11 +98,11 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
if (mysql_conn.State != ConnectionState.Open)
|
||||
{
|
||||
log.Warn("Lost connection to database");
|
||||
log.Warning("Lost connection to database");
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Error("Error executing query\r\n" + query, ex);
|
||||
log.Error(ex, "Error executing {query}", query);
|
||||
|
||||
// Prevent an endless loop from failed query
|
||||
lock (mysql_lock)
|
||||
|
@ -119,6 +117,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
public void Shutdown()
|
||||
{
|
||||
running = false;
|
||||
trigger.Set();
|
||||
}
|
||||
|
||||
|
@ -198,7 +197,7 @@ namespace OmniLinkBridge.Modules
|
|||
e.Area.AreaDuressAlarmText + "','" + status + "')");
|
||||
|
||||
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)
|
||||
Notification.Notify("Security", e.Area.Name + " " + e.Area.ModeText());
|
||||
|
@ -213,9 +212,9 @@ namespace OmniLinkBridge.Modules
|
|||
if (Global.verbose_zone)
|
||||
{
|
||||
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
|
||||
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
|
||||
if (!e.EventTimer && Global.verbose_thermostat)
|
||||
log.Debug("ThermostatStatus " + e.ID + " " + e.Thermostat.Name +
|
||||
", Status: " + e.Thermostat.TempText() + " " + e.Thermostat.HorC_StatusText() +
|
||||
", Heat: " + e.Thermostat.HeatSetpointText() +
|
||||
", Cool: " + e.Thermostat.CoolSetpointText() +
|
||||
", Mode: " + e.Thermostat.ModeText() +
|
||||
", Fan: " + e.Thermostat.FanModeText() +
|
||||
", Hold: " + e.Thermostat.HoldStatusText());
|
||||
log.Verbose("ThermostatStatus {id} {name}, Status: {temp} {status}, " +
|
||||
"Heat {heat}, Cool: {cool}, Mode: {mode}, Fan: {fan}, Hold: {hold}",
|
||||
e.ID, e.Thermostat.Name,
|
||||
e.Thermostat.TempText(), e.Thermostat.HorC_StatusText(),
|
||||
e.Thermostat.HeatSetpointText(),
|
||||
e.Thermostat.CoolSetpointText(),
|
||||
e.Thermostat.ModeText(),
|
||||
e.Thermostat.FanModeText(),
|
||||
e.Thermostat.HoldStatusText());
|
||||
}
|
||||
|
||||
private void Omnilink_OnUnitStatus(object sender, UnitStatusEventArgs e)
|
||||
|
@ -266,7 +267,7 @@ namespace OmniLinkBridge.Modules
|
|||
status + "','" + e.Unit.Status + "','" + e.Unit.StatusTime + "')");
|
||||
|
||||
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)
|
||||
|
@ -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() + "')");
|
||||
|
||||
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)
|
||||
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 + "')");
|
||||
|
||||
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)
|
||||
Notification.Notify("SystemEvent", e.Type.ToString() + " " + e.Value);
|
||||
|
@ -306,7 +307,7 @@ namespace OmniLinkBridge.Modules
|
|||
}
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using HAI_Shared;
|
||||
using log4net;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Connecting;
|
||||
|
@ -11,6 +10,7 @@ using MQTTnet.Protocol;
|
|||
using Newtonsoft.Json;
|
||||
using OmniLinkBridge.MQTT;
|
||||
using OmniLinkBridge.OmniLink;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
@ -22,7 +22,7 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
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; }
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace OmniLinkBridge.Modules
|
|||
if (ControllerConnected)
|
||||
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.StartAsync(manoptions);
|
||||
|
@ -118,8 +118,7 @@ namespace OmniLinkBridge.Modules
|
|||
// Wait until shutdown
|
||||
trigger.WaitOne();
|
||||
|
||||
log.Debug("Publishing controller offline");
|
||||
PublishAsync($"{Global.mqtt_prefix}/status", "offline");
|
||||
PublishControllerStatus("offline");
|
||||
|
||||
MqttClient.StopAsync();
|
||||
}
|
||||
|
@ -142,10 +141,13 @@ namespace OmniLinkBridge.Modules
|
|||
ControllerConnected = false;
|
||||
|
||||
if (MqttClient.IsConnected)
|
||||
{
|
||||
log.Debug("Publishing controller offline");
|
||||
PublishAsync($"{Global.mqtt_prefix}/status", "offline");
|
||||
}
|
||||
PublishControllerStatus("offline");
|
||||
}
|
||||
|
||||
private void PublishControllerStatus(string status)
|
||||
{
|
||||
log.Information("Publishing controller {status}", status);
|
||||
PublishAsync($"{Global.mqtt_prefix}/status", status);
|
||||
}
|
||||
|
||||
private void PublishConfig()
|
||||
|
@ -157,15 +159,14 @@ namespace OmniLinkBridge.Modules
|
|||
PublishButtons();
|
||||
PublishMessages();
|
||||
|
||||
log.Debug("Publishing controller online");
|
||||
PublishAsync($"{Global.mqtt_prefix}/status", "online");
|
||||
PublishControllerStatus("online");
|
||||
PublishAsync($"{Global.mqtt_prefix}/model", OmniLink.Controller.GetModelText());
|
||||
PublishAsync($"{Global.mqtt_prefix}/version", OmniLink.Controller.GetVersionText());
|
||||
}
|
||||
|
||||
private void PublishAreas()
|
||||
{
|
||||
log.Debug("Publishing areas");
|
||||
log.Debug("Publishing {type}", "areas");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Areas.Count; i++)
|
||||
{
|
||||
|
@ -214,7 +215,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void PublishZones()
|
||||
{
|
||||
log.Debug("Publishing zones");
|
||||
log.Debug("Publishing {type}", "zones");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Zones.Count; i++)
|
||||
{
|
||||
|
@ -255,7 +256,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void PublishUnits()
|
||||
{
|
||||
log.Debug("Publishing units");
|
||||
log.Debug("Publishing {type}", "units");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Units.Count; i++)
|
||||
{
|
||||
|
@ -289,7 +290,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void PublishThermostats()
|
||||
{
|
||||
log.Debug("Publishing thermostats");
|
||||
log.Debug("Publishing {type}", "thermostats");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Thermostats.Count; i++)
|
||||
{
|
||||
|
@ -318,7 +319,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void PublishButtons()
|
||||
{
|
||||
log.Debug("Publishing buttons");
|
||||
log.Debug("Publishing {type}", "buttons");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Buttons.Count; i++)
|
||||
{
|
||||
|
@ -342,7 +343,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void PublishMessages()
|
||||
{
|
||||
log.Debug("Publishing messages");
|
||||
log.Debug("Publishing {type}", "messages");
|
||||
|
||||
for (ushort i = 1; i <= OmniLink.Controller.Messages.Count; i++)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using HAI_Shared;
|
||||
using OmniLinkBridge.OmniLink;
|
||||
using log4net;
|
||||
using Serilog;
|
||||
using Serilog.Context;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
@ -12,7 +13,9 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
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
|
||||
public clsHAC Controller { get; private set; }
|
||||
|
@ -54,7 +57,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
public void Startup()
|
||||
{
|
||||
while (Global.running)
|
||||
while(running)
|
||||
{
|
||||
// Make sure controller connection is active
|
||||
if (Controller.Connection.ConnectionState == enuOmniLinkConnectionState.Offline &&
|
||||
|
@ -71,6 +74,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
public void Shutdown()
|
||||
{
|
||||
running = false;
|
||||
trigger.Set();
|
||||
}
|
||||
|
||||
|
@ -92,7 +96,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void Disconnect()
|
||||
{
|
||||
log.Info("CONNECTION STATUS: Disconnecting");
|
||||
log.Debug("Controller Status: {connectionStatus}", "Disconnecting");
|
||||
|
||||
if (Controller.Connection.ConnectionState != enuOmniLinkConnectionState.Offline)
|
||||
Controller.Connection.Disconnect();
|
||||
|
@ -100,187 +104,86 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
private void HandleConnectStatus(enuOmniLinkCommStatus CS)
|
||||
{
|
||||
var status = CS.ToString().ToSpaceTitleCase();
|
||||
|
||||
switch (CS)
|
||||
{
|
||||
case enuOmniLinkCommStatus.NoReply:
|
||||
log.Error("CONNECTION STATUS: No Reply");
|
||||
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");
|
||||
case enuOmniLinkCommStatus.Connecting:
|
||||
log.Debug("Controller Status: {connectionStatus}", status);
|
||||
break;
|
||||
case enuOmniLinkCommStatus.Connected:
|
||||
IdentifyController();
|
||||
break;
|
||||
case enuOmniLinkCommStatus.Connecting:
|
||||
log.Info("CONNECTION STATUS: Connecting");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.Disconnected:
|
||||
log.Info("CONNECTION STATUS: Disconnected");
|
||||
log.Information("Controller Status: {connectionStatus}", status);
|
||||
OnDisconnect?.Invoke(this, new EventArgs());
|
||||
break;
|
||||
case enuOmniLinkCommStatus.InterruptedFunctionCall:
|
||||
if (Global.running)
|
||||
log.Error("CONNECTION STATUS: Interrupted Function Call");
|
||||
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");
|
||||
if (running)
|
||||
log.Error("Controller Status: {connectionStatus}", status);
|
||||
break;
|
||||
|
||||
case enuOmniLinkCommStatus.Retrying:
|
||||
case enuOmniLinkCommStatus.OperationNowInProgress:
|
||||
log.Warn("CONNECTION STATUS: Operation Now In Progress");
|
||||
break;
|
||||
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:
|
||||
log.Warn("CONNECTION STATUS: Already Connected");
|
||||
log.Warning("Controller Status: {connectionStatus}", status);
|
||||
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:
|
||||
log.Error("CONNECTION STATUS: Not Connected");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.CannotSendAfterShutdown:
|
||||
log.Error("CONNECTION STATUS: Cannot Send After Shutdown");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.ConnectionTimedOut:
|
||||
log.Error("CONNECTION STATUS: Connection Timed Out");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.ConnectionRefused:
|
||||
log.Error("CONNECTION STATUS: Connection Refused");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.HostIsDown:
|
||||
log.Error("CONNECTION STATUS: Host Is Down");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.HostUnreachable:
|
||||
log.Error("CONNECTION STATUS: Host Unreachable");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.TooManyProcesses:
|
||||
log.Error("CONNECTION STATUS: Too Many Processes");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.NetworkSubsystemIsUnavailable:
|
||||
log.Error("CONNECTION STATUS: Network Subsystem Is Unavailable");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.UnsupportedVersion:
|
||||
log.Error("CONNECTION STATUS: Unsupported Version");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.NotInitialized:
|
||||
log.Error("CONNECTION STATUS: Not Initialized");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.ShutdownInProgress:
|
||||
log.Error("CONNECTION STATUS: Shutdown In Progress");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.ClassTypeNotFound:
|
||||
log.Error("CONNECTION STATUS: Class Type Not Found");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.HostNotFound:
|
||||
log.Error("CONNECTION STATUS: Host Not Found");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.HostNotFoundTryAgain:
|
||||
log.Error("CONNECTION STATUS: Host Not Found Try Again");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.NonRecoverableError:
|
||||
log.Error("CONNECTION STATUS: Non Recoverable Error");
|
||||
break;
|
||||
case enuOmniLinkCommStatus.NoDataOfRequestedType:
|
||||
log.Error("CONNECTION STATUS: No Data Of Requested Type");
|
||||
log.Error("Controller Status: {connectionStatus}", status);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -316,7 +219,10 @@ namespace OmniLinkBridge.Modules
|
|||
if (Controller.Model == MSG.ModelNumber)
|
||||
{
|
||||
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();
|
||||
|
||||
|
@ -371,7 +277,7 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
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);
|
||||
|
||||
|
@ -415,7 +321,9 @@ namespace OmniLinkBridge.Modules
|
|||
Controller.TimeFormat = MSG2.Time;
|
||||
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();
|
||||
break;
|
||||
|
@ -443,7 +351,8 @@ namespace OmniLinkBridge.Modules
|
|||
tstats[MSG.ObjectNumber] = DateTime.MinValue;
|
||||
|
||||
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;
|
||||
case enuObjectType.Unit:
|
||||
Controller.Units.CopyProperties(MSG);
|
||||
|
@ -471,7 +380,7 @@ namespace OmniLinkBridge.Modules
|
|||
#region Notifications
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -676,7 +585,7 @@ namespace OmniLinkBridge.Modules
|
|||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < MSG.MessageLength; i++)
|
||||
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;
|
||||
for (int i = 0; i < num; i++)
|
||||
|
@ -745,7 +654,8 @@ namespace OmniLinkBridge.Modules
|
|||
});
|
||||
}
|
||||
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)))
|
||||
tstats.Add(MSG.ObjectNumber(i), DateTime.Now);
|
||||
|
@ -753,7 +663,8 @@ namespace OmniLinkBridge.Modules
|
|||
tstats[MSG.ObjectNumber(i)] = DateTime.Now;
|
||||
|
||||
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;
|
||||
|
@ -817,7 +728,8 @@ namespace OmniLinkBridge.Modules
|
|||
Controller.Connection.Send(new clsOL2MsgRequestExtendedStatus(Controller.Connection, enuObjectType.Thermostat, tstat.Key, tstat.Key), HandleRequestThermostatStatus);
|
||||
|
||||
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
|
||||
|
@ -836,10 +748,12 @@ namespace OmniLinkBridge.Modules
|
|||
});
|
||||
}
|
||||
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)
|
||||
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;
|
||||
|
||||
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 log4net;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Modules
|
|||
{
|
||||
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; }
|
||||
|
||||
|
@ -78,7 +78,7 @@ namespace OmniLinkBridge.Modules
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Warn("Controller time could not be parsed");
|
||||
log.Warning("Controller time could not be parsed");
|
||||
|
||||
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,
|
||||
|
@ -91,7 +91,8 @@ namespace OmniLinkBridge.Modules
|
|||
|
||||
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;
|
||||
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.OmniLink;
|
||||
using OmniLinkBridge.WebAPI;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.ServiceModel;
|
||||
|
@ -14,7 +14,7 @@ namespace OmniLinkBridge
|
|||
{
|
||||
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; }
|
||||
|
||||
|
@ -43,11 +43,11 @@ namespace OmniLinkBridge
|
|||
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IOmniLinkService), new WebHttpBinding(), "");
|
||||
host.Open();
|
||||
|
||||
log.Info("Listening on " + uri.ToString());
|
||||
log.Information("Listening on {url}", uri.ToString());
|
||||
}
|
||||
catch (CommunicationException ex)
|
||||
{
|
||||
log.Error("An exception occurred starting web service", ex);
|
||||
log.Error(ex, "An exception occurred starting web service");
|
||||
host.Abort();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using log4net;
|
||||
using OmniLinkBridge.Modules;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
|
@ -8,7 +9,7 @@ namespace OmniLinkBridge.Notifications
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -40,7 +41,7 @@ namespace OmniLinkBridge.Notifications
|
|||
}
|
||||
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.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
|||
{
|
||||
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>()
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ namespace OmniLinkBridge.Notifications
|
|||
}
|
||||
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.Collections.Generic;
|
||||
using System.Net;
|
||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
|||
{
|
||||
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");
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace OmniLinkBridge.Notifications
|
|||
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
||||
{
|
||||
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.Collections.Specialized;
|
||||
using System.Net;
|
||||
|
@ -8,7 +8,7 @@ namespace OmniLinkBridge.Notifications
|
|||
{
|
||||
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");
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace OmniLinkBridge.Notifications
|
|||
private void Client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
|
||||
{
|
||||
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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4net">
|
||||
<Version>2.0.8</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Mono.Posix-4.5">
|
||||
<Version>4.5.0</Version>
|
||||
</PackageReference>
|
||||
|
@ -173,6 +170,24 @@
|
|||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>12.0.3</Version>
|
||||
</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>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 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 Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Filters;
|
||||
using Serilog.Formatting.Compact;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -12,10 +16,15 @@ namespace OmniLinkBridge
|
|||
{
|
||||
static CoreServer server;
|
||||
|
||||
static void Main(string[] args)
|
||||
static int Main(string[] args)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
switch (args[i])
|
||||
|
@ -24,15 +33,27 @@ namespace OmniLinkBridge
|
|||
case "-h":
|
||||
case "-help":
|
||||
ShowHelp();
|
||||
return;
|
||||
return 0;
|
||||
case "-c":
|
||||
Global.config_file = args[++i];
|
||||
config_file = args[++i];
|
||||
break;
|
||||
case "-e":
|
||||
Settings.UseEnvironment = true;
|
||||
Global.UseEnvironment = true;
|
||||
break;
|
||||
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;
|
||||
case "-s":
|
||||
Global.webapi_subscriptions_file = args[++i];
|
||||
|
@ -43,27 +64,53 @@ namespace OmniLinkBridge
|
|||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Global.config_file))
|
||||
Global.config_file = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
|
||||
Path.DirectorySeparatorChar + "OmniLinkBridge.ini";
|
||||
config_file = GetFullPath(config_file);
|
||||
|
||||
if (string.IsNullOrEmpty(Global.webapi_subscriptions_file))
|
||||
Global.webapi_subscriptions_file = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) +
|
||||
Path.DirectorySeparatorChar + "WebSubscriptions.json";
|
||||
Global.webapi_subscriptions_file = GetFullPath(Global.webapi_subscriptions_file ?? "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)
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
|
||||
string log_format = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{SourceContext} {Level:u3}] {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
var log_config = new LoggerConfiguration()
|
||||
.MinimumLevel.Verbose()
|
||||
.Enrich.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
|
||||
{
|
||||
Settings.LoadSettings(Global.config_file);
|
||||
Settings.LoadSettings(config_file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Errors are logged in LoadSettings();
|
||||
Environment.Exit(1);
|
||||
Log.CloseAndFlush();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Environment.UserInteractive || interactive)
|
||||
|
@ -104,6 +151,16 @@ namespace OmniLinkBridge
|
|||
|
||||
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)
|
||||
|
@ -117,16 +174,28 @@ namespace OmniLinkBridge
|
|||
return Type.GetType("Mono.Runtime") != null;
|
||||
}
|
||||
|
||||
static bool UseTelemetry()
|
||||
{
|
||||
return string.Compare(Environment.GetEnvironmentVariable("TELEMETRY_OPTOUT"), "1") != 0;
|
||||
}
|
||||
|
||||
static void ShowHelp()
|
||||
{
|
||||
Console.WriteLine(
|
||||
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-s subscriptions_file] [-i]\n" +
|
||||
"\t[-debug-config] [-ignore-env]\n" +
|
||||
"\t-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" +
|
||||
"\t-e Check environment variables for configuration settings\n" +
|
||||
"\t-d Show debug output for configuration loading\n" +
|
||||
"\t-s Specifies the web api subscriptions file. Default is WebSubscriptions.json\n" +
|
||||
"\t-i Run in interactive mode");
|
||||
AppDomain.CurrentDomain.FriendlyName + " [-c config_file] [-e] [-d] [-j] [-s subscriptions_file]\n" +
|
||||
"\t[-lf log_file|disable] [-lj [-ll verbose|debug|information|warning|error] [-i]\n" +
|
||||
"\t-c Specifies the configuration file. Default is OmniLinkBridge.ini\n" +
|
||||
"\t-e Check environment variables for configuration settings\n" +
|
||||
"\t-d Show debug ouput for configuration loading\n" +
|
||||
"\t-s Specifies the web api subscriptions file. Default is WebSubscriptions.json\n" +
|
||||
"\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
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OmniLinkBridge")]
|
||||
[assembly: AssemblyTitle("OmniLink Bridge")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
||||
[assembly: AssemblyProduct("OmniLinkBridge")]
|
||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2019")]
|
||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using log4net;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
@ -7,14 +7,13 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
namespace OmniLinkBridge
|
||||
{
|
||||
public static class Settings
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
public static bool ShowDebug { get; set; }
|
||||
public static bool UseEnvironment { get; set; }
|
||||
private static readonly ILogger log = Log.Logger.ForContext(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static void LoadSettings(string file)
|
||||
{
|
||||
|
@ -115,10 +114,10 @@ namespace OmniLinkBridge
|
|||
|
||||
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];
|
||||
|
||||
if (ShowDebug)
|
||||
if (Global.DebugSettings)
|
||||
log.Debug((!string.IsNullOrEmpty(env) ? "ENV" : "CONF").PadRight(5) + $"{name}: {value}");
|
||||
|
||||
return value;
|
||||
|
@ -170,7 +169,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error("Invalid override zone specified for " + section, ex);
|
||||
log.Error(ex, "Invalid override zone specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +180,7 @@ namespace OmniLinkBridge
|
|||
|
||||
if(string.IsNullOrEmpty(value))
|
||||
{
|
||||
log.Error("Empty string specified for " + section);
|
||||
log.Error("Empty string specified for {section}", section);
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
|
@ -196,7 +195,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid integer specified for " + section);
|
||||
log.Error("Invalid integer specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +213,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid range specified for " + section);
|
||||
log.Error("Invalid range specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +231,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid port specified for " + section);
|
||||
log.Error("Invalid port specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +244,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid email specified for " + section);
|
||||
log.Error("Invalid email specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +268,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid email specified for " + section);
|
||||
log.Error("Invalid email specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +284,7 @@ namespace OmniLinkBridge
|
|||
}
|
||||
catch
|
||||
{
|
||||
log.Error("Invalid string specified for " + section);
|
||||
log.Error("Invalid string specified for {section}", section);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ namespace OmniLinkBridge
|
|||
return false;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -330,24 +329,24 @@ namespace OmniLinkBridge
|
|||
return settings;
|
||||
}
|
||||
|
||||
private static NameValueCollection LoadCollection(string sFile)
|
||||
private static NameValueCollection LoadCollection(string file)
|
||||
{
|
||||
if (ShowDebug)
|
||||
log.Debug($"Using settings file {sFile}");
|
||||
if (Global.DebugSettings)
|
||||
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();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return LoadCollection(File.ReadAllLines(sFile));
|
||||
return LoadCollection(File.ReadAllLines(file));
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
log.Error("Error parsing settings file " + sFile, ex);
|
||||
log.Error(ex, "Error parsing settings file {file}", file);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using HAI_Shared;
|
||||
using log4net;
|
||||
using OmniLinkBridge.WebAPI;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
@ -12,7 +12,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
|
||||
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)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
public AreaContract GetArea(ushort id)
|
||||
{
|
||||
log.Debug("GetArea: " + id);
|
||||
log.Debug("GetArea: {id}", id);
|
||||
|
||||
WebOperationContext ctx = WebOperationContext.Current;
|
||||
ctx.OutgoingResponse.Headers.Add("type", "area");
|
||||
|
@ -139,7 +139,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
public ZoneContract GetZone(ushort id)
|
||||
{
|
||||
log.Debug("GetZone: " + id);
|
||||
log.Debug("GetZone: {id}", id);
|
||||
|
||||
WebOperationContext ctx = WebOperationContext.Current;
|
||||
|
||||
|
@ -173,7 +173,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
public UnitContract GetUnit(ushort id)
|
||||
{
|
||||
log.Debug("GetUnit: " + id);
|
||||
log.Debug("GetUnit: {id}", id);
|
||||
|
||||
WebOperationContext ctx = WebOperationContext.Current;
|
||||
ctx.OutgoingResponse.Headers.Add("type", "unit");
|
||||
|
@ -183,7 +183,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
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)
|
||||
WebServiceModule.OmniLink.Controller.SendCommand(enuUnitCommand.Off, 0, unit.id);
|
||||
|
@ -196,7 +196,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
public ThermostatContract GetThermostat(ushort id)
|
||||
{
|
||||
log.Debug("GetThermostat: " + id);
|
||||
log.Debug("GetThermostat: {id}", id);
|
||||
|
||||
WebOperationContext ctx = WebOperationContext.Current;
|
||||
ctx.OutgoingResponse.Headers.Add("type", "thermostat");
|
||||
|
@ -236,7 +236,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -251,25 +251,25 @@ namespace OmniLinkBridge.WebAPI
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
@ -10,7 +10,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
{
|
||||
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 readonly object subscriptions_lock = new object();
|
||||
|
@ -52,7 +52,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
}
|
||||
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);
|
||||
SaveSubscriptions();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
{
|
||||
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)
|
||||
subscriptions.Remove(e.UserState.ToString());
|
||||
|
@ -88,7 +88,7 @@ namespace OmniLinkBridge.WebAPI
|
|||
}
|
||||
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)
|
||||
{
|
||||
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.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("OmniLinkBridgeTest")]
|
||||
[assembly: AssemblyTitle("OmniLink Bridge Test")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Excalibur Partners, LLC")]
|
||||
[assembly: AssemblyProduct("OmniLinkBridgeTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2019")]
|
||||
[assembly: AssemblyCopyright("Copyright © Excalibur Partners, LLC 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[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)
|
||||
|
||||
## 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_
|
||||
- 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;
|
||||
```
|
||||
|
||||
## 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