From ab08a546f710c20b374404c3cc07bae150c5b641 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Sep 2025 15:25:23 -0600 Subject: [PATCH 01/13] feat: Add HideInUi property to room combiner classes - Introduced `HideInUi` property in `EssentialsRoomCombinerPropertiesConfig` to control UI visibility. - Added `HideInUi` interface property in `IEssentialsRoomCombiner`. - Implemented `HideInUi` in `RoomCombinationScenario`, along with new `Key` and `Name` properties for improved data representation. --- .../EssentialsRoomCombinerPropertiesConfig.cs | 6 +++++ .../Room/Combining/IEssentialsRoomCombiner.cs | 6 +++++ .../Room/Combining/RoomCombinationScenario.cs | 24 ++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index fec7e380..868f3992 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -103,6 +103,12 @@ namespace PepperDash.Essentials.Core [JsonProperty("name")] public string Name { get; set; } + /// + /// Gets or sets a value indicating whether to hide this scenario in the UI. + /// + [JsonProperty("hideInUi", NullValueHandling = NullValueHandling.Ignore)] + public bool HideInUi { get; set; } + /// /// Gets or sets the collection of partition states. /// diff --git a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs index 50d6d84e..42fcb659 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs @@ -109,6 +109,12 @@ namespace PepperDash.Essentials.Core [JsonProperty("isActive")] bool IsActive { get; } + /// + /// Gets a value indicating whether the entity is active. + /// + [JsonProperty("hideInUi")] + bool HideInUi { get; } + /// /// Activates this room combination scenario /// diff --git a/src/PepperDash.Essentials.Core/Room/Combining/RoomCombinationScenario.cs b/src/PepperDash.Essentials.Core/Room/Combining/RoomCombinationScenario.cs index b6bd2547..aa0bdcaa 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/RoomCombinationScenario.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/RoomCombinationScenario.cs @@ -14,18 +14,40 @@ namespace PepperDash.Essentials.Core { private RoomCombinationScenarioConfig _config; + /// + /// Gets or sets the key associated with the object. + /// [JsonProperty("key")] public string Key { get; set; } + /// + /// Gets or sets the name associated with the object. + /// [JsonProperty("name")] public string Name { get; set; } - [JsonProperty("partitionStates")] + /// + /// Gets a value indicating whether to hide this scenario in the UI. + /// + /// + [JsonProperty("hideInUi")] + + public bool HideInUi + { + get { return _config.HideInUi; } + } + /// /// Gets or sets the PartitionStates /// + /// + [JsonProperty("partitionStates")] + public List PartitionStates { get; private set; } + /// + /// Determines which UI devices get mapped to which room in this scenario. The Key should be the key of the UI device and the Value should be the key of the room to map to + /// [JsonProperty("uiMap")] public Dictionary UiMap { get; set; } From dea4407e3efcc2008c330650631064414a0040e2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Sep 2025 16:36:33 -0600 Subject: [PATCH 02/13] Update src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Room/Combining/IEssentialsRoomCombiner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs index 42fcb659..34d0a0a0 100644 --- a/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs +++ b/src/PepperDash.Essentials.Core/Room/Combining/IEssentialsRoomCombiner.cs @@ -110,7 +110,7 @@ namespace PepperDash.Essentials.Core bool IsActive { get; } /// - /// Gets a value indicating whether the entity is active. + /// Gets a value indicating whether this scenario should be hidden in the UI. /// [JsonProperty("hideInUi")] bool HideInUi { get; } From 738504e9fca8c1269a84ed1715c54ffbd16f3978 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 18 Sep 2025 14:48:21 -0600 Subject: [PATCH 03/13] fix: Add error handling for network parameter retrieval Introduced a try-catch block to handle exceptions when fetching the Crestron Ethernet adapter's ID, subnet mask, and IP address. Added logging for cases where the processor lacks a CS LAN. Also included a new using directive for Serilog.Events. --- .../MobileControlTouchpanelController.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs index a4476cd8..bd082233 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs @@ -16,6 +16,7 @@ using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.DeviceInfo; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.UI; +using Serilog.Events; using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Touchpanel @@ -190,12 +191,19 @@ namespace PepperDash.Essentials.Touchpanel RegisterForExtenders(); - var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter); - var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId); - var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId); + try + { + var csAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetCSAdapter); + var csSubnetMask = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, csAdapterId); + var csIpAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, csAdapterId); - this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask); - this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress); + this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask); + this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress); + } + catch + { + Debug.LogInformation("This processor does not have a CS LAN", this); + } } /// From 258699fbcd5bc575a908bd013184915b2af43d5c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 18 Sep 2025 18:23:12 -0600 Subject: [PATCH 04/13] fix: Enhance AppUrl change logging Updated logging to include the new AppUrl value when it changes. This provides better context in the logs, making it easier to track the specific URL that was set. --- .../Touchpanel/MobileControlTouchpanelController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs index bd082233..61f54832 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs @@ -510,7 +510,7 @@ namespace PepperDash.Essentials.Touchpanel _bridge.UserCodeChanged += UpdateFeedbacks; _bridge.AppUrlChanged += (s, a) => { - this.LogInformation("AppURL changed"); + this.LogInformation("AppURL changed: {appURL}", _bridge.AppUrl); SetAppUrl(_bridge.AppUrl); UpdateFeedbacks(s, a); }; From ba0de5128fb365622f42c4f555cefaf3193c1e4f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 23 Sep 2025 11:56:57 -0600 Subject: [PATCH 05/13] Update src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Touchpanel/MobileControlTouchpanelController.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs index 61f54832..540063c5 100644 --- a/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs +++ b/src/PepperDash.Essentials.MobileControl/Touchpanel/MobileControlTouchpanelController.cs @@ -200,10 +200,18 @@ namespace PepperDash.Essentials.Touchpanel this.csSubnetMask = System.Net.IPAddress.Parse(csSubnetMask); this.csIpAddress = System.Net.IPAddress.Parse(csIpAddress); } - catch + catch (ArgumentException) { Debug.LogInformation("This processor does not have a CS LAN", this); } + catch (InvalidOperationException) + { + Debug.LogInformation("This processor does not have a CS LAN", this); + } + catch (Exception ex) + { + Debug.LogError($"Unexpected exception when checking CS LAN: {ex}", this); + } } /// From d7f9c74b2f19076f3b83468c6f2c203e55c983dc Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 23 Sep 2025 13:39:03 -0500 Subject: [PATCH 06/13] fix: modify volume messenger to start with IBasicVolumeControls --- .../Messengers/DeviceVolumeMessenger.cs | 124 ++++++++++-------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs index b6c9b18e..3a04c77d 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/DeviceVolumeMessenger.cs @@ -1,9 +1,10 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using PepperDash.Core; +using PepperDash.Core.Logging; using PepperDash.Essentials.Core; -using System; namespace PepperDash.Essentials.AppServer.Messengers { @@ -12,35 +13,46 @@ namespace PepperDash.Essentials.AppServer.Messengers /// public class DeviceVolumeMessenger : MessengerBase { - private readonly IBasicVolumeWithFeedback _localDevice; + private readonly IBasicVolumeControls device; - public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device) + /// + /// Initializes a new instance of the class. + /// + /// The key. + /// The message path. + /// The device. + public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeControls device) : base(key, messagePath, device as IKeyName) { - _localDevice = device; + this.device = device; } - private void SendStatus() + private void SendStatus(string id = null) { try { + if (!(device is IBasicVolumeWithFeedback feedbackDevice)) + { + return; + } + var messageObj = new VolumeStateMessage { Volume = new Volume { - Level = _localDevice?.VolumeLevelFeedback.IntValue ?? -1, - Muted = _localDevice?.MuteFeedback.BoolValue ?? false, + Level = feedbackDevice?.VolumeLevelFeedback.IntValue ?? -1, + Muted = feedbackDevice?.MuteFeedback.BoolValue ?? false, HasMute = true, // assume all devices have mute for now } }; - if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced) + if (device is IBasicVolumeWithFeedbackAdvanced volumeAdvanced) { messageObj.Volume.RawValue = volumeAdvanced.RawVolumeLevel.ToString(); messageObj.Volume.Units = volumeAdvanced.Units; } - PostStatusMessage(messageObj); + PostStatusMessage(messageObj, id); } catch (Exception ex) { @@ -53,44 +65,23 @@ namespace PepperDash.Essentials.AppServer.Messengers protected override void RegisterActions() { - AddAction("/fullStatus", (id, content) => SendStatus()); - - AddAction("/level", (id, content) => - { - var volume = content.ToObject>(); - - _localDevice.SetVolume(volume.Value); - }); + AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => + { + Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume up with {value}", DeviceKey, b); + try + { + device.VolumeUp(b); + } + catch (Exception ex) + { + Debug.LogMessage(ex, "Got exception during volume up: {Exception}", null, ex); + } + })); AddAction("/muteToggle", (id, content) => - { - _localDevice.MuteToggle(); - }); - - AddAction("/muteOn", (id, content) => - { - _localDevice.MuteOn(); - }); - - AddAction("/muteOff", (id, content) => - { - _localDevice.MuteOff(); - }); - - AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => - { - Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Calling {localDevice} volume up with {value}", DeviceKey, b); - try - { - _localDevice.VolumeUp(b); - } - catch (Exception ex) - { - Debug.LogMessage(ex, "Got exception during volume up: {Exception}", null, ex); - } - })); - - + { + device.MuteToggle(); + }); AddAction("/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(DeviceKey, content, (b) => { @@ -98,7 +89,7 @@ namespace PepperDash.Essentials.AppServer.Messengers try { - _localDevice.VolumeDown(b); + device.VolumeDown(b); } catch (Exception ex) { @@ -106,7 +97,38 @@ namespace PepperDash.Essentials.AppServer.Messengers } })); - _localDevice.MuteFeedback.OutputChange += (sender, args) => + if (!(device is IBasicVolumeWithFeedback feedback)) + { + this.LogDebug("Skipping feedback methods for {deviceKey}", (device as IKeyName)?.Key); + return; + } + + AddAction("/fullStatus", (id, content) => SendStatus(id)); + + AddAction("/volumeStatus", (id, content) => SendStatus(id)); + + AddAction("/level", (id, content) => + { + var volume = content.ToObject>(); + + feedback.SetVolume(volume.Value); + }); + + + + AddAction("/muteOn", (id, content) => + { + feedback.MuteOn(); + }); + + AddAction("/muteOff", (id, content) => + { + feedback.MuteOff(); + }); + + + + feedback.MuteFeedback.OutputChange += (sender, args) => { PostStatusMessage(JToken.FromObject( new @@ -119,10 +141,10 @@ namespace PepperDash.Essentials.AppServer.Messengers ); }; - _localDevice.VolumeLevelFeedback.OutputChange += (sender, args) => + feedback.VolumeLevelFeedback.OutputChange += (sender, args) => { var rawValue = ""; - if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced) + if (feedback is IBasicVolumeWithFeedbackAdvanced volumeAdvanced) { rawValue = volumeAdvanced.RawVolumeLevel.ToString(); } @@ -138,8 +160,6 @@ namespace PepperDash.Essentials.AppServer.Messengers PostStatusMessage(JToken.FromObject(message)); }; - - } #endregion From 278408a3bcbb1103a22f3f1fd88263867ba5aca4 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 09:45:42 -0500 Subject: [PATCH 07/13] docs: reword XML comments for IHasFeedback Interface --- src/PepperDash.Essentials.Core/Devices/IHasFeedbacks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/IHasFeedbacks.cs b/src/PepperDash.Essentials.Core/Devices/IHasFeedbacks.cs index 8850a6b1..330538e0 100644 --- a/src/PepperDash.Essentials.Core/Devices/IHasFeedbacks.cs +++ b/src/PepperDash.Essentials.Core/Devices/IHasFeedbacks.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials.Core public interface IHasFeedback : IKeyed { /// - /// This method shall return a list of all Output objects on a device, + /// This method returns a list of all Output objects on a device, /// including all "aggregate" devices. /// FeedbackCollection Feedbacks { get; } From d9ef8a22899bf162f84b32ae80894c53efe1d80e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 09:46:03 -0500 Subject: [PATCH 08/13] docs: add XML comments for IAnalogInput --- src/PepperDash.Essentials.Core/CrestronIO/IAnalogInput.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PepperDash.Essentials.Core/CrestronIO/IAnalogInput.cs b/src/PepperDash.Essentials.Core/CrestronIO/IAnalogInput.cs index c647834e..426834ed 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/IAnalogInput.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/IAnalogInput.cs @@ -12,6 +12,12 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public interface IAnalogInput { + /// + /// Get the InputValueFeedback. + /// + /// + /// Updates when the analog input value changes + /// IntFeedback InputValueFeedback { get; } } } \ No newline at end of file From f8728b6825f54d8ff658483cf4cd342b0721a5a1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 09:46:55 -0500 Subject: [PATCH 09/13] docs: update XML comments for EssentialsDeviceFactory --- .../Devices/EssentialsDeviceFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PepperDash.Essentials.Core/Devices/EssentialsDeviceFactory.cs b/src/PepperDash.Essentials.Core/Devices/EssentialsDeviceFactory.cs index 3ac326bf..9c1a6a94 100644 --- a/src/PepperDash.Essentials.Core/Devices/EssentialsDeviceFactory.cs +++ b/src/PepperDash.Essentials.Core/Devices/EssentialsDeviceFactory.cs @@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core public List TypeNames { get; protected set; } /// - /// The method that will build the device + /// Build the device using the configuration /// /// The device config /// An instance of the device From 72e67a1c4c68b29114f8261c2d7989a797f10a08 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 09:47:44 -0500 Subject: [PATCH 10/13] fix: implement IHasFeedback for all IO devices and modify logging --- .../CrestronIO/GenericDigitalInputDevice.cs | 85 +++++------ .../GenericVersiportAnalogInputDevice.cs | 138 +++++++----------- .../CrestronIO/GenericVersiportInputDevice.cs | 109 +++++++------- .../GenericVersiportOutputDevice.cs | 136 +++++++---------- 4 files changed, 195 insertions(+), 273 deletions(-) diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericDigitalInputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericDigitalInputDevice.cs index 8463ae96..6f858144 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericDigitalInputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericDigitalInputDevice.cs @@ -2,59 +2,54 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Core.Logging; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; -using Serilog.Events; namespace PepperDash.Essentials.Core.CrestronIO { - [Description("Wrapper class for Digital Input")] + /// /// Represents a GenericDigitalInputDevice /// - public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput + /// [Description("Wrapper class for Digital Input")] + public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IHasFeedback { - /// - /// Gets or sets the InputPort - /// - public DigitalInput InputPort { get; private set; } + private DigitalInput inputPort; /// /// Gets or sets the InputStateFeedback /// public BoolFeedback InputStateFeedback { get; private set; } - Func InputStateFeedbackFunc - { - get - { - return () => InputPort.State; - } - } - + /// + public FeedbackCollection Feedbacks { get; private set; } = new FeedbackCollection(); + /// + /// Initializes a new instance of the class. + /// + /// key for device + /// name for device + /// function to call after activation. Should return the DigitalInput + /// config for device public GenericDigitalInputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) : base(key, name) { - InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc); + InputStateFeedback = new BoolFeedback("inputState", () => inputPort.State); AddPostActivationAction(() => { - InputPort = postActivationFunc(config); + inputPort = postActivationFunc(config); - InputPort.Register(); - - InputPort.StateChange += InputPort_StateChange; + inputPort.Register(); + inputPort.StateChange += InputPort_StateChange; }); } @@ -71,41 +66,31 @@ namespace PepperDash.Essentials.Core.CrestronIO private static DigitalInput GetDigitalInput(IOPortConfig dc) { - IDigitalInputPorts ioPortDevice; if (dc.PortDeviceKey.Equals("processor")) { if (!Global.ControlSystem.SupportsDigitalInput) { - Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Processor does not support Digital Inputs"); + Debug.LogError("GetDigitalInput: Processor does not support Digital Inputs"); return null; } - ioPortDevice = Global.ControlSystem; + + return Global.ControlSystem.DigitalInputPorts[dc.PortNumber]; } - else + + if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IDigitalInputPorts ioPortDevice)) { - var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IDigitalInputPorts; - if (ioPortDev == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey); - return null; - } - ioPortDevice = ioPortDev; - } - if (ioPortDevice == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey); + Debug.LogError("GetDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey); return null; } if (dc.PortNumber > ioPortDevice.NumberOfDigitalInputPorts) { - Debug.LogMessage(LogEventLevel.Information, "GetDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + Debug.LogError("GetDigitalInput: Device {key} does not contain a digital input port {port}", dc.PortDeviceKey, dc.PortNumber); + return null; } return ioPortDevice.DigitalInputPorts[dc.PortNumber]; - - } #endregion @@ -131,20 +116,20 @@ namespace PepperDash.Essentials.Core.CrestronIO } else { - Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } try { - Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X")); // Link feedback for input state InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]); } catch (Exception e) { - Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); - Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); + this.LogError("Unable to link device {key}. {message}", Key, e.Message); + this.LogDebug(e, "Stack Trace: "); } } @@ -153,22 +138,22 @@ namespace PepperDash.Essentials.Core.CrestronIO #region Factory /// - /// Represents a GenericDigitalInputDeviceFactory + /// Factory for creating GenericDigitalInputDevice devices /// public class GenericDigitalInputDeviceFactory : EssentialsDeviceFactory { + /// + /// Constructor for GenericDigitalInputDeviceFactory + /// public GenericDigitalInputDeviceFactory() { TypeNames = new List() { "digitalinput" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Digital Input Device"); + Debug.LogDebug("Factory Attempting to create new Generic Digital Input Device"); var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs index c87a688c..0c5cec65 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs @@ -2,66 +2,64 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Bridges; - - using Newtonsoft.Json; -using Serilog.Events; +using PepperDash.Core; +using PepperDash.Core.Logging; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.CrestronIO { /// /// Represents a generic digital input deviced tied to a versiport /// - public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput + public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput, IHasFeedback { - public Versiport InputPort { get; private set; } + private Versiport inputPort; + /// public IntFeedback InputValueFeedback { get; private set; } + + /// + /// Get the InputMinimumChangeFeedback + /// + /// + /// Updates when the analog input minimum change value changes + /// public IntFeedback InputMinimumChangeFeedback { get; private set; } - Func InputValueFeedbackFunc - { - get - { - return () => InputPort.AnalogIn; - } - } - - Func InputMinimumChangeFeedbackFunc - { - get { return () => InputPort.AnalogMinChange; } - } + /// + public FeedbackCollection Feedbacks { get; private set; } = new FeedbackCollection(); + /// + /// Initializes a new instance of the class. + /// + /// key for the device + /// name for the device + /// function to call after activation + /// IO port configuration public GenericVersiportAnalogInputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) : base(key, name) { - InputValueFeedback = new IntFeedback(InputValueFeedbackFunc); - InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc); + InputValueFeedback = new IntFeedback("inputValue", () => inputPort.AnalogIn); + InputMinimumChangeFeedback = new IntFeedback("inputMinimumChange", () => inputPort.AnalogMinChange); AddPostActivationAction(() => { - InputPort = postActivationFunc(config); + inputPort = postActivationFunc(config); - InputPort.Register(); + inputPort.Register(); - InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput); - InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655); + inputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput); + inputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655); if (config.DisablePullUpResistor) - InputPort.DisablePullUpResistor = true; + inputPort.DisablePullUpResistor = true; - InputPort.VersiportChange += InputPort_VersiportChange; - - Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor); + inputPort.VersiportChange += InputPort_VersiportChange; + this.LogDebug("Created GenericVersiportAnalogInputDevice on port {port}. DisablePullUpResistor: {pullUpResistorDisabled}", config.PortNumber, inputPort.DisablePullUpResistor); }); } @@ -69,20 +67,17 @@ namespace PepperDash.Essentials.Core.CrestronIO /// /// Set minimum voltage change for device to update voltage changed method /// - /// valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details - /// - /// SetMinimumChange method - /// + /// valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details public void SetMinimumChange(ushort value) { - InputPort.AnalogMinChange = value; + inputPort.AnalogMinChange = value; } void InputPort_VersiportChange(Versiport port, VersiportEventArgs args) { - Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); + this.LogDebug("Versiport change: {event}", args.Event); - if(args.Event == eVersiportEvent.AnalogInChange) + if (args.Event == eVersiportEvent.AnalogInChange) InputValueFeedback.FireUpdate(); if (args.Event == eVersiportEvent.AnalogMinChangeChange) InputMinimumChangeFeedback.FireUpdate(); @@ -91,9 +86,6 @@ namespace PepperDash.Essentials.Core.CrestronIO #region Bridge Linking - /// - /// LinkToApi method - /// /// public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { @@ -110,12 +102,12 @@ namespace PepperDash.Essentials.Core.CrestronIO } else { - Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } try { - Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + this.LogDebug("Linking to Trilist '{trilistId}'", trilist.ID.ToString("X")); // Link feedback for input state InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]); @@ -125,8 +117,8 @@ namespace PepperDash.Essentials.Core.CrestronIO } catch (Exception e) { - Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); - Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); + this.LogError("Unable to link device {key}: {message}", Key, e.Message); + this.LogDebug(e, "Stack Trace: "); } trilist.OnlineStatusChange += (d, args) => @@ -138,11 +130,6 @@ namespace PepperDash.Essentials.Core.CrestronIO } - void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) - { - throw new NotImplementedException(); - } - #endregion @@ -151,70 +138,55 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public static Versiport GetVersiportDigitalInput(IOPortConfig dc) { - - IIOPorts ioPortDevice; - if (dc.PortDeviceKey.Equals("processor")) { if (!Global.ControlSystem.SupportsVersiport) { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Processor does not support Versiports"); + Debug.LogError("GetVersiportAnalogInput: Processor does not support Versiports"); return null; } - ioPortDevice = Global.ControlSystem; + return Global.ControlSystem.VersiPorts[dc.PortNumber]; } - else + + if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice)) { - var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts; - if (ioPortDev == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey); - return null; - } - ioPortDevice = ioPortDev; - } - if (ioPortDevice == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey); + Debug.LogError("GetVersiportAnalogInput: Device {key} is not a valid device", dc.PortDeviceKey); return null; } if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + Debug.LogError("GetVersiportAnalogInput: Device {key} does not contain a port {port}", dc.PortDeviceKey, dc.PortNumber); return null; } - if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput) + if (!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput) { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber); + Debug.LogError("GetVersiportAnalogInput: Device {key} does not support AnalogInput on port {port}", dc.PortDeviceKey, dc.PortNumber); return null; } - return ioPortDevice.VersiPorts[dc.PortNumber]; - - } } /// - /// Represents a GenericVersiportAbalogInputDeviceFactory + /// Represents a GenericVersiportAnalogInputDeviceFactory /// - public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory + public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory { - public GenericVersiportAbalogInputDeviceFactory() + /// + /// Constructor for GenericVersiportAnalogInputDeviceFactory + /// + public GenericVersiportAnalogInputDeviceFactory() { TypeNames = new List() { "versiportanaloginput" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); + Debug.LogDebug("Factory Attempting to create new Generic Versiport Device"); var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs index f94137c3..e2c4474a 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs @@ -2,78 +2,82 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Bridges; - - using Newtonsoft.Json; -using Serilog.Events; +using PepperDash.Core; +using PepperDash.Core.Logging; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core.CrestronIO { /// /// Represents a generic digital input deviced tied to a versiport /// - public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider + public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput, IPartitionStateProvider, IHasFeedback { - public Versiport InputPort { get; private set; } + private Versiport inputPort; + /// + /// Gets or sets the InputStateFeedback + /// public BoolFeedback InputStateFeedback { get; private set; } - Func InputStateFeedbackFunc - { - get - { - return () => InputPort.DigitalIn; - } - } + /// + public FeedbackCollection Feedbacks { get; private set; } = new FeedbackCollection(); /// /// Gets or sets the PartitionPresentFeedback /// public BoolFeedback PartitionPresentFeedback { get; } - public bool PartitionPresent => !InputStateFeedbackFunc(); + /// + /// Get partition state + /// + public bool PartitionPresent => !inputPort.DigitalIn; + /// + /// Initializes a new instance of the class. + /// + /// key for device + /// name for device + /// function to call after activation. Should return the Versiport + /// config for device public GenericVersiportDigitalInputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) : base(key, name) { - InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc); - PartitionPresentFeedback = new BoolFeedback(() => !InputStateFeedbackFunc()); + InputStateFeedback = new BoolFeedback("inputState", () => inputPort.DigitalIn); + PartitionPresentFeedback = new BoolFeedback("partitionPresent", () => !inputPort.DigitalIn); AddPostActivationAction(() => { - InputPort = postActivationFunc(config); + inputPort = postActivationFunc(config); - InputPort.Register(); + inputPort.Register(); - InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput); + inputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput); if (config.DisablePullUpResistor) - InputPort.DisablePullUpResistor = true; + inputPort.DisablePullUpResistor = true; - InputPort.VersiportChange += InputPort_VersiportChange; + inputPort.VersiportChange += InputPort_VersiportChange; InputStateFeedback.FireUpdate(); PartitionPresentFeedback.FireUpdate(); - Debug.LogMessage(LogEventLevel.Debug, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor); + this.LogDebug("Created GenericVersiportDigitalInputDevice for port {port}. DisablePullUpResistor: {pullUpResistorDisable}", config.PortNumber, inputPort.DisablePullUpResistor); }); + Feedbacks.Add(InputStateFeedback); + Feedbacks.Add(PartitionPresentFeedback); } void InputPort_VersiportChange(Versiport port, VersiportEventArgs args) { - Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); + this.LogDebug("Versiport change: {0}", args.Event); - if(args.Event == eVersiportEvent.DigitalInChange) + if (args.Event == eVersiportEvent.DigitalInChange) { InputStateFeedback.FireUpdate(); PartitionPresentFeedback.FireUpdate(); @@ -102,20 +106,20 @@ namespace PepperDash.Essentials.Core.CrestronIO } else { - Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } try { - Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X")); // Link feedback for input state InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]); } catch (Exception e) { - Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); - Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); + this.LogError("Unable to link device {key}. Input is null. {message}", Key, e.Message); + this.LogDebug(e, "Stack Trace: "); } } @@ -127,63 +131,50 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public static Versiport GetVersiportDigitalInput(IOPortConfig dc) { - - IIOPorts ioPortDevice; - if (dc.PortDeviceKey.Equals("processor")) { if (!Global.ControlSystem.SupportsVersiport) { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Processor does not support Versiports"); + Debug.LogError("GetVersiportDigitalInput: Processor does not support Versiports"); return null; } - ioPortDevice = Global.ControlSystem; + return Global.ControlSystem.VersiPorts[dc.PortNumber]; } - else + + if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice)) { - var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts; - if (ioPortDev == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey); - return null; - } - ioPortDevice = ioPortDev; - } - if (ioPortDevice == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey); + Debug.LogError("GetVersiportDigitalInput: Device {key} is not a valid device", dc.PortDeviceKey); return null; } if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + Debug.LogError("GetVersiportDigitalInput: Device {key} does not contain versiport {port}", dc.PortDeviceKey, dc.PortNumber); + return null; } return ioPortDevice.VersiPorts[dc.PortNumber]; - - } } /// - /// Represents a GenericVersiportDigitalInputDeviceFactory + /// Factory class for GenericVersiportDigitalInputDevice /// public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory { + /// + /// Constructor for GenericVersiportDigitalInputDeviceFactory + /// public GenericVersiportDigitalInputDeviceFactory() { TypeNames = new List() { "versiportinput" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); + Debug.LogDebug("Factory Attempting to create new Generic Versiport Device"); var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs index 7a823c9a..1ff4db6e 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs @@ -2,18 +2,13 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Bridges; - - using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Core.Logging; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; using Serilog.Events; namespace PepperDash.Essentials.Core.CrestronIO @@ -21,76 +16,68 @@ namespace PepperDash.Essentials.Core.CrestronIO /// /// Represents a generic digital input deviced tied to a versiport /// - public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput + public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput, IHasFeedback { - public Versiport OutputPort { get; private set; } + private Versiport outputPort; + /// + /// Gets or sets the OutputStateFeedback + /// public BoolFeedback OutputStateFeedback { get; private set; } - Func OutputStateFeedbackFunc - { - get - { - return () => OutputPort.DigitalOut; - } - } + /// + public FeedbackCollection Feedbacks { get; private set; } = new FeedbackCollection(); + /// + /// Initializes a new instance of the class. + /// public GenericVersiportDigitalOutputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) : base(key, name) { - OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc); + OutputStateFeedback = new BoolFeedback("outputState", () => outputPort.DigitalOut); AddPostActivationAction(() => { - OutputPort = postActivationFunc(config); + outputPort = postActivationFunc(config); - OutputPort.Register(); + outputPort.Register(); - if (!OutputPort.SupportsDigitalOutput) + if (!outputPort.SupportsDigitalOutput) { - Debug.LogMessage(LogEventLevel.Information, this, "Device does not support configuration as a Digital Output"); + this.LogError("Device does not support configuration as a Digital Output"); return; } - OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput); + outputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput); - OutputPort.VersiportChange += OutputPort_VersiportChange; + outputPort.VersiportChange += OutputPort_VersiportChange; }); - } void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args) { - Debug.LogMessage(LogEventLevel.Debug, this, "Versiport change: {0}", args.Event); + this.LogDebug("Versiport change: {event}", args.Event); - if(args.Event == eVersiportEvent.DigitalOutChange) + if (args.Event == eVersiportEvent.DigitalOutChange) OutputStateFeedback.FireUpdate(); } /// /// Set value of the versiport digital output /// - /// value to set the output to - /// - /// SetOutput method - /// + /// value to set the output to public void SetOutput(bool state) { - if (OutputPort.SupportsDigitalOutput) - { - Debug.LogMessage(LogEventLevel.Information, this, "Passed the Check"); - - OutputPort.DigitalOut = state; - - } - else - { - Debug.LogMessage(LogEventLevel.Information, this, "Versiport does not support Digital Output Mode"); - } + if (!outputPort.SupportsDigitalOutput) + { + this.LogError("Versiport does not support Digital Output Mode"); + return; + } + outputPort.DigitalOut = state; } #region Bridge Linking @@ -114,12 +101,12 @@ namespace PepperDash.Essentials.Core.CrestronIO } else { - Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + this.LogWarning("Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } try { - Debug.LogMessage(LogEventLevel.Debug, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + this.LogDebug("Linking to Trilist '{0}'", trilist.ID.ToString("X")); // Link feedback for input state OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]); @@ -127,8 +114,8 @@ namespace PepperDash.Essentials.Core.CrestronIO } catch (Exception e) { - Debug.LogMessage(LogEventLevel.Debug, this, "Unable to link device '{0}'. Input is null", Key); - Debug.LogMessage(LogEventLevel.Debug, this, "Error: {0}", e); + this.LogError("Unable to link device: {message}", e.Message); + this.LogDebug(e, "Stack Trace: "); } } @@ -140,41 +127,28 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public static Versiport GetVersiportDigitalOutput(IOPortConfig dc) { - - IIOPorts ioPortDevice; - - if (dc.PortDeviceKey.Equals("processor")) + if (dc.PortDeviceKey.Equals("processor")) + { + if (!Global.ControlSystem.SupportsVersiport) { - if (!Global.ControlSystem.SupportsVersiport) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Processor does not support Versiports"); - return null; - } - ioPortDevice = Global.ControlSystem; - } - else - { - var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts; - if (ioPortDev == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey); - return null; - } - ioPortDevice = ioPortDev; - } - if (ioPortDevice == null) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey); + Debug.LogError("GetVersiportDigitalOuptut: Processor does not support Versiports"); return null; } + return Global.ControlSystem.VersiPorts[dc.PortNumber]; + } - if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) - { - Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); - } - var port = ioPortDevice.VersiPorts[dc.PortNumber]; - return port; + if (!(DeviceManager.GetDeviceForKey(dc.PortDeviceKey) is IIOPorts ioPortDevice)) + { + Debug.LogError("GetVersiportDigitalOutput: Device {key} is not a valid device", dc.PortDeviceKey); + return null; + } + if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts) + { + Debug.LogMessage(LogEventLevel.Information, "GetVersiportDigitalOutput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + return null; + } + return ioPortDevice.VersiPorts[dc.PortNumber]; } } @@ -184,18 +158,18 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory { + /// + /// Initialize a new instance of the class. + /// public GenericVersiportDigitalOutputDeviceFactory() { TypeNames = new List() { "versiportoutput" }; } - /// - /// BuildDevice method - /// /// public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new Generic Versiport Device"); + Debug.LogDebug("Factory Attempting to create new Generic Versiport Device"); var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); From df03a71cbc7672ea24621fb0dfd9385191d14827 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 09:50:55 -0500 Subject: [PATCH 11/13] chore: fix errors in log statements Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../CrestronIO/GenericVersiportAnalogInputDevice.cs | 2 +- .../CrestronIO/GenericVersiportOutputDevice.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs index 0c5cec65..ad5507d0 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs @@ -171,7 +171,7 @@ namespace PepperDash.Essentials.Core.CrestronIO /// - /// Represents a GenericVersiportAnalogInputDeviceFactory + /// Factory for creating GenericVersiportAnalogInputDevice devices /// public class GenericVersiportAnalogInputDeviceFactory : EssentialsDeviceFactory { diff --git a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs index 1ff4db6e..ee3f0320 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs @@ -131,7 +131,7 @@ namespace PepperDash.Essentials.Core.CrestronIO { if (!Global.ControlSystem.SupportsVersiport) { - Debug.LogError("GetVersiportDigitalOuptut: Processor does not support Versiports"); + Debug.LogError("GetVersiportDigitalOutput: Processor does not support Versiports"); return null; } return Global.ControlSystem.VersiPorts[dc.PortNumber]; From 11b190e76fb6fb4935df80b8343cdf2e2902d665 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 10:51:22 -0500 Subject: [PATCH 12/13] docs: put XML comments on correct thing --- .../CrestronIO/IOPortConfig.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/PepperDash.Essentials.Core/CrestronIO/IOPortConfig.cs b/src/PepperDash.Essentials.Core/CrestronIO/IOPortConfig.cs index 52db6300..8641df69 100644 --- a/src/PepperDash.Essentials.Core/CrestronIO/IOPortConfig.cs +++ b/src/PepperDash.Essentials.Core/CrestronIO/IOPortConfig.cs @@ -14,25 +14,28 @@ namespace PepperDash.Essentials.Core.CrestronIO /// public class IOPortConfig { - [JsonProperty("portDeviceKey")] /// /// Gets or sets the PortDeviceKey /// + [JsonProperty("portDeviceKey")] public string PortDeviceKey { get; set; } - [JsonProperty("portNumber")] + /// /// Gets or sets the PortNumber /// + [JsonProperty("portNumber")] public uint PortNumber { get; set; } - [JsonProperty("disablePullUpResistor")] + /// /// Gets or sets the DisablePullUpResistor /// + [JsonProperty("disablePullUpResistor")] public bool DisablePullUpResistor { get; set; } - [JsonProperty("minimumChange")] + /// /// Gets or sets the MinimumChange /// + [JsonProperty("minimumChange")] public int MinimumChange { get; set; } } } \ No newline at end of file From 9fc558653191383f6f8150e64caaa2a31ca6f2bc Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Sep 2025 15:29:35 -0500 Subject: [PATCH 13/13] fix: use IBasicVolumeControls to build DeviceVolumeMessenger --- .../MobileControlSystemController.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs index 49e71010..83254e76 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs @@ -486,15 +486,15 @@ namespace PepperDash.Essentials messengerAdded = true; } - if (device is IBasicVolumeWithFeedback) + if (device is IBasicVolumeControls) { var deviceKey = device.Key; this.LogVerbose( - "Adding IBasicVolumeControlWithFeedback for {deviceKey}", + "Adding IBasicVolumeControls for {deviceKey}", deviceKey ); - var volControlDevice = device as IBasicVolumeWithFeedback; + var volControlDevice = device as IBasicVolumeControls; var messenger = new DeviceVolumeMessenger( $"{device.Key}-volume-{Key}", string.Format("/device/{0}", deviceKey),