diff --git a/PepperDashEssentials/Bridges/BridgeBase.cs b/PepperDashEssentials/Bridges/BridgeBase.cs
new file mode 100644
index 00000000..1131c1b0
--- /dev/null
+++ b/PepperDashEssentials/Bridges/BridgeBase.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.EthernetCommunication;
+
+using Newtonsoft.Json;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Devices;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.DM;
+
+namespace PepperDash.Essentials.Bridges
+{
+ ///
+ /// Base class for all bridge class variants
+ ///
+ public class BridgeBase : Device
+ {
+ public BridgeApi Api { get; private set; }
+
+ public BridgeBase(string key) :
+ base(key)
+ {
+
+ }
+
+ }
+
+ ///
+ /// Base class for bridge API variants
+ ///
+ public abstract class BridgeApi : Device
+ {
+ public BridgeApi(string key) :
+ base(key)
+ {
+
+ }
+
+ }
+
+ ///
+ /// Bridge API using EISC
+ ///
+ public class EiscApi : BridgeApi
+ {
+ public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
+
+ public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
+
+
+ public EiscApi(DeviceConfig dc) :
+ base(dc.Key)
+ {
+ PropertiesConfig = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
+
+ Eisc.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Eisc_SigChange);
+
+ Eisc.Register();
+
+ AddPostActivationAction( () =>
+ {
+ Debug.Console(1, this, "Linking Devices...");
+
+ foreach (var d in PropertiesConfig.Devices)
+ {
+ var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
+
+ if (device != null)
+ {
+ if (device is GenericComm)
+ {
+ (device as GenericComm).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
+ continue;
+ }
+ else if (device is DmChassisController)
+ {
+ (device as DmChassisController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
+ continue;
+ }
+ else if (device is DmTxControllerBase)
+ {
+ (device as DmTxControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
+ continue;
+ }
+ else if (device is DmRmcControllerBase)
+ {
+ (device as DmRmcControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
+ continue;
+ }
+ }
+ }
+
+ Debug.Console(1, this, "Devices Linked.");
+ });
+ }
+
+ ///
+ /// Handles incoming sig changes
+ ///
+ ///
+ ///
+ void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
+ {
+ if (Debug.Level >= 1)
+ Debug.Console(1, this, "EiscApi change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
+ var uo = args.Sig.UserObject;
+ if (uo is Action)
+ (uo as Action)(args.Sig.BoolValue);
+ else if (uo is Action)
+ (uo as Action)(args.Sig.UShortValue);
+ else if (uo is Action)
+ (uo as Action)(args.Sig.StringValue);
+ }
+ }
+
+ public class EiscApiPropertiesConfig
+ {
+ [JsonProperty("control")]
+ public EssentialsControlPropertiesConfig Control { get; set; }
+
+ [JsonProperty("devices")]
+ public List Devices { get; set; }
+
+ public class ApiDevice
+ {
+ [JsonProperty("deviceKey")]
+ public string DeviceKey { get; set; }
+
+ [JsonProperty("joinStart")]
+ public uint JoinStart { get; set; }
+
+ [JsonProperty("joinMapKey")]
+ public string JoinMapKey { get; set; }
+ }
+
+ }
+
+
+ /////
+ ///// API class for IBasicCommunication devices
+ /////
+ //public class IBasicCommunicationApi : DeviceApiBase
+ //{
+ // public IBasicCommunication Device { get; set; }
+
+ // SerialFeedback TextReceivedFeedback;
+
+ // public IBasicCommunicationApi(IBasicCommunication dev)
+ // {
+ // TextReceivedFeedback = new SerialFeedback();
+
+ // Device = dev;
+
+ // SetupFeedbacks();
+
+ // ActionApi = new Dictionary
+ // {
+ // { "connect", new Action(Device.Connect) },
+ // { "disconnect", new Action(Device.Disconnect) },
+ // { "connectstate", new Action( b => ConnectByState(b) ) },
+ // { "sendtext", new Action( s => Device.SendText(s) ) }
+
+ // };
+
+ // FeedbackApi = new Dictionary
+ // {
+ // { "isconnected", new BoolFeedback( () => Device.IsConnected ) },
+ // { "textrecieved", TextReceivedFeedback }
+ // };
+ // }
+
+ // ///
+ // /// Controls connection based on state of input
+ // ///
+ // ///
+ // void ConnectByState(bool state)
+ // {
+ // if (state)
+ // Device.Connect();
+ // else
+ // Device.Disconnect();
+ // }
+
+ // void SetupFeedbacks()
+ // {
+ // Device.TextReceived += new EventHandler(Device_TextReceived);
+
+ // if(Device is ISocketStatus)
+ // (Device as ISocketStatus).ConnectionChange += new EventHandler(IBasicCommunicationApi_ConnectionChange);
+ // }
+
+ // void IBasicCommunicationApi_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e)
+ // {
+ // FeedbackApi["isconnected"].FireUpdate();
+ // }
+
+ // void Device_TextReceived(object sender, GenericCommMethodReceiveTextArgs e)
+ // {
+ // TextReceivedFeedback.FireUpdate(e.Text);
+ // }
+ //}
+
+
+
+ /////
+ ///// Each flavor of API is a static class with static properties and a static constructor that
+ ///// links up the things to do.
+ /////
+ //public class DmChassisControllerApi : DeviceApiBase
+ //{
+ // IntFeedback Output1Feedback;
+ // IntFeedback Output2Feedback;
+
+ // public DmChassisControllerApi(DmChassisController dev)
+ // {
+ // Output1Feedback = new IntFeedback( new Func(() => 1));
+ // Output2Feedback = new IntFeedback( new Func(() => 2));
+
+ // ActionApi = new Dictionary
+ // {
+
+ // };
+
+ // FeedbackApi = new Dictionary
+ // {
+ // { "Output-1/fb", Output1Feedback },
+ // { "Output-2/fb", Output2Feedback }
+ // };
+ // }
+
+ // ///
+ // /// Factory method
+ // ///
+ // ///
+ // ///
+ // public static DmChassisControllerApi GetActionApiForDevice(DmChassisController dev)
+ // {
+ // return new DmChassisControllerApi(dev);
+ // }
+ //}
+
+
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs b/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs
new file mode 100644
index 00000000..22d2ec1c
--- /dev/null
+++ b/PepperDashEssentials/Bridges/DigitalLoggerBridge.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Devices.Common;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class DigitalLoggerApiExtensions
+ {
+ public static void LinkToApi(this DigitalLogger digitalLogger, BasicTriList trilist, uint joinStart, string joinMapKey)
+ {
+ var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DigitalLoggerJoinMap;
+
+ if (joinMap == null)
+ joinMap = new DigitalLoggerJoinMap();
+
+ joinMap.OffsetJoinNumbers(joinStart);
+ Debug.Console(1, digitalLogger, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+ for (uint i = 1; i <= digitalLogger.CircuitCount; i++)
+ {
+ var circuit = i;
+ digitalLogger.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
+ }
+ }
+ }
+ public class DigitalLoggerJoinMap : JoinMapBase
+ {
+ public uint IsOnline { get; set; }
+ public uint CircuitNames { get; set; }
+ public DigitalLoggerJoinMap()
+ {
+ // Digital
+ IsOnline = 1;
+
+ // Serial
+ CircuitNames = 1;
+ // Analog
+ }
+
+ public override void OffsetJoinNumbers(uint joinStart)
+ {
+ var joinOffset = joinStart - 1;
+
+ IsOnline = IsOnline + joinOffset;
+ CircuitNames = CircuitNames + joinOffset;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs
new file mode 100644
index 00000000..037a7a5b
--- /dev/null
+++ b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.DM;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class DmChassisControllerApiExtentions
+ {
+ public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey)
+ {
+ var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmChassisControllerJoinMap;
+
+ if (joinMap == null)
+ joinMap = new DmChassisControllerJoinMap();
+
+ joinMap.OffsetJoinNumbers(joinStart);
+
+ Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
+
+ // Link up outputs
+ for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs - 1; i++)
+ {
+ var ioSlot = i;
+
+ // Control
+ trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)));
+ trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)));
+
+ // Feedback
+ dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]);
+ dmChassis.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]);
+
+ dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
+
+ dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]);
+ dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]);
+ dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]);
+ dmChassis.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]);
+ dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
+ dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
+
+
+ }
+ }
+
+
+ public class DmChassisControllerJoinMap : JoinMapBase
+ {
+ public uint IsOnline { get; set; }
+ public uint OutputVideo { get; set; }
+ public uint OutputAudio { get; set; }
+ public uint VideoSyncStatus { get; set; }
+ public uint InputNames { get; set; }
+ public uint OutputNames { get; set; }
+ public uint OutputCurrentVideoInputNames { get; set; }
+ public uint OutputCurrentAudioInputNames { get; set; }
+ public uint InputCurrentResolution { get; set; }
+ public uint InputEndpointOnline { get; set; }
+ public uint OutputEndpointOnline { get; set; }
+ //public uint HdcpSupport { get; set; }
+ //public uint HdcpSupportCapability { get; set; }
+
+
+ public DmChassisControllerJoinMap()
+ {
+ IsOnline = 11;
+ OutputVideo = 100; //101-299
+ OutputAudio = 300; //301-499
+ VideoSyncStatus = 100; //101-299
+ InputNames = 100; //101-299
+ OutputNames = 300; //301-499
+ OutputCurrentVideoInputNames = 2000; //2001-2199
+ OutputCurrentAudioInputNames = 2200; //2201-2399
+ InputCurrentResolution = 2400; // 2401-2599
+ InputEndpointOnline = 500;
+ OutputEndpointOnline = 700;
+ //HdcpSupport = 1000; //1001-1199
+ //HdcpSupportCapability = 1200; //1201-1399
+
+ }
+
+ public override void OffsetJoinNumbers(uint joinStart)
+ {
+ var joinOffset = joinStart - 1;
+
+ IsOnline = IsOnline + joinOffset;
+ OutputVideo = OutputVideo + joinOffset;
+ OutputAudio = OutputAudio + joinOffset;
+ VideoSyncStatus = VideoSyncStatus + joinOffset;
+ InputNames = InputNames + joinOffset;
+ OutputNames = OutputNames + joinOffset;
+ OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset;
+ OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset;
+ InputCurrentResolution = InputCurrentResolution + joinOffset;
+ InputEndpointOnline = InputEndpointOnline + joinOffset;
+ OutputEndpointOnline = OutputEndpointOnline + joinOffset;
+ //HdcpSupport = HdcpSupport + joinOffset;
+ //HdcpSupportCapability = HdcpSupportCapability + joinOffset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs b/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs
new file mode 100644
index 00000000..318a3d0b
--- /dev/null
+++ b/PepperDashEssentials/Bridges/DmRmcControllerBridge.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.DM;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class DmRmcControllerApiExtensions
+ {
+ public static void LinkToApi(this DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey)
+ {
+ var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmRmcControllerJoinMap;
+
+ if (joinMap == null)
+ joinMap = new DmRmcControllerJoinMap();
+
+ joinMap.OffsetJoinNumbers(joinStart);
+
+ Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
+ if(rmc.VideoOutputResolutionFeedback != null)
+ rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution]);
+ if(rmc.EdidManufacturerFeedback != null)
+ rmc.EdidManufacturerFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidManufacturer]);
+ if(rmc.EdidNameFeedback != null)
+ rmc.EdidNameFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidName]);
+ if(rmc.EdidPreferredTimingFeedback != null)
+ rmc.EdidPreferredTimingFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidPrefferedTiming]);
+ if(rmc.EdidSerialNumberFeedback != null)
+ rmc.EdidSerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidSerialNumber]);
+ }
+
+ public class DmRmcControllerJoinMap : JoinMapBase
+ {
+ public uint IsOnline { get; set; }
+ public uint CurrentOutputResolution { get; set; }
+ public uint EdidManufacturer { get; set; }
+ public uint EdidName { get; set; }
+ public uint EdidPrefferedTiming { get; set; }
+ public uint EdidSerialNumber { get; set; }
+
+ public DmRmcControllerJoinMap()
+ {
+ // Digital
+ IsOnline = 1;
+
+ // Serial
+ CurrentOutputResolution = 1;
+ EdidManufacturer = 2;
+ EdidName = 3;
+ EdidPrefferedTiming = 4;
+ EdidSerialNumber = 5;
+ }
+
+ public override void OffsetJoinNumbers(uint joinStart)
+ {
+ var joinOffset = joinStart - 1;
+
+ IsOnline = IsOnline + joinOffset;
+ CurrentOutputResolution = CurrentOutputResolution + joinOffset;
+ EdidManufacturer = EdidManufacturer + joinOffset;
+ EdidName = EdidName + joinOffset;
+ EdidPrefferedTiming = EdidPrefferedTiming + joinOffset;
+ EdidSerialNumber = EdidSerialNumber + joinOffset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/DmTxControllerBridge.cs b/PepperDashEssentials/Bridges/DmTxControllerBridge.cs
new file mode 100644
index 00000000..26a6a939
--- /dev/null
+++ b/PepperDashEssentials/Bridges/DmTxControllerBridge.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.DM;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class DmTxControllerApiExtensions
+ {
+ public static void LinkToApi(this DmTxControllerBase tx, BasicTriList trilist, uint joinStart, string joinMapKey)
+ {
+ var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmTxControllerJoinMap;
+
+ if (joinMap == null)
+ joinMap = new DmTxControllerJoinMap();
+
+ joinMap.OffsetJoinNumbers(joinStart);
+
+ Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
+ tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus]);
+ tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution]);
+ //tx.HdcpSupportAllFeedback.LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportCapability]);
+
+ bool hdcpTypeSimple;
+
+ if (tx.Hardware is DmTx4kX02CBase || tx.Hardware is DmTx4kzX02CBase)
+ hdcpTypeSimple = false;
+ else
+ hdcpTypeSimple = true;
+
+ if (tx is ITxRouting)
+ {
+ var txR = tx as ITxRouting;
+
+ trilist.SetUShortSigAction(joinMap.VideoInput,
+ new Action(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video)));
+ trilist.SetUShortSigAction(joinMap.AudioInput,
+ new Action(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio)));
+
+ txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput]);
+ txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput]);
+
+ trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability;
+
+ if(txR.InputPorts[DmPortName.HdmiIn] != null)
+ {
+ var inputPort = txR.InputPorts[DmPortName.HdmiIn];
+
+ if (tx.Feedbacks["HdmiInHdcpCapability"] != null)
+ (tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
+
+ if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
+ {
+ var port = inputPort.Port as EndpointHdmiInput;
+
+ SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
+ }
+ }
+
+ if (txR.InputPorts[DmPortName.HdmiIn1] != null)
+ {
+ var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
+
+ if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null)
+ (tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
+
+ if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
+ {
+ var port = inputPort.Port as EndpointHdmiInput;
+
+ SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
+ }
+ }
+
+ if (txR.InputPorts[DmPortName.HdmiIn2] != null)
+ {
+ var inputPort = txR.InputPorts[DmPortName.HdmiIn2];
+
+ if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null)
+ (tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
+
+ if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
+ {
+ var port = inputPort.Port as EndpointHdmiInput;
+
+ SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState, trilist);
+ }
+ }
+
+ }
+ }
+
+ static void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
+ {
+ if (hdcpTypeSimple)
+ {
+ trilist.SetUShortSigAction(join,
+ new Action(s =>
+ {
+ if (s == 0)
+ {
+ port.HdcpSupportOff();
+ }
+ else if (s > 0)
+ {
+ port.HdcpSupportOn();
+ }
+ }));
+ }
+ else
+ {
+ trilist.SetUShortSigAction(join,
+ new Action(s =>
+ {
+ port.HdcpCapability = (eHdcpCapabilityType)s;
+ }));
+ }
+ }
+
+ public class DmTxControllerJoinMap : JoinMapBase
+ {
+ public uint IsOnline { get; set; }
+ public uint VideoSyncStatus { get; set; }
+ public uint CurrentInputResolution { get; set; }
+ public uint HdcpSupportCapability { get; set; }
+ public uint VideoInput { get; set; }
+ public uint AudioInput { get; set; }
+ public uint Port1HdcpState { get; set; }
+ public uint Port2HdcpState { get; set; }
+
+
+ public DmTxControllerJoinMap()
+ {
+ // Digital
+ IsOnline = 1;
+ VideoSyncStatus = 2;
+ // Serial
+ CurrentInputResolution = 1;
+ // Analog
+ VideoInput = 1;
+ AudioInput = 2;
+ HdcpSupportCapability = 3;
+ Port1HdcpState = 4;
+ Port2HdcpState = 5;
+ }
+
+ public override void OffsetJoinNumbers(uint joinStart)
+ {
+ var joinOffset = joinStart - 1;
+
+ IsOnline = IsOnline + joinOffset;
+ VideoSyncStatus = VideoSyncStatus + joinOffset;
+ CurrentInputResolution = CurrentInputResolution + joinOffset;
+ VideoInput = VideoInput + joinOffset;
+ AudioInput = AudioInput + joinOffset;
+ HdcpSupportCapability = HdcpSupportCapability + joinOffset;
+ Port1HdcpState = Port1HdcpState + joinOffset;
+ Port2HdcpState = Port2HdcpState + joinOffset;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs b/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs
new file mode 100644
index 00000000..230f7806
--- /dev/null
+++ b/PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class IBasicCommunicationApiExtensions
+ {
+ public static void LinkToApi(this GenericComm comm, BasicTriList trilist, uint joinStart, string joinMapKey)
+ {
+ var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as IBasicCommunicationJoinMap;
+
+ if (joinMap == null)
+ joinMap = new IBasicCommunicationJoinMap();
+
+ joinMap.OffsetJoinNumbers(joinStart);
+
+ if (comm.CommPort == null)
+ {
+ Debug.Console(1, comm, "Unable to link device '{0}'. CommPort is null", comm.Key);
+ return;
+ }
+
+ Debug.Console(1, comm, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ // this is a permanent event handler. This cannot be -= from event
+ comm.CommPort.TextReceived += (s, a) => trilist.SetString(joinMap.TextReceived, a.Text);
+ trilist.SetStringSigAction(joinMap.SendText, new Action(s => comm.CommPort.SendText(s)));
+ trilist.SetStringSigAction(joinMap.SetPortConfig + 1, new Action(s => comm.SetPortConfig(s)));
+
+
+ var sComm = comm.CommPort as ISocketStatus;
+ if (sComm != null)
+ {
+ sComm.ConnectionChange += (s, a) =>
+ {
+ trilist.SetUshort(joinMap.Status, (ushort)(a.Client.ClientStatus));
+ trilist.SetBool(joinMap.Connected, a.Client.ClientStatus ==
+ Crestron.SimplSharp.CrestronSockets.SocketStatus.SOCKET_STATUS_CONNECTED);
+ };
+
+ trilist.SetBoolSigAction(joinMap.Connect, new Action(b =>
+ {
+ if (b)
+ {
+ sComm.Connect();
+ }
+ else
+ {
+ sComm.Disconnect();
+ }
+ }));
+ }
+ }
+
+
+
+ public class IBasicCommunicationJoinMap : JoinMapBase
+ {
+ // Default joins
+ public uint TextReceived { get; set; }
+ public uint SendText { get; set; }
+ public uint SetPortConfig { get; set; }
+ public uint Connect { get; set; }
+ public uint Connected { get; set; }
+ public uint Status { get; set; }
+
+ public IBasicCommunicationJoinMap()
+ {
+ TextReceived = 1;
+ SendText = 1;
+ SetPortConfig = 2;
+ Connect = 1;
+ Connected = 1;
+ Status = 1;
+ }
+
+ public override void OffsetJoinNumbers(uint joinStart)
+ {
+ var joinOffset = joinStart - 1;
+
+ TextReceived = TextReceived + joinOffset;
+ SendText = SendText + joinOffset;
+ SetPortConfig = SetPortConfig + joinOffset;
+ Connect = Connect + joinOffset;
+ Connected = Connected + joinOffset;
+ Status = Status + joinOffset;
+ }
+ }
+ }
+ /////
+ /////
+ /////
+ //public static class DmChassisControllerApiExtensions
+ //{
+ // public static void LinkToApi(this PepperDash.Essentials.DM.DmChassisController chassis,
+ // BasicTriList trilist, Dictionary map, uint joinstart)
+ // {
+ // uint joinOffset = joinstart - 1;
+
+ // uint videoSelectOffset = 0 + joinOffset;
+ // uint audioSelectOffset = 40 + joinOffset;
+
+
+ // // loop chassis number of inupts
+ // for (uint i = 1; i <= chassis.Chassis.NumberOfOutputs; i++)
+ // {
+ // trilist.SetUShortSigAction(videoSelectOffset + i, new Action(u => chassis.ExecuteSwitch(u, i, eRoutingSignalType.Video)));
+ // trilist.SetUShortSigAction(audioSelectOffset + i, new Action(u => chassis.ExecuteSwitch(u, i, eRoutingSignalType.Audio)));
+ // }
+
+ // // wire up output change detection (try to add feedbacks or something to DMChassisController??
+
+ // // names?
+
+ // // HDCP?
+
+
+ // }
+ //}
+
+
+
+
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/Bridges/JoinMapBase.cs b/PepperDashEssentials/Bridges/JoinMapBase.cs
new file mode 100644
index 00000000..13d08a3f
--- /dev/null
+++ b/PepperDashEssentials/Bridges/JoinMapBase.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Bridges
+{
+ public static class JoinMapHelper
+ {
+ ///
+ /// Attempts to get the join map from config
+ ///
+ ///
+ ///
+ public static JoinMapBase GetJoinMapForDevice(string joinMapKey)
+ {
+ if (!string.IsNullOrEmpty(joinMapKey))
+ return null;
+
+ // FUTURE TODO: Get the join map from the ConfigReader.ConfigObject
+
+ return null;
+ }
+ }
+
+
+ public abstract class JoinMapBase
+ {
+ ///
+ /// Modifies all the join numbers by adding the offset. This should never be called twice
+ ///
+ ///
+ public abstract void OffsetJoinNumbers(uint joinStart);
+
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj
index 73c69cf1..d3f82782 100644
--- a/PepperDashEssentials/PepperDashEssentials.csproj
+++ b/PepperDashEssentials/PepperDashEssentials.csproj
@@ -105,10 +105,17 @@
+
+
+
+
+
+
+
diff --git a/essentials-framework b/essentials-framework
index 2ce1b084..676d4dc8 160000
--- a/essentials-framework
+++ b/essentials-framework
@@ -1 +1 @@
-Subproject commit 2ce1b0841bf590eb58669fc0b563d58bd310e19d
+Subproject commit 676d4dc8ac8e6d036d8e01a8efda4498103c9298