using System; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM { /// /// Represent both a transmitter and receiver pair of the HD-MD-400-C-E / HD-MD-300-C-E / HD-MD-200-C-E kits /// [Description("Wrapper class for all HD-MD variants")] public class HdMdxxxCEController : CrestronGenericBridgeableBaseDevice, IRouting//, IComPorts { /// ///// DmLite Ports ///// //public RoutingOutputPort ToRx { get; private set; } //public RoutingInputPort FromTx { get; private set; } public RoutingOutputPort HdmiOut { get; private set; } public HdMdxxxCE TxRxPair { get; private set; } public RoutingPortCollection InputPorts { get; private set; } /// /// The value of the current video source for the HDMI output on the receiver /// public IntFeedback VideoSourceFeedback { get; private set; } /// /// Indicates if Auto Route is on on the transmitter /// public BoolFeedback AutoRouteOnFeedback { get; private set; } /// /// Indicates if Priority Routing is on on the transmitter /// public BoolFeedback PriorityRoutingOnFeedback { get; private set; } /// /// INdicates if the On Screen Display is enabled /// public BoolFeedback InputOnScreenDisplayEnabledFeedback { get; private set; } /// /// Indicates if video sync is detected on each of the inputs /// public Dictionary SyncDetectedFeedbacks { get; private set; } /// /// Indicates if the remote end device is detected /// public BoolFeedback RemoteEndDetectedFeedback { get; private set; } public RoutingPortCollection OutputPorts { get { return new RoutingPortCollection { HdmiOut }; } } public HdMdxxxCEController(string key, string name, HdMdxxxCE txRxPair) :base(key, name, txRxPair) { TxRxPair = txRxPair; RemoteEndDetectedFeedback = new BoolFeedback(() => TxRxPair.RemoteEndDetectedOnFeedback.BoolValue); AutoRouteOnFeedback = new BoolFeedback(() => TxRxPair.TransmitterAutoModeOnFeedback.BoolValue); PriorityRoutingOnFeedback = new BoolFeedback(() => TxRxPair.PriorityRoutingOnFeedback.BoolValue); InputOnScreenDisplayEnabledFeedback = new BoolFeedback(() => TxRxPair.OnScreenDisplayEnabledFeedback.BoolValue); InputPorts = new RoutingPortCollection(); SyncDetectedFeedbacks = new Dictionary(); // Add the HDMI input port on the receiver InputPorts.Add(new RoutingInputPort(DmPortName.Hdmi, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 1, this)); SyncDetectedFeedbacks.Add(1, new BoolFeedback( () => TxRxPair.HdmiInputs[1].VideoDetectedFeedback.BoolValue)); if(txRxPair is HdMd400CE) { InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2, this)); SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 3, this)); SyncDetectedFeedbacks.Add(3, new BoolFeedback(() => TxRxPair.HdmiInputs[3].VideoDetectedFeedback.BoolValue)); InputPorts.Add(new RoutingInputPort(DmPortName.VgaIn, eRoutingSignalType.Video | eRoutingSignalType.Audio, eRoutingPortConnectionType.Vga, 4, this)); SyncDetectedFeedbacks.Add(4, new BoolFeedback(() => TxRxPair.VgaInputs[1].VideoDetectedFeedback.BoolValue)); // Set Ports for CEC InputPorts[DmPortName.HdmiIn1].Port = TxRxPair.HdmiInputs[1]; InputPorts[DmPortName.HdmiIn2].Port = TxRxPair.HdmiInputs[2]; } else if (txRxPair is HdMd300CE) { InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2, this)); SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); InputPorts.Add(new RoutingInputPort(DmPortName.VgaIn, eRoutingSignalType.Video | eRoutingSignalType.Audio, eRoutingPortConnectionType.Vga, 3, this)); SyncDetectedFeedbacks.Add(3, new BoolFeedback(() => TxRxPair.VgaInputs[1].VideoDetectedFeedback.BoolValue)); // Set Ports for CEC InputPorts[DmPortName.HdmiIn].Port = TxRxPair.HdmiInputs[1]; } else if (txRxPair is HdMd200CE || txRxPair is HdMd200C1GE) { InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2, this)); SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); // Set Ports for CEC InputPorts[DmPortName.HdmiIn].Port = TxRxPair.HdmiInputs[1]; } //ToRx = new RoutingOutputPort(DmPortName.ToTx, eRoutingSignalType.Audio | eRoutingSignalType.Video, // eRoutingPortConnectionType.DmCat, null, this); //FromTx = new RoutingInputPort(DmPortName.FromTx, eRoutingSignalType.Audio | eRoutingSignalType.Video, // eRoutingPortConnectionType.DmCat, null, this); HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this); OutputPorts[DmPortName.HdmiOut].Port = TxRxPair.HdmiOutputs[1]; TxRxPair.DMInputChange += new DMInputEventHandler(TxRxPair_DMInputChange); TxRxPair.DMOutputChange += new DMOutputEventHandler(TxRxPair_DMOutputChange); TxRxPair.DMSystemChange += new DMSystemEventHandler(TxRxPair_DMSystemChange); VideoSourceFeedback = new IntFeedback(() => (int)TxRxPair.HdmiOutputs[1].VideoOutFeedback.Number); } void TxRxPair_DMSystemChange(Switch device, DMSystemEventArgs args) { if (args.EventId == DMSystemEventIds.RemoteEndDetectedEventId) RemoteEndDetectedFeedback.FireUpdate(); else if (args.EventId == DMSystemEventIds.TransmitterAutoModeOnEventId) AutoRouteOnFeedback.FireUpdate(); else if (args.EventId == DMSystemEventIds.PriorityRoutingOnEventId) PriorityRoutingOnFeedback.FireUpdate(); else if (args.EventId == DMSystemEventIds.OnScreenDisplayEnabledEventId) InputOnScreenDisplayEnabledFeedback.FireUpdate(); } void TxRxPair_DMOutputChange(Switch device, DMOutputEventArgs args) { if (args.EventId == DMOutputEventIds.VideoOutEventId) VideoSourceFeedback.FireUpdate(); } void TxRxPair_DMInputChange(Switch device, DMInputEventArgs args) { if (args.EventId == DMInputEventIds.VideoDetectedEventId) SyncDetectedFeedbacks[args.Number].FireUpdate(); } public void AutoRouteOn() { TxRxPair.TransmitterAutoModeOn(); } public void AutoRouteOff() { TxRxPair.TransmitterAutoModeOff(); } public void PriorityRouteOn() { TxRxPair.PriorityRoutingOn(); } public void PriorityRouteOff() { TxRxPair.PriorityRoutingOff(); } public void OnScreenDisplayEnable() { TxRxPair.OnScreenDisplayEnabled(); } public void OnScreenDisplayDisable() { TxRxPair.OnScreenDisplayDisabled(); } public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { var number = Convert.ToUInt32(inputSelector); // Cast can sometimes fail var input = number == 0 ? null : TxRxPair.Inputs[number]; TxRxPair.HdmiOutputs[1].VideoOut = input; } // This device has a different class for com ports which will make it hard to implement IComPorts.... //#region IComPorts Members //public CrestronCollection ComPorts { get { return TxRxPair.ComPorts as CrestronCollection; } } //public int NumberOfComPorts { get { return 1; } } //#endregion public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { var joinMap = new HdMdxxxCEControllerJoinMap(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")); IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); RemoteEndDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RemoteEndDetected.JoinNumber]); trilist.SetSigTrueAction(joinMap.AutoRouteOn.JoinNumber, AutoRouteOn); AutoRouteOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutoRouteOn.JoinNumber]); trilist.SetSigTrueAction(joinMap.AutoRouteOff.JoinNumber, AutoRouteOff); AutoRouteOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.AutoRouteOff.JoinNumber]); trilist.SetSigTrueAction(joinMap.PriorityRoutingOn.JoinNumber, PriorityRouteOn); PriorityRoutingOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOn.JoinNumber]); trilist.SetSigTrueAction(joinMap.PriorityRoutingOff.JoinNumber, PriorityRouteOff); PriorityRoutingOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOff.JoinNumber]); trilist.SetSigTrueAction(joinMap.InputOnScreenDisplayEnabled.JoinNumber, OnScreenDisplayEnable); InputOnScreenDisplayEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayEnabled.JoinNumber]); trilist.SetSigTrueAction(joinMap.AutoRouteOff.JoinNumber, OnScreenDisplayDisable); InputOnScreenDisplayEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayDisabled.JoinNumber]); trilist.SetUShortSigAction(joinMap.VideoSource.JoinNumber, (i) => ExecuteSwitch(i, null, eRoutingSignalType.Video | eRoutingSignalType.Audio)); VideoSourceFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoSource.JoinNumber]); trilist.UShortInput[joinMap.SourceCount.JoinNumber].UShortValue = (ushort)InputPorts.Count; foreach (var input in InputPorts) { var number = Convert.ToUInt16(input.Selector); var numberJoin = (UInt16)(number - 1); SyncDetectedFeedbacks[number].LinkInputSig(trilist.BooleanInput[joinMap.SyncDetected.JoinNumber + numberJoin]); trilist.StringInput[joinMap.SourceNames.JoinNumber + numberJoin].StringValue = input.Key; } } } public class HdMdxxxCEPropertiesConfig { public ControlPropertiesConfig Control { get; set; } } public class HdMdxxxCEControllerFactory : EssentialsDeviceFactory { public HdMdxxxCEControllerFactory() { TypeNames = new List() { "hdmd400ce", "hdmd300ce", "hdmd200ce", "hdmd200c1ge"}; } public override EssentialsDevice BuildDevice(DeviceConfig dc) { var typeName = dc.Type.ToLower(); var key = dc.Key; var name = dc.Name; Debug.Console(1, "Factory Attempting to create new HD-MD Device"); var props = JsonConvert.DeserializeObject (dc.Properties.ToString()); if (typeName.Equals("hdmd400ce")) return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, new HdMd400CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); else if (typeName.Equals("hdmd300ce")) return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, new HdMd300CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); else if (typeName.Equals("hdmd200ce")) return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, new HdMd200CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); else if (typeName.Equals("hdmd200c1ge")) return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, new HdMd200C1GE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); else return null; } } }