diff --git a/Dockerfile b/Dockerfile index 36101a8..7e2561d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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" ] \ No newline at end of file +CMD [ "mono", "OmniLinkBridge.exe", "-i", "-c", "/config/OmniLinkBridge.ini", "-e", "-s", "/config/WebSubscriptions.json", "-lf", "disable" ] \ No newline at end of file diff --git a/OmniLinkBridge/App.config b/OmniLinkBridge/App.config index f531d78..a826409 100644 --- a/OmniLinkBridge/App.config +++ b/OmniLinkBridge/App.config @@ -1,37 +1,6 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OmniLinkBridge/CoreServer.cs b/OmniLinkBridge/CoreServer.cs index b380bfe..3d52b94 100644 --- a/OmniLinkBridge/CoreServer.cs +++ b/OmniLinkBridge/CoreServer.cs @@ -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 modules = new List(); private readonly List tasks = new List(); + 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(); } } } \ No newline at end of file diff --git a/OmniLinkBridge/Extensions.cs b/OmniLinkBridge/Extensions.cs index 41bc9a0..681834f 100644 --- a/OmniLinkBridge/Extensions.cs +++ b/OmniLinkBridge/Extensions.cs @@ -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 ParseRanges(this string ranges) { string[] groups = ranges.Split(','); diff --git a/OmniLinkBridge/Global.cs b/OmniLinkBridge/Global.cs index 677154e..a6c7312 100644 --- a/OmniLinkBridge/Global.cs +++ b/OmniLinkBridge/Global.cs @@ -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; diff --git a/OmniLinkBridge/MQTT/MessageProcessor.cs b/OmniLinkBridge/MQTT/MessageProcessor.cs index ae3b086..a08aafa 100644 --- a/OmniLinkBridge/MQTT/MessageProcessor.cs +++ b/OmniLinkBridge/MQTT/MessageProcessor.cs @@ -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) diff --git a/OmniLinkBridge/Modules/LoggerModule.cs b/OmniLinkBridge/Modules/LoggerModule.cs index e672266..740ff11 100644 --- a/OmniLinkBridge/Modules/LoggerModule.cs +++ b/OmniLinkBridge/Modules/LoggerModule.cs @@ -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 alarms = new List(); @@ -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; } diff --git a/OmniLinkBridge/Modules/MQTTModule.cs b/OmniLinkBridge/Modules/MQTTModule.cs index 258cdab..39a3c49 100644 --- a/OmniLinkBridge/Modules/MQTTModule.cs +++ b/OmniLinkBridge/Modules/MQTTModule.cs @@ -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++) { diff --git a/OmniLinkBridge/Modules/OmniLinkII.cs b/OmniLinkBridge/Modules/OmniLinkII.cs index 5361e2a..07125e0 100644 --- a/OmniLinkBridge/Modules/OmniLinkII.cs +++ b/OmniLinkBridge/Modules/OmniLinkII.cs @@ -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,8 +57,8 @@ namespace OmniLinkBridge.Modules public void Startup() { - while (Global.running) - { + while(running) + { // Make sure controller connection is active if (Controller.Connection.ConnectionState == enuOmniLinkConnectionState.Offline && retry < DateTime.Now) @@ -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); } } } diff --git a/OmniLinkBridge/Modules/TimeSyncModule.cs b/OmniLinkBridge/Modules/TimeSyncModule.cs index 92488f3..05c4e46 100644 --- a/OmniLinkBridge/Modules/TimeSyncModule.cs +++ b/OmniLinkBridge/Modules/TimeSyncModule.cs @@ -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, diff --git a/OmniLinkBridge/Modules/WebServiceModule.cs b/OmniLinkBridge/Modules/WebServiceModule.cs index 392a4e2..91040f2 100644 --- a/OmniLinkBridge/Modules/WebServiceModule.cs +++ b/OmniLinkBridge/Modules/WebServiceModule.cs @@ -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(); } diff --git a/OmniLinkBridge/Notifications/EmailNotification.cs b/OmniLinkBridge/Notifications/EmailNotification.cs index 1e59940..2ab7f70 100644 --- a/OmniLinkBridge/Notifications/EmailNotification.cs +++ b/OmniLinkBridge/Notifications/EmailNotification.cs @@ -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"); } } } diff --git a/OmniLinkBridge/Notifications/Notification.cs b/OmniLinkBridge/Notifications/Notification.cs index 22beb6f..74f365a 100644 --- a/OmniLinkBridge/Notifications/Notification.cs +++ b/OmniLinkBridge/Notifications/Notification.cs @@ -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 providers = new List() { @@ -27,7 +27,7 @@ namespace OmniLinkBridge.Notifications } catch (Exception ex) { - log.Error("Failed to send notification", ex); + log.Error(ex, "Failed to send notification"); } }); } diff --git a/OmniLinkBridge/Notifications/ProwlNotification.cs b/OmniLinkBridge/Notifications/ProwlNotification.cs index bd631b9..df7dc1d 100644 --- a/OmniLinkBridge/Notifications/ProwlNotification.cs +++ b/OmniLinkBridge/Notifications/ProwlNotification.cs @@ -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"); } } } diff --git a/OmniLinkBridge/Notifications/PushoverNotification.cs b/OmniLinkBridge/Notifications/PushoverNotification.cs index f54f5d1..20c7fc3 100644 --- a/OmniLinkBridge/Notifications/PushoverNotification.cs +++ b/OmniLinkBridge/Notifications/PushoverNotification.cs @@ -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"); } } } diff --git a/OmniLinkBridge/OmniLinkBridge.csproj b/OmniLinkBridge/OmniLinkBridge.csproj index a96f30b..14761de 100644 --- a/OmniLinkBridge/OmniLinkBridge.csproj +++ b/OmniLinkBridge/OmniLinkBridge.csproj @@ -161,9 +161,6 @@ - - 2.0.8 - 4.5.0 @@ -173,6 +170,24 @@ 12.0.3 + + 2.9.0 + + + 1.1.0 + + + 1.4.0 + + + 3.1.1 + + + 4.1.0 + + + 5.2.0 +