From 307b2f54a70126ce7e46148f1328ac0592a1ae32 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 13 Aug 2025 13:55:24 -0500 Subject: [PATCH 1/5] fix: update Crestron databases From 3f8e72f366bad0286374f06a917709e0059987ae Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 14 Aug 2025 12:20:03 -0500 Subject: [PATCH 2/5] wip: reverse genericcomm --- .../Comm and IR/GenericCommBridge.cs | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs new file mode 100644 index 00000000..6d18d38b --- /dev/null +++ b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharp.CrestronSockets; +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.Config; + + +namespace PepperDash.Essentials.Core +{ + /// + /// Implements IBasicCommunication and sends all communication through an EISC + /// + [Description("Generic communication wrapper class for any IBasicCommunication type")] + public class GenericCommBridge : ReconfigurableBridgableDevice, IBasicCommunication + { + public GenericComm(DeviceConfig config) + : base(config) + { + + } + + public static IKeyed BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + return new GenericComm(dc); + } + + protected override void CustomSetConfig(DeviceConfig config) + { + PropertiesConfig = CommFactory.GetControlPropertiesConfig(config); + + ConfigWriter.UpdateDeviceConfig(config); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new IBasicCommunicationJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + // this is a permanent event handler. This cannot be -= from event + CommPort.TextReceived += (s, a) => + { + trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text); + }; + trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s)); + trilist.SetStringSigAction(joinMap.SetPortConfig.JoinNumber, SetPortConfig); + + + var sComm = CommPort as ISocketStatus; + if (sComm == null) return; + sComm.ConnectionChange += (s, a) => + { + trilist.SetUshort(joinMap.Status.JoinNumber, (ushort)(a.Client.ClientStatus)); + trilist.SetBool(joinMap.Connected.JoinNumber, a.Client.ClientStatus == + SocketStatus.SOCKET_STATUS_CONNECTED); + }; + + trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, b => + { + if (b) + { + sComm.Connect(); + } + else + { + sComm.Disconnect(); + } + }); + } + } + + public class GenericCommBridgeFactory : EssentialsDeviceFactory + { + public GenericCommBridgeFactory() + { + TypeNames = new List() { "genericCommBridge" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); + return new GenericComm(dc); + } + } +} \ No newline at end of file From 5ad232135ccebdacd9439003e65d6d3dce5c43ad Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 14 Aug 2025 14:22:22 -0500 Subject: [PATCH 3/5] feat: CommBridge communication method implementation In some scenarios, it becomes necessary to have a plugin in Essentials use a Communications method that's defined in SIMPL and bridged the opposite from what normally happens. The CommBridge method facilitates that sort of operation. To use it: set the method in the Control configuration for the device to 'comBridge'. The bridge will be built with a key of "{deviceKey}-simpl", so it can be added to a bridge using that key. --- .../Comm and IR/CommBridge.cs | 97 ++++++++++++++++ .../Comm and IR/GenericCommBridge.cs | 105 ------------------ .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 98 insertions(+), 105 deletions(-) create mode 100644 src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs delete mode 100644 src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs new file mode 100644 index 00000000..73e839f8 --- /dev/null +++ b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharp.CrestronSockets; +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; +using System.Text; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.Config; + + +namespace PepperDash.Essentials.Core +{ + /// + /// Implements IBasicCommunication and sends all communication through an EISC + /// + [Description("Generic communication wrapper class for any IBasicCommunication type")] + public class CommBridge : EssentialsBridgeableDevice, IBasicCommunication + { + private EiscApiAdvanced eisc; + + private IBasicCommunicationJoinMap joinMap; + + public event EventHandler TextReceived; + + public event EventHandler BytesReceived; + + public bool IsConnected { get; private set; } + + public CommBridge(string key, string name) + : base(key, name) + { + + } + + public void SendBytes(byte[] bytes) + { + eisc.Eisc.SetString(joinMap.SendText.JoinNumber, Encoding.ASCII.GetString(bytes, 0, bytes.Length)); + } + + public void SendText(string text) + { + eisc.Eisc.SetString(joinMap.SendText.JoinNumber, text); + } + + public void Connect() { + eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, true); + } + + public void Disconnect() { + eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, false); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + joinMap = new IBasicCommunicationJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + eisc = bridge; + + trilist.SetBoolSigAction(joinMap.Connected.JoinNumber, (b) => IsConnected = b); + + trilist.SetStringSigAction(joinMap.TextReceived.JoinNumber, (s) => { + var textHandler = TextReceived; + + if (textHandler != null) + { + textHandler(this, new GenericCommMethodReceiveTextArgs(s)); + } + + var bytesHandler = BytesReceived; + + if(bytesHandler != null) + { + bytesHandler(this, new GenericCommMethodReceiveBytesArgs(Encoding.ASCII.GetBytes(s))); + } + }); + } + } +} \ No newline at end of file diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs deleted file mode 100644 index 6d18d38b..00000000 --- a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericCommBridge.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Collections.Generic; -using Crestron.SimplSharp.CrestronSockets; -using Crestron.SimplSharpPro.DeviceSupport; -using Newtonsoft.Json; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Core.Config; - - -namespace PepperDash.Essentials.Core -{ - /// - /// Implements IBasicCommunication and sends all communication through an EISC - /// - [Description("Generic communication wrapper class for any IBasicCommunication type")] - public class GenericCommBridge : ReconfigurableBridgableDevice, IBasicCommunication - { - public GenericComm(DeviceConfig config) - : base(config) - { - - } - - public static IKeyed BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); - return new GenericComm(dc); - } - - protected override void CustomSetConfig(DeviceConfig config) - { - PropertiesConfig = CommFactory.GetControlPropertiesConfig(config); - - ConfigWriter.UpdateDeviceConfig(config); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new IBasicCommunicationJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - // this is a permanent event handler. This cannot be -= from event - CommPort.TextReceived += (s, a) => - { - trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text); - }; - trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s)); - trilist.SetStringSigAction(joinMap.SetPortConfig.JoinNumber, SetPortConfig); - - - var sComm = CommPort as ISocketStatus; - if (sComm == null) return; - sComm.ConnectionChange += (s, a) => - { - trilist.SetUshort(joinMap.Status.JoinNumber, (ushort)(a.Client.ClientStatus)); - trilist.SetBool(joinMap.Connected.JoinNumber, a.Client.ClientStatus == - SocketStatus.SOCKET_STATUS_CONNECTED); - }; - - trilist.SetBoolSigAction(joinMap.Connect.JoinNumber, b => - { - if (b) - { - sComm.Connect(); - } - else - { - sComm.Disconnect(); - } - }); - } - } - - public class GenericCommBridgeFactory : EssentialsDeviceFactory - { - public GenericCommBridgeFactory() - { - TypeNames = new List() { "genericCommBridge" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); - return new GenericComm(dc); - } - } -} \ No newline at end of file diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 0dfd3657..9ae4379d 100644 --- a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -165,6 +165,7 @@ + From dba07dced8b5b9bfd99f24b8979e28019161825b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 14 Aug 2025 14:25:36 -0500 Subject: [PATCH 4/5] fix: PD Core 1.4.2 and comm factory update --- packages.config | 2 +- .../PepperDashEssentialsBase/Comm and IR/CommFactory.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 242a7b7d..e0ed54c7 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs index 5203d416..d63abd91 100644 --- a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs +++ b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs @@ -50,6 +50,9 @@ namespace PepperDash.Essentials.Core case eControlMethod.Com: comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig); break; + case eControlMethod.ComBridge: + comm = new CommBridge(deviceConfig.Key + "-simpl", deviceConfig.Name + " Simpl"); + break; case eControlMethod.Cec: comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig); break; From 078f35a91d7d57a62eb5a8ee84f3c9d397057e4f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 15 Aug 2025 09:47:56 -0500 Subject: [PATCH 5/5] fix: check EISC for null prior to using --- .../Comm and IR/CommBridge.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs index 73e839f8..af9fd543 100644 --- a/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs +++ b/src/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommBridge.cs @@ -37,19 +37,39 @@ namespace PepperDash.Essentials.Core public void SendBytes(byte[] bytes) { + if (eisc == null) + { + Debug.Console(0, this, "EISC not linked. Call LinkToApi before sending bytes."); + return; + } eisc.Eisc.SetString(joinMap.SendText.JoinNumber, Encoding.ASCII.GetString(bytes, 0, bytes.Length)); } public void SendText(string text) { + if (eisc == null) + { + Debug.Console(0, this, "EISC not linked. Call LinkToApi before sending text."); + return; + } eisc.Eisc.SetString(joinMap.SendText.JoinNumber, text); } public void Connect() { + if (eisc == null) + { + Debug.Console(0, this, "EISC not linked. Call LinkToApi before connecting."); + return; + } eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, true); } public void Disconnect() { + if (eisc == null) + { + Debug.Console(0, this, "EISC not linked. Call LinkToApi before disconnecting."); + return; + } eisc.Eisc.SetBool(joinMap.Connect.JoinNumber, false); }