diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs index b766ac3c..3d41af3a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using Newtonsoft.Json; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; @@ -15,421 +16,489 @@ using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM.Chassis { - [Description("Wrapper class for all HdMdNxM4E switchers")] - public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback - { - private HdMdNxM _Chassis; - private HdMd4x14kE _Chassis4x1; + [Description("Wrapper class for all HdMdNxM4E switchers")] + public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback + { + private HdMdNxM _Chassis; + private HdMd4x14kE _Chassis4x1; - //IroutingNumericEvent - public event EventHandler NumericSwitchChange; + //IroutingNumericEvent + public event EventHandler NumericSwitchChange; - public Dictionary InputNames { get; set; } - public Dictionary OutputNames { get; set; } + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } - public RoutingPortCollection InputPorts { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } - public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } - public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } - public FeedbackCollection InputNameFeedbacks { get; private set; } - public FeedbackCollection OutputNameFeedbacks { get; private set; } - public FeedbackCollection OutputRouteNameFeedbacks { get; private set; } - public FeedbackCollection InputHdcpEnableFeedback { get; private set; } - public FeedbackCollection DeviceNameFeedback { get; private set; } - public FeedbackCollection AutoRouteFeedback { get; private set; } + public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } + public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } + public FeedbackCollection InputNameFeedbacks { get; private set; } + public FeedbackCollection OutputNameFeedbacks { get; private set; } + public FeedbackCollection OutputRouteNameFeedbacks { get; private set; } + public FeedbackCollection InputHdcpEnableFeedback { get; private set; } + public StringFeedback DeviceNameFeedback { get; private set; } + public BoolFeedback AutoRouteFeedback { get; private set; } - #region Constructor + #region Constructor - public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis, - HdMdNxM4kEBridgeablePropertiesConfig props) - : base(key, name, chassis) - { - _Chassis = chassis; - var _props = props; + public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis, + HdMdNxM4kEBridgeablePropertiesConfig props) + : base(key, name, chassis) + { + _Chassis = chassis; + Name = name; - InputNames = props.Inputs; - OutputNames = props.Outputs; + if (props == null) + { + Debug.Console(1, this, "HdMdNx4keBridgeableController properties are null, failed to build the device"); + return; + } - VideoInputSyncFeedbacks = new FeedbackCollection(); - VideoOutputRouteFeedbacks = new FeedbackCollection(); - InputNameFeedbacks = new FeedbackCollection(); - OutputNameFeedbacks = new FeedbackCollection(); - OutputRouteNameFeedbacks = new FeedbackCollection(); - InputHdcpEnableFeedback = new FeedbackCollection(); - DeviceNameFeedback = new FeedbackCollection(); - AutoRouteFeedback = new FeedbackCollection(); - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); + if (props.Inputs != null) + { + foreach (var kvp in props.Inputs) + { + Debug.Console(1, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value); + } + InputNames = props.Inputs; + } + if (props.Outputs != null) + { + foreach (var kvp in props.Outputs) + { + Debug.Console(1, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value); + } + OutputNames = props.Outputs; + } - DeviceNameFeedback.Add(new StringFeedback(this.Name, () => this.Name)); + DeviceNameFeedback = new StringFeedback(()=>Name); - if (_Chassis.NumberOfInputs == 1) - { - _Chassis4x1 = _Chassis as HdMd4x14kE; - AutoRouteFeedback.Add(new BoolFeedback(this.Name + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue)); - } + VideoInputSyncFeedbacks = new FeedbackCollection(); + VideoOutputRouteFeedbacks = new FeedbackCollection(); + InputNameFeedbacks = new FeedbackCollection(); + OutputNameFeedbacks = new FeedbackCollection(); + OutputRouteNameFeedbacks = new FeedbackCollection(); + InputHdcpEnableFeedback = new FeedbackCollection(); + + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - var index = i; - var inputName = InputNames[index]; - _Chassis.Inputs[index].Name.StringValue = inputName; + if (_Chassis.NumberOfInputs == 1) + { + _Chassis4x1 = _Chassis as HdMd4x14kE; + AutoRouteFeedback = new BoolFeedback(() => _Chassis4x1.AutoModeOnFeedback.BoolValue); + } - InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) - { - FeedbackMatchObject = _Chassis.HdmiInputs[index] - }); - VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue)); - InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue)); - InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); - } + for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) + { + var index = i; + var inputName = InputNames[index]; + //_Chassis.Inputs[index].Name.StringValue = inputName; + _Chassis.HdmiInputs[index].Name.StringValue = inputName; - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - var index = i; - var outputName = OutputNames[index]; - _Chassis.Outputs[i].Name.StringValue = outputName; + InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, _Chassis.HdmiInputs[index], this) + { + FeedbackMatchObject = _Chassis.HdmiInputs[index] + }); + VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue)); + //InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue)); + InputNameFeedbacks.Add(new StringFeedback(inputName, () => InputNames[index])); + InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); + } - OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) - { - FeedbackMatchObject = _Chassis.HdmiOutputs[index] - }); - VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); - OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue)); - OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); - } + for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + { + var index = i; + var outputName = OutputNames[index]; + //_Chassis.Outputs[index].Name.StringValue = outputName; + //_Chassis.HdmiOutputs[index].Name.StringValue = outputName; - _Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); - _Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, _Chassis.HdmiOutputs[index], this) + { + FeedbackMatchObject = _Chassis.HdmiOutputs[index] + }); + VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); + OutputNameFeedbacks.Add(new StringFeedback(outputName, () => OutputNames[index])); + OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); + } - AddPostActivationAction(AddFeedbackCollections); - } + _Chassis.DMInputChange += Chassis_DMInputChange; + _Chassis.DMOutputChange += Chassis_DMOutputChange; - #endregion + AddPostActivationAction(AddFeedbackCollections); + } - #region Methods + #endregion - /// - /// Raise an event when the status of a switch object changes. - /// - /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType - private void OnSwitchChange(RoutingNumericEventArgs e) - { - var newEvent = NumericSwitchChange; - if (newEvent != null) newEvent(this, e); - } + #region Methods - public void EnableHdcp(uint port) - { - if (port > _Chassis.NumberOfInputs) return; - if (port <= 0) return; + /// + /// Raise an event when the status of a switch object changes. + /// + /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType + private void OnSwitchChange(RoutingNumericEventArgs e) + { + var newEvent = NumericSwitchChange; + if (newEvent != null) newEvent(this, e); + } - _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } + public void EnableHdcp(uint port) + { + if (port > _Chassis.NumberOfInputs) return; + if (port <= 0) return; - public void DisableHdcp(uint port) - { - if (port > _Chassis.NumberOfInputs) return; - if (port <= 0) return; + _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } - _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } + public void DisableHdcp(uint port) + { + if (port > _Chassis.NumberOfInputs) return; + if (port <= 0) return; - public void EnableAutoRoute() - { - if (_Chassis.NumberOfInputs != 1) return; + _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } - if (_Chassis4x1 == null) return; + public void EnableAutoRoute() + { + if (_Chassis.NumberOfInputs != 1) return; - _Chassis4x1.AutoModeOn(); - } + if (_Chassis4x1 == null) return; - public void DisableAutoRoute() - { - if (_Chassis.NumberOfInputs != 1) return; + _Chassis4x1.AutoModeOn(); + } - if (_Chassis4x1 == null) return; + public void DisableAutoRoute() + { + if (_Chassis.NumberOfInputs != 1) return; - _Chassis4x1.AutoModeOff(); - } + if (_Chassis4x1 == null) return; - #region PostActivate + _Chassis4x1.AutoModeOff(); + } - public void AddFeedbackCollections() - { - AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); - AddCollectionsToList(VideoOutputRouteFeedbacks); - AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback); - } + #region PostActivate - #endregion + public void AddFeedbackCollections() + { + AddFeedbackToList(DeviceNameFeedback); + AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); + AddCollectionsToList(VideoOutputRouteFeedbacks); + AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks); + } - #region FeedbackCollection Methods + #endregion - //Add arrays of collections - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } + #region FeedbackCollection Methods - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } + //Add arrays of collections + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } - //Add Collections - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } - AddFeedbackToList(f); - } - } + //Add Collections + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; + AddFeedbackToList(f); + } + } - AddFeedbackToList(f); - } - } + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; + AddFeedbackToList(f); + } + } - AddFeedbackToList(f); - } - } + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; - //Add Individual Feedbacks - public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb) - { - if (newFb == null) return; + AddFeedbackToList(f); + } + } - if (!Feedbacks.Contains(newFb)) - { - Feedbacks.Add(newFb); - } - } + //Add Individual Feedbacks + public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb) + { + if (newFb == null) return; - #endregion + if (!Feedbacks.Contains(newFb)) + { + Feedbacks.Add(newFb); + } + } - #region IRouting Members + #endregion - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - // Try to make switch only when necessary. The unit appears to toggle when already selected. - var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut; - if (current != _Chassis.HdmiInputs[(uint)inputSelector]) - _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector]; - } + #region IRouting Members - #endregion + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + var input = inputSelector as HdMdNxMHdmiInput; //changed from HdMdNxM4kzEHdmiInput; + var output = outputSelector as HdMdNxMHdmiOutput; + Debug.Console(2, this, "ExecuteSwitch: input={0} output={1}", input, output); - #region IRoutingNumeric Members + if (output == null) + { + Debug.Console(0, this, "Unable to make switch. output selector is not HdMdNxMHdmiOutput"); + return; + } - public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) - { - ExecuteSwitch(inputSelector, outputSelector, signalType); - } + // Try to make switch only when necessary. The unit appears to toggle when already selected. + var current = output.VideoOut; + if (current != input) + output.VideoOut = input; + } - #endregion + #endregion - #endregion + #region IRoutingNumeric Members - #region Bridge Linking + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) + { + var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector]; + var output = _Chassis.HdmiOutputs[outputSelector]; - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart); + Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output); - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + ExecuteSwitch(input, output, signalType); + } - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + #endregion - 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."); - } + #endregion - IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); + #region Bridge Linking + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new HdMdNxM4kEControllerJoinMap(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."); + } + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + DeviceNameFeedback.LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); + + if (_Chassis4x1 != null) + { + trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn()); + trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff()); + AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); + } + + for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) + { + var joinIndex = i - 1; + var input = i; + //Digital + VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[input]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); + trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(input)); + trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(input)); + + //Serial + InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); + } + + for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + { + var joinIndex = i - 1; + var output = i; + //Analog + VideoOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); + trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); + + //Serial + OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); + OutputRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); + } + + _Chassis.OnlineStatusChange += Chassis_OnlineStatusChange; + + trilist.OnlineStatusChange += (d, args) => + { + if (!args.DeviceOnLine) return; + + // feedback updates was moved to the Chassis_OnlineStatusChange + // due to the amount of time it takes for the device to come online + }; + } + + + #endregion + + #region Events + + void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) + { + IsOnline.FireUpdate(); + + if (!args.DeviceOnLine) return; + + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } if (_Chassis4x1 != null) - { - trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn()); - trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff()); - AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); - } + AutoRouteFeedback.FireUpdate(); + } - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - var joinIndex = i - 1; - //Digital - VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); - trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i)); - trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i)); + void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) + { + if (args.EventId != DMOutputEventIds.VideoOutEventId) return; - //Serial - InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); - } + var output = args.Number; - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - var joinIndex = i - 1; - //Analog - VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); - trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo)); + var inputNumber = _Chassis.HdmiOutputs[output].VideoOutFeedback == null + ? 0 + : _Chassis.HdmiOutputs[output].VideoOutFeedback.Number; - //Serial - OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); - OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); - } + var outputName = OutputNames[output]; - _Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange); + var feedback = VideoOutputRouteFeedbacks[outputName]; - trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => - { - if (args.DeviceOnLine) - { - foreach (var feedback in Feedbacks) + if (feedback == null) + { + return; + } + var inPort = + InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output].VideoOutFeedback); + var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output]); + + feedback.FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.AudioVideo)); + } + + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { + switch (args.EventId) + { + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", args.EventId); + foreach (var item in VideoInputSyncFeedbacks) { - feedback.FireUpdate(); + item.FireUpdate(); } - } - }); - } + break; + } + case DMInputEventIds.InputNameFeedbackEventId: + case DMInputEventIds.InputNameEventId: + case DMInputEventIds.NameFeedbackEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId); + Debug.Console(1, this, "Input {0} Name {1}", args.Number, + _Chassis.HdmiInputs[args.Number].NameFeedback.StringValue); + foreach (var item in InputNameFeedbacks) + { + item.FireUpdate(); + } + break; + } + default: + { + Debug.Console(1, this, "Unhandled DM Input Event ID {0}", args.EventId); + break; + } + } + } + + #endregion + + #region Factory + + public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory + { + public HdMdNxM4kEControllerFactory() + { + TypeNames = new List() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + var type = dc.Type.ToLower(); + var control = props.Control; + var ipid = control.IpIdInt; + var address = control.TcpSshProperties.Address; + + switch (type) + { + case ("hdmd4x14ke-bridgeable"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props); + case ("hdmd4x24ke"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props); + case ("hdmd6x24ke"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props); + default: + return null; + } + } + } + + #endregion - #endregion - #region Events - - void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) - { - if (!args.DeviceOnLine) return; - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - _Chassis.Inputs[i].Name.StringValue = InputNames[i]; - } - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - _Chassis.Outputs[i].Name.StringValue = OutputNames[i]; - } - - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } - } - - void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) - { - if (args.EventId != DMOutputEventIds.VideoOutEventId) return; - - for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) - { - var index = i; - var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback); - var localOutputPort = - OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]); - - - VideoOutputRouteFeedbacks[i].FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); - } - } - - void Chassis_DMInputChange(Switch device, DMInputEventArgs args) - { - if (args.EventId != DMInputEventIds.VideoDetectedEventId) return; - foreach (var item in VideoInputSyncFeedbacks) - { - item.FireUpdate(); - } - } - - #endregion - - #region Factory - - public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory - { - public HdMdNxM4kEControllerFactory() - { - TypeNames = new List() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device"); - - var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); - - var type = dc.Type.ToLower(); - var control = props.Control; - var ipid = control.IpIdInt; - var address = control.TcpSshProperties.Address; - - switch (type) - { - case ("hdmd4x14ke-bridgeable"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props); - case ("hdmd4x24ke"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props); - case ("hdmd6x24ke"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props); - default: - return null; - } - } - } - - #endregion - - - - } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs index 57c52627..b47139e2 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DM; using Newtonsoft.Json; @@ -13,6 +14,7 @@ using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM.Chassis { + [Obsolete("Please use HdMdNxM4kEBridgeable Controller")] public class HdMdNxM4kEController : CrestronGenericBaseDevice, IRoutingInputsOutputs, IRouting { public HdMdNxM Chassis { get; private set; } @@ -31,6 +33,7 @@ namespace PepperDash.Essentials.DM.Chassis HdMdNxM4kEPropertiesConfig props) : base(key, name, chassis) { + Debug.Console(0, this, "Type hdmd4x14ke is obsolete. Please use hdmd4x14ke-bridgeable"); Chassis = chassis; // logical ports @@ -43,14 +46,19 @@ namespace PepperDash.Essentials.DM.Chassis OutputPorts = new RoutingPortCollection(); OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this)); - + // physical settings if (props != null && props.Inputs != null) { + var inputRegex = new Regex(@"(?\d)", RegexOptions.IgnoreCase); foreach (var kvp in props.Inputs) { - // strip "hdmiIn" - var inputNum = Convert.ToUInt32(kvp.Key.Substring(6)); + // get numnbers from key and convert to int + //var inputNum = Convert.ToUInt32(kvp.Key.Substring(6)); + var inputMatch = inputRegex.Match(kvp.Key); + if (inputMatch == null) continue; + + var inputNum = Convert.ToUInt32(inputMatch.Groups["InputNum"].Value); var port = chassis.HdmiInputs[inputNum].HdmiInputPort; // set hdcp disables