From 759fb1d72949bd88e76cc071249740eb6399327e Mon Sep 17 00:00:00 2001 From: jdevito Date: Wed, 6 Sep 2023 11:22:19 -0500 Subject: [PATCH 1/7] feature: adds support for HdSpXxx switchers WIP: added support for HD-PS401, HD-PS402, HD-PS621 and HD-PS622, pending testing with device. --- .../JoinMaps/HdPsXxxControllerJoinMap.cs | 190 ++++++ .../PepperDash_Essentials_Core.csproj | 1 + .../Chassis/HdPsXxxController.cs | 637 ++++++++++++++++++ .../Config/HdPsXxxPropertiesConfig.cs | 18 + .../PepperDash_Essentials_DM.csproj | 2 + 5 files changed, 848 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs new file mode 100644 index 00000000..3f2901c9 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs @@ -0,0 +1,190 @@ +using System; +using PepperDash.Essentials.Core; + +namespace PepperDash_Essentials_Core.Bridges +{ + public class HdPsXxxControllerJoinMap : JoinMapBaseAdvanced + { + + #region Digital + + [JoinName("EnableAutoRoute")] + public JoinDataComplete EnableAutoRoute = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Enable Automatic Routing on Xx1 Switchers", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("InputSync")] + public JoinDataComplete InputSync = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 8 + }, + new JoinMetadata + { + Description = "Device Input Sync", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("EnableInputHdcp")] + public JoinDataComplete EnableInputHdcp = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 8 + }, + new JoinMetadata + { + Description = "Device Enable Input Hdcp", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("DisableInputHdcp")] + public JoinDataComplete DisableInputHdcp = new JoinDataComplete( + new JoinData + { + JoinNumber = 21, + JoinSpan = 8 + }, + new JoinMetadata + { + Description = "Device Disnable Input Hdcp", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 30, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Device Onlne", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + + #region Analog + + [JoinName("OutputRoute")] + public JoinDataComplete OutputRoute = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 2 + }, + new JoinMetadata + { + Description = "Device Output Route Set/Get", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + #endregion + + + #region Serial + + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Device Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + [JoinName("InputName")] + public JoinDataComplete InputName = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 8 + }, + new JoinMetadata + { + Description = "Device Input Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + [JoinName("OutputName")] + public JoinDataComplete OutputName = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 2 + }, + new JoinMetadata + { + Description = "Device Output Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + [JoinName("OutputRoutedName")] + public JoinDataComplete OutputRoutedName = new JoinDataComplete( + new JoinData + { + JoinNumber = 16, + JoinSpan = 2 + }, + new JoinMetadata + { + Description = "Device Output Route Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + #endregion + + /// + /// Constructor to use when instantiating this join map without inheriting from it + /// + /// Join this join map will start at + public HdPsXxxControllerJoinMap(uint joinStart) + : this(joinStart, typeof(HdPsXxxControllerJoinMap)) + { + } + + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + protected HdPsXxxControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 75d4626d..0d9aa9bc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -127,6 +127,7 @@ + diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs new file mode 100644 index 00000000..78da7a7b --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -0,0 +1,637 @@ +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 Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; +using PepperDash_Essentials_Core.Bridges; +using PepperDash_Essentials_DM.Config; + +namespace PepperDash_Essentials_DM.Chassis +{ + [Description("Wrapper class for all HdPsXxx switchers")] + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback + { + + private readonly HdPsXxx _chassis; + private readonly HdPs401 _chassis401; + private readonly HdPs621 _chassis621; + + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } + + public FeedbackCollection InputNameFeedbacks { get; private set; } + public FeedbackCollection InputHdcpEnableFeedback { get; private set; } + + public FeedbackCollection OutputNameFeedbacks { get; private set; } + public FeedbackCollection OutputRouteNameFeedback { get; private set; } + + public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } + public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } + + public StringFeedback DeviceNameFeedback { get; private set; } + public BoolFeedback AutoRouteFeedback { get; private set; } + + public event EventHandler NumericSwitchChange; + + /// + /// Constructor + /// + /// + /// + /// HdPs401 device instance + /// + public HdPsXxxController(string key, string name, HdPsXxx chassis, HdPsXxxPropertiesConfig props) + : base(key, name) + { + _chassis = chassis; + Name = name; + + if (props == null) + { + Debug.Console(1, this, "HdPsXxxController properties are null, failed to build device"); + return; + } + + InputPorts = new RoutingPortCollection(); + InputNames = new Dictionary(); + InputNameFeedbacks = new FeedbackCollection(); + InputHdcpEnableFeedback = new FeedbackCollection(); + + OutputPorts = new RoutingPortCollection(); + OutputNames = new Dictionary(); + OutputNameFeedbacks = new FeedbackCollection(); + OutputRouteNameFeedback = new FeedbackCollection(); + + VideoInputSyncFeedbacks = new FeedbackCollection(); + VideoOutputRouteFeedbacks = new FeedbackCollection(); + + if (_chassis.NumberOfOutputs == 1) + { + if (_chassis is HdPs401) + _chassis401 = _chassis as HdPs401; + if (_chassis is HdPs621) + _chassis621 = _chassis as HdPs621; + + AutoRouteFeedback = new BoolFeedback(() => _chassis401.PriorityRouteOnFeedback.BoolValue); + } + + SetupInputs(props.Inputs); + SetupOutputs(props.Outputs); + + AddPostActivationAction(AddFeedbackCollecitons); + } + + // input setup + private void SetupInputs(Dictionary dict) + { + InputNames = dict; + + for (uint i = 1; i <= _chassis.NumberOfInputs; i++) + { + var index = i; + var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("Input {0}", index) : InputNames[index]; + var input = _chassis.Inputs[index]; + var hdmiInput = _chassis.HdmiInputs[index]; + var dmLiteInput = _chassis.DmLiteInputs[index]; + + InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); + + // TODO [ ] verify which input type is needed + input.Name.StringValue = name; + hdmiInput.Name.StringValue = name; + dmLiteInput.Name.StringValue = name; + + var port = new RoutingInputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) + { + FeedbackMatchObject = input + }; + InputPorts.Add(port); + + InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => hdmiInput.InputPort.HdcpSupportOnFeedback.BoolValue)); + + VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + } + + _chassis.DMInputChange += _chassis_InputChange; + } + + // output setup + private void SetupOutputs(Dictionary dict) + { + OutputNames = dict; + + for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) + { + var index = i; + var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) : OutputNames[index]; + var output = _chassis.Outputs[index]; + var hdmiDmLiteOutput = _chassis.HdmiDmLiteOutputs[index]; + + OutputNameFeedbacks.Add(new StringFeedback(name, () => OutputNames[index])); + + // TODO [ ] verify which output type is needed + output.Name.StringValue = name; + hdmiDmLiteOutput.Name.StringValue = name; + + var port = new RoutingOutputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) + { + FeedbackMatchObject = output + }; + OutputPorts.Add(port); + + OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); + + VideoOutputRouteFeedbacks.Add(new IntFeedback(name, () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); + } + + _chassis.DMOutputChange += _chassis_OutputChange; + } + + + #region BridgeLinking + + /// + /// Link device to API + /// + /// + /// + /// + /// + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new HdPsXxxControllerJoinMap(joinStart); + + 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]); + + _chassis.OnlineStatusChange += _chassis_OnlineStatusChange; + + if (_chassis401 != null) LinkChassis401ToApi(trilist, joinMap); + + if (_chassis621 != null) LinkChassis621ToApi(trilist, joinMap); + + LinkChassisInputsToApi(trilist, joinMap); + LinkChassisOutputsToApi(trilist, joinMap); + + trilist.OnlineStatusChange += (sender, args) => + { + if (!args.DeviceOnLine) return; + }; + } + + + // links inputs to API + private void LinkChassisInputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) + { + for (uint i = 1; i <= _chassis.NumberOfInputs; i++) + { + var input = i; + var inputName = InputNames[input]; + var indexWithOffset = input - 1; + + trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + indexWithOffset, () => EnableHdcp(input)); + trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + indexWithOffset, () => DisableHdcp(input)); + + InputHdcpEnableFeedback[inputName].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]); + InputHdcpEnableFeedback[inputName].LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]); + + VideoInputSyncFeedbacks[inputName].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + indexWithOffset]); + + InputNameFeedbacks[inputName].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + indexWithOffset]); + } + } + + + // links outputs to API + private void LinkChassisOutputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) + { + for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) + { + var output = i; + var outputName = OutputNames[output]; + var indexWithOffset = output - 1; + + trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + indexWithOffset, (a) => + ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); + + OutputNameFeedbacks[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + indexWithOffset]); + OutputRouteNameFeedback[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + indexWithOffset]); + + VideoOutputRouteFeedbacks[outputName].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + indexWithOffset]); + } + } + + + // links HdPs401 chassis to API + private void LinkChassis401ToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) + { + trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis401.AutoRouteOn()); + trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis401.AutoRouteOff()); + + AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); + } + + + // links HdPs621 chassis to API + private void LinkChassis621ToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) + { + trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis621.AutoRouteOn()); + trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis621.AutoRouteOff()); + + AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); + } + + + #endregion + + + /// + /// Executes a device switch using objects + /// + /// + /// + /// + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + var input = inputSelector as HdPsXxxHdmiInput; + var output = outputSelector as HdPsXxxHdmiOutput; + + Debug.Console(2, this, "ExecuteSwitch: input={0}, output={1}", input, output); + + if (output == null) + { + Debug.Console(0, this, "Unable to make switch, output selector is not HdPsXxxHdmiOutput"); + return; + } + + // TODO [ ] Validate if sending the same input toggles the switch + var current = output.VideoOut; + if (current != input) + output.VideoOut = input; + } + + + /// + /// Executes a device switch using numeric values + /// + /// + /// + /// + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) + { + var input = inputSelector == 0 ? null : _chassis.Inputs[inputSelector]; + var output = _chassis.Outputs[outputSelector]; + + Debug.Console(2, this, "ExecuteNumericSwitch: input={0}, output={1}", input, output); + + ExecuteSwitch(input, output, signalType); + } + + + /// + /// Enables Hdcp on the provided port + /// + /// + public void EnableHdcp(uint port) + { + if (port <= 0 || port > _chassis.NumberOfInputs) return; + + _chassis.HdmiInputs[port].InputPort.HdcpSupportOn(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } + + + /// + /// Disables Hdcp on the provided port + /// + /// + public void DisableHdcp(uint port) + { + if (port <= 0 || port > _chassis.NumberOfInputs) return; + + _chassis.HdmiInputs[port].InputPort.HdcpSupportOff(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } + + + /// + /// Enables switcher auto route + /// + public void EnableAutoRoute() + { + if (_chassis.NumberOfInputs != 1) return; + + if (_chassis401 != null) + { + _chassis401.AutoRouteOn(); + } + + if (_chassis621 != null) + { + _chassis621.AutoRouteOn(); + } + } + + + /// + /// Disables switcher auto route + /// + public void DisableAutoRoute() + { + if (_chassis.NumberOfInputs != 1) return; + + if (_chassis401 != null) + { + _chassis401.AutoRouteOff(); + } + + if (_chassis621 != null) + { + _chassis621.AutoRouteOff(); + } + } + + #region Events + + + // _chassis online/offline event + private void _chassis_OnlineStatusChange(GenericBase currentDevice, + OnlineOfflineEventArgs args) + { + IsOnline.FireUpdate(); + + if (!args.DeviceOnLine) return; + + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } + } + + + // _chassis input change event + private void _chassis_InputChange(Switch device, DMInputEventArgs args) + { + var eventId = args.EventId; + + switch (eventId) + { + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", eventId); + foreach (var item in VideoInputSyncFeedbacks) + { + item.FireUpdate(); + } + break; + } + case DMInputEventIds.InputNameFeedbackEventId: + case DMInputEventIds.InputNameEventId: + case DMInputEventIds.NameFeedbackEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating name feedbacks", eventId); + + var input = args.Number; + var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; + + Debug.Console(1, this, "Input {0} Name {1}", input, name); + break; + } + default: + { + Debug.Console(1, this, "Uhandled DM Input Event ID {0}", eventId); + break; + } + } + } + + + // _chassis output change event + private void _chassis_OutputChange(Switch device, DMOutputEventArgs args) + { + if (args.EventId != DMOutputEventIds.VideoOutEventId) return; + + var output = args.Number; + + var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null + ? 0 + : _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback.Number; + + var outputName = OutputNames[output]; + + var feedback = VideoOutputRouteFeedbacks[outputName]; + if (feedback == null) return; + + var inputPort = InputPorts.FirstOrDefault( + p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback); + + var outputPort = OutputPorts.FirstOrDefault( + p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output]); + + feedback.FireUpdate(); + + OnSwitchChange(new RoutingNumericEventArgs( + output, input, outputPort, inputPort, eRoutingSignalType.AudioVideo)); + } + + + /// + /// Raise an event when the status of a switch object changes. + /// + /// Argumetns defined as IKeyName sender, output, input, & eRoutingSignalType + private void OnSwitchChange(RoutingNumericEventArgs args) + { + var newEvent = NumericSwitchChange; + if (newEvent != null) newEvent(this, args); + } + + + #endregion + + + #region FeedbacksAndFeedbackCollections + + + /// + /// Add feedback colleciton arrays to feedback collections + /// + /// BoolFeedback[] arrays + public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) + { + foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) + { + AddCollectionsToList(item); + } + } + + + /// + /// Add feedback colleciton arrays to feedback collections + /// + /// IntFeedback[] arrays + public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) + { + foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) + { + AddCollectionsToList(item); + } + } + + + /// + /// Add feedback colleciton arrays to feedback collections + /// + /// StringFeedback[] arrays + public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) + { + foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) + { + AddCollectionsToList(item); + } + } + + + /// + /// Adds feedback colleciton to feedback collections + /// + /// BoolFeedback + public void AddCollectionToList(FeedbackCollection feedbackCollection) + { + foreach (var item in feedbackCollection.Where(item => item != null)) + { + AddFeedbackToList(item); + } + } + + + /// + /// Adds feedback colleciton to feedback collections + /// + /// IntFeedback + public void AddCollectionToList(FeedbackCollection feedbackCollection) + { + foreach (var item in feedbackCollection.Where(item => item != null)) + { + AddFeedbackToList(item); + } + } + + + /// + /// Adds feedback colleciton to feedback collections + /// + /// StringFeedback + public void AddCollectionToList(FeedbackCollection feedbackCollection) + { + foreach (var item in feedbackCollection.Where(item => item != null)) + { + AddFeedbackToList(item); + } + } + + + /// + /// Adds individual feedbacks to feedback collection + /// + /// Feedback + public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback fb) + { + if (fb == null || Feedbacks.Contains(fb)) return; + + Feedbacks.Add(fb); + } + + + /// + /// Adds provided feedbacks to feedback collection list + /// + public void AddFeedbackCollecitons() + { + AddFeedbackToList(DeviceNameFeedback); + AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); + AddCollectionsToList(VideoOutputRouteFeedbacks); + AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedback); + } + + + #endregion + + + #region Factory + + + public class HdSp401ControllerFactory : EssentialsDeviceFactory + { + public HdSp401ControllerFactory() + { + TypeNames = new List() { "hdsp401", "hdsp402", "hdsp621", "hdsp622" }; + } + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new HD-PSXxx device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + if (props == null) + { + Debug.Console(1, "Factory failed to create new HD-PSXxx device, properties config was null"); + return null; + } + + var key = dc.Key; + var name = dc.Name; + var type = dc.Type.ToLower(); + var control = props.Control; + var ipid = control.IpIdInt; + var address = control.TcpSshProperties.Address; + + switch (type) + { + case ("hdps401"): + { + return new HdPsXxxController(key, name, new HdPs401(ipid, Global.ControlSystem), props); + } + case ("hdsp402"): + { + return new HdPsXxxController(key, name, new HdPs402(ipid, Global.ControlSystem), props); + } + case ("hdsp621"): + { + return new HdPsXxxController(key, name, new HdPs621(ipid, Global.ControlSystem), props); + } + case ("hdsp622"): + { + return new HdPsXxxController(key, name, new HdPs622(ipid, Global.ControlSystem), props); + } + default: + { + Debug.Console(1, "Factory failed to create new {0} device", type); + return null; + } + } + } + } + + + #endregion + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs new file mode 100644 index 00000000..b521facf --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using PepperDash.Core; + +namespace PepperDash_Essentials_DM.Config +{ + public class HdPsXxxPropertiesConfig + { + [JsonProperty("control")] + public ControlPropertiesConfig Control { get; set; } + + [JsonProperty("inputs")] + public Dictionary Inputs { get; set; } + + [JsonProperty("outputs")] + public Dictionary Outputs { get; set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj index adfddbe3..0011c305 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -104,6 +104,8 @@ + + From b06d0c0debd2a75245f2105b563625dc5f45758f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 7 Sep 2023 18:37:21 -0500 Subject: [PATCH 2/7] fix: resolves typo of hdpsXxx type name in the factory --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 78da7a7b..499dd865 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -52,7 +52,7 @@ namespace PepperDash_Essentials_DM.Chassis /// HdPs401 device instance /// public HdPsXxxController(string key, string name, HdPsXxx chassis, HdPsXxxPropertiesConfig props) - : base(key, name) + : base(key, name, chassis) { _chassis = chassis; Name = name; @@ -584,7 +584,7 @@ namespace PepperDash_Essentials_DM.Chassis { public HdSp401ControllerFactory() { - TypeNames = new List() { "hdsp401", "hdsp402", "hdsp621", "hdsp622" }; + TypeNames = new List() { "hdps401", "hdps402", "hdps621", "hdps622" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) { @@ -610,15 +610,15 @@ namespace PepperDash_Essentials_DM.Chassis { return new HdPsXxxController(key, name, new HdPs401(ipid, Global.ControlSystem), props); } - case ("hdsp402"): + case ("hdps402"): { return new HdPsXxxController(key, name, new HdPs402(ipid, Global.ControlSystem), props); } - case ("hdsp621"): + case ("hdps621"): { return new HdPsXxxController(key, name, new HdPs621(ipid, Global.ControlSystem), props); } - case ("hdsp622"): + case ("hdps622"): { return new HdPsXxxController(key, name, new HdPs622(ipid, Global.ControlSystem), props); } From d74c5de65130c1fe03db44394a65b9dc3cb96c64 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 8 Sep 2023 10:51:19 -0500 Subject: [PATCH 3/7] wip: updates to HdPsXxx class while test implementation to resolve exceptions --- .../Chassis/HdPsXxxController.cs | 28 ++++++++++++++++--- .../Config/HdPsXxxPropertiesConfig.cs | 14 +++++++++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 499dd865..d923949e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -63,15 +63,17 @@ namespace PepperDash_Essentials_DM.Chassis return; } - InputPorts = new RoutingPortCollection(); - InputNames = new Dictionary(); + InputPorts = new RoutingPortCollection(); InputNameFeedbacks = new FeedbackCollection(); InputHdcpEnableFeedback = new FeedbackCollection(); + InputNames = new Dictionary(); + //InputNames = props.Inputs; OutputPorts = new RoutingPortCollection(); - OutputNames = new Dictionary(); OutputNameFeedbacks = new FeedbackCollection(); OutputRouteNameFeedback = new FeedbackCollection(); + OutputNames = new Dictionary(); + //OutputNames = props.Outputs; VideoInputSyncFeedbacks = new FeedbackCollection(); VideoOutputRouteFeedbacks = new FeedbackCollection(); @@ -95,6 +97,15 @@ namespace PepperDash_Essentials_DM.Chassis // input setup private void SetupInputs(Dictionary dict) { + if (dict == null) + { + Debug.Console(1, this, "Failed to setup inputs, properties are null"); + return; + } + foreach (var kvp in dict) + { + Debug.Console(1, this, "props.Input[{0}]: {1}", kvp.Key, kvp.Value); + } InputNames = dict; for (uint i = 1; i <= _chassis.NumberOfInputs; i++) @@ -129,6 +140,15 @@ namespace PepperDash_Essentials_DM.Chassis // output setup private void SetupOutputs(Dictionary dict) { + if (dict == null) + { + Debug.Console(1, this, "Failed to setup outputs, properties are null"); + return; + } + foreach (var kvp in dict) + { + Debug.Console(1, this, "props.Output[{0}]: {1}", kvp.Key, kvp.Value); + } OutputNames = dict; for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) @@ -602,7 +622,7 @@ namespace PepperDash_Essentials_DM.Chassis var type = dc.Type.ToLower(); var control = props.Control; var ipid = control.IpIdInt; - var address = control.TcpSshProperties.Address; + //var address = control.TcpSshProperties.Address; switch (type) { diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs index b521facf..c02fc511 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using PepperDash.Core; +using PepperDash.Essentials.DM.Config; namespace PepperDash_Essentials_DM.Config { @@ -10,9 +11,20 @@ namespace PepperDash_Essentials_DM.Config public ControlPropertiesConfig Control { get; set; } [JsonProperty("inputs")] + //public Dictionary Inputs { get; set; } public Dictionary Inputs { get; set; } [JsonProperty("outputs")] - public Dictionary Outputs { get; set; } + //public Dictionary Outputs { get; set; } + public Dictionary Outputs { get; set; } + + public HdPsXxxPropertiesConfig() + { + //Inputs = new Dictionary(); + //Outputs = new Dictionary(); + + Inputs = new Dictionary(); + Outputs = new Dictionary(); + } } } \ No newline at end of file From 527457baf54d557f5c5991330335d0be894165b2 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 8 Sep 2023 13:00:27 -0500 Subject: [PATCH 4/7] refactor(wip): MPC3 class refactor constructor --- PepperDashEssentials/ControlSystem.cs | 48 ++-- .../Touchpanels/Mpc3Touchpanel.cs | 231 +++++++++++------- 2 files changed, 169 insertions(+), 110 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index f24cb828..0ebfd927 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -392,50 +392,45 @@ namespace PepperDash.Essentials { Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt); - var propertiesConfig = JsonConvert.DeserializeObject(devConf.Properties.ToString()); + var propertiesConfig = JsonConvert.DeserializeObject(devConf.Properties.ToString()) ?? + new DM.Config.DmpsRoutingPropertiesConfig(); - if(propertiesConfig == null) - propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig(); - - DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig)); + DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig)); } else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1) { Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController."); var butToken = devConf.Properties["buttons"]; - if (butToken != null) - { - var buttons = butToken.ToObject>(); - var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons); - DeviceManager.AddDevice(tpController); - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); - } - + if (butToken == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, + "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); + continue; + } + + var buttons = butToken.ToObject>(); + var tpController = new Core.Touchpanels.Mpc3TouchpanelController( + string.Format("{0}-keypadButtons", devConf.Key), devConf.Name, Global.ControlSystem, buttons); + + DeviceManager.AddDevice(tpController); } else { Debug.Console(2, "************Processor is not DMPS type***************"); } - - continue; } // Try local factories first - IKeyed newDev = null; + var newDev = null ?? PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); - - if (newDev != null) - DeviceManager.AddDevice(newDev); - else - Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); + if (newDev == null) + Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", + devConf.Type, devConf.Key); + else + DeviceManager.AddDevice(newDev); } catch (Exception e) { @@ -443,7 +438,6 @@ namespace PepperDash.Essentials } } Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); - } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index c9a5f605..97a18d50 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; +using System.Collections.Generic; +using System.Globalization; using Crestron.SimplSharpPro; - +using Newtonsoft.Json; using PepperDash.Core; -using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core.Touchpanels { @@ -16,82 +12,147 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public class Mpc3TouchpanelController : Device { - MPC3Basic _Touchpanel; + readonly MPC3Basic _touchpanel; - Dictionary _Buttons; + readonly Dictionary _buttons; public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons) : base(key, name) { - _Touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic; - _Buttons = buttons; + _touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic; + if (_touchpanel == null) + { + Debug.Console(1, this, "Failed to construct {0}, check configuration", key); + return; + } + + _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange; + _buttons = buttons; - _Touchpanel.ButtonStateChange += new Crestron.SimplSharpPro.DeviceSupport.ButtonEventHandler(_Touchpanel_ButtonStateChange); + AddPostActivationAction(() => + { + // Link up the button feedbacks to the specified BoolFeedbacks + foreach (var button in _buttons) + { + var buttonKey = button.Key.ToLower(); + var buttonConfig = button.Value; + if (buttonConfig == null) + { + Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); + continue; + } - AddPostActivationAction(() => - { - // Link up the button feedbacks to the specified BoolFeedbacks - foreach (var button in _Buttons) - { - var feedbackConfig = button.Value.Feedback; - var device = DeviceManager.GetDeviceForKey(feedbackConfig.DeviceKey) as Device; - if (device != null) - { - var bKey = button.Key.ToLower(); + int buttonNumber; + if (TryParseInt(buttonKey, out buttonNumber)) + { + Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); + _touchpanel.EnableNumericalButton((uint)buttonNumber); + } + else + { + Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + } - var feedback = device.GetFeedbackProperty(feedbackConfig.FeedbackName); + //var buttonEventTypes = buttonConfig.EventTypes; - var bFeedback = feedback as BoolFeedback; - var iFeedback = feedback as IntFeedback; - if (bFeedback != null) - { + var buttonFeedback = buttonConfig.Feedback; + if (buttonFeedback == null) + { + Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); + continue; + } + + var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; + if (device == null) + { + Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", + buttonFeedback.DeviceKey); + continue; + } - if (bKey == "power") - { - bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackPower); - continue; - } - else if (bKey == "mute") - { - bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackMute); - continue; - } + var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); + Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); + //switch (feedback.GetType().Name.ToLower()) + //{ + // case("boolfeedback"): + // { - // Link to the Crestron Feedback corresponding to the button number - bFeedback.LinkCrestronFeedback(_Touchpanel.Feedbacks[UInt16.Parse(button.Key)]); - } - else if (iFeedback != null) - { - if (bKey == "volumefeedback") - { - var volFeedback = feedback as IntFeedback; - // TODO: Figure out how to subsribe to a volume IntFeedback and link it to the voluem - volFeedback.LinkInputSig(_Touchpanel.VolumeBargraph); - } - } - else - { - Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.FeedbackName, device.Key); - } - } - else - { - Debug.Console(1, this, "Unable to get device with key: {0}", feedbackConfig.DeviceKey); - } - } - }); + // break; + // } + // case("intfeedback"): + // { + + // break; + // } + //} + + var boolFeedback = deviceFeedback as BoolFeedback; + var intFeedback = deviceFeedback as IntFeedback; + + switch (buttonKey) + { + case ("power"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); + break; + } + case ("volumeup"): + { + break; + } + case ("volumedown"): + { + break; + } + case ("volumefeedback"): + { + if (intFeedback != null) + { + var volumeFeedback = intFeedback; + volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); + } + break; + } + case ("mute"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); + break; + } + default: + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); + break; + } + } + } + }); } - void _Touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) + public bool TryParseInt(string str, out int result) + { + result = 0; + + foreach (var c in str) + { + if(c < '0' || c > '9') + return false; + + result = result*10 + (c - '0'); + } + + return true; + } + + void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) { Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState); var type = args.NewButtonState.ToString(); - if (_Buttons.ContainsKey(args.Button.Number.ToString())) + if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture))) { - Press(args.Button.Number.ToString(), type); + Press(args.Button.Number.ToString(CultureInfo.InvariantCulture), type); } - else if(_Buttons.ContainsKey(args.Button.Name.ToString())) + else if(_buttons.ContainsKey(args.Button.Name.ToString())) { Press(args.Button.Name.ToString(), type); } @@ -101,29 +162,30 @@ namespace PepperDash.Essentials.Core.Touchpanels /// Runs the function associated with this button/type. One of the following strings: /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased /// - /// + /// /// - public void Press(string number, string type) + public void Press(string buttonKey, string type) { // TODO: In future, consider modifying this to generate actions at device activation time // to prevent the need to dynamically call the method via reflection on each button press - if (!_Buttons.ContainsKey(number)) { return; } - var but = _Buttons[number]; - if (but.EventTypes.ContainsKey(type)) - { - foreach (var a in but.EventTypes[type]) { DeviceJsonApi.DoDeviceAction(a); } - } + if (!_buttons.ContainsKey(buttonKey)) return; + + var button = _buttons[buttonKey]; + if (!button.EventTypes.ContainsKey(type)) return; + + foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType); } - - } /// - /// Represents the configuration of a keybad buggon + /// Represents the configuration of a keypad button /// public class KeypadButton { + [JsonProperty("eventTypes")] public Dictionary EventTypes { get; set; } + + [JsonProperty("feedback")] public KeypadButtonFeedback Feedback { get; set; } public KeypadButton() @@ -133,12 +195,15 @@ namespace PepperDash.Essentials.Core.Touchpanels } } - /// - /// - /// - public class KeypadButtonFeedback - { - public string DeviceKey { get; set; } - public string FeedbackName { get; set; } - } + /// + /// Represents the configuration of a keypad button feedback + /// + public class KeypadButtonFeedback + { + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + [JsonProperty("feedbackName")] + public string FeedbackName { get; set; } + } } \ No newline at end of file From 13df52ab497f785cb114aaf7dbeea427e77fe012 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 8 Sep 2023 13:47:34 -0500 Subject: [PATCH 5/7] refactor(wip): updates constructor postActiviate call to seperate methods for enabling/disabling buttons and feedbacks --- .../Touchpanels/Mpc3Touchpanel.cs | 574 +++++++++++++----- 1 file changed, 413 insertions(+), 161 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 97a18d50..2cab16e6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -1,199 +1,451 @@ using System.Collections.Generic; using System.Globalization; +using System.Linq; using Crestron.SimplSharpPro; using Newtonsoft.Json; using PepperDash.Core; namespace PepperDash.Essentials.Core.Touchpanels { - /// - /// A wrapper class for the touchpanel portion of an MPC3 class process to allow for configurable - /// behavior of the keybad buttons - /// - public class Mpc3TouchpanelController : Device - { - readonly MPC3Basic _touchpanel; + /// + /// A wrapper class for the touchpanel portion of an MPC3 class process to allow for configurable + /// behavior of the keybad buttons + /// + public class Mpc3TouchpanelController : Device + { + readonly MPC3Basic _touchpanel; - readonly Dictionary _buttons; + readonly Dictionary _buttons; + + public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons) + : base(key, name) + { + _touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic; + if (_touchpanel == null) + { + Debug.Console(1, this, "Failed to construct MPC3 Touchpanel Controller with key {0}, check configuration", key); + return; + } - public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons) - : base(key, name) - { - _touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic; - if (_touchpanel == null) - { - Debug.Console(1, this, "Failed to construct {0}, check configuration", key); - return; - } - _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange; _buttons = buttons; - AddPostActivationAction(() => - { - // Link up the button feedbacks to the specified BoolFeedbacks - foreach (var button in _buttons) - { - var buttonKey = button.Key.ToLower(); - var buttonConfig = button.Value; - if (buttonConfig == null) - { - Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); - continue; - } + AddPostActivationAction(() => + { + SetupButtonsForEvents(); + SetupButtonFeedbacks(); - int buttonNumber; - if (TryParseInt(buttonKey, out buttonNumber)) + // check button config + //foreach (var button in _buttons) + //{ + // var buttonKey = button.Key.ToLower(); + // var buttonConfig = button.Value; + // if (buttonConfig == null) + // { + // Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); + // continue; + // } + + // int buttonNumber; + // if (TryParseInt(buttonKey, out buttonNumber)) + // Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); + // else + // Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + + + // // button event type configuration enables/disables keypad button + // var buttonEventTypes = buttonConfig.EventTypes; + // switch (buttonKey) + // { + // case ("power"): + // { + // if (buttonEventTypes == null) + // _touchpanel.DisablePowerButton(); + // else + // _touchpanel.EnablePowerButton(); + + // break; + // } + // case ("volumeup"): + // { + // if (buttonEventTypes == null) + // _touchpanel.DisableVolumeUpButton(); + + // break; + // } + // case ("volumedown"): + // { + // if(buttonEventTypes == null) + // _touchpanel.DisableVolumeDownButton(); + + // break; + // } + // case ("volumefeedback"): + // { + + // break; + // } + // case ("mute"): + // { + // if(buttonEventTypes == null) + // _touchpanel.DisableMuteButton(); + // else + // _touchpanel.EnableMuteButton(); + + // break; + // } + // default: + // { + // if(buttonNumber == 0) + // break; + + // if (buttonEventTypes == null) + // _touchpanel.DisableNumericalButton((uint)buttonNumber); + // else + // _touchpanel.EnableNumericalButton((uint)buttonNumber); + + // break; + // } + // } + + + // // Link up the button feedbacks to the specified device feedback + // var buttonFeedback = buttonConfig.Feedback; + // if (buttonFeedback == null) + // { + // Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); + // continue; + // } + + // var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; + // if (device == null) + // { + // Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", + // buttonFeedback.DeviceKey); + // continue; + // } + + // var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); + // Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); + // //switch (feedback.GetType().Name.ToLower()) + // //{ + // // case("boolfeedback"): + // // { + + // // break; + // // } + // // case("intfeedback"): + // // { + + // // break; + // // } + // //} + + // var boolFeedback = deviceFeedback as BoolFeedback; + // var intFeedback = deviceFeedback as IntFeedback; + + // switch (buttonKey) + // { + // case ("power"): + // { + // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); + // break; + // } + // case ("volumeup"): + // { + // break; + // } + // case ("volumedown"): + // { + // break; + // } + // case ("volumefeedback"): + // { + // if (intFeedback != null) + // { + // var volumeFeedback = intFeedback; + // volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); + // } + // break; + // } + // case ("mute"): + // { + // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); + // break; + // } + // default: + // { + // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); + // break; + // } + // } + //} + }); + } + + public void SetupButtonsForEvents() + { + if (_buttons == null) + { + Debug.Console(1, this, "Button properties are null, failed to setup buttons for events. Verify button configuraiton."); + return; + } + + // check button config + foreach (var button in _buttons) + { + var buttonKey = button.Key.ToLower(); + var buttonConfig = button.Value; + if (buttonConfig == null) + { + Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); + continue; + } + + int buttonNumber; + if (TryParseInt(buttonKey, out buttonNumber)) + Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); + else + Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + + + // button event type configuration enables/disables keypad button + var buttonEventTypes = buttonConfig.EventTypes; + switch (buttonKey) + { + case ("power"): { - Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); - _touchpanel.EnableNumericalButton((uint)buttonNumber); + if (buttonEventTypes == null) + _touchpanel.DisablePowerButton(); + else + _touchpanel.EnablePowerButton(); + + break; } - else + case ("volumeup"): { - Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + if (buttonEventTypes == null) + _touchpanel.DisableVolumeUpButton(); + + break; } - - //var buttonEventTypes = buttonConfig.EventTypes; - - var buttonFeedback = buttonConfig.Feedback; - if (buttonFeedback == null) - { - Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); - continue; - } - - var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; - if (device == null) - { - Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", - buttonFeedback.DeviceKey); - continue; - } - - var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); - Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); - //switch (feedback.GetType().Name.ToLower()) - //{ - // case("boolfeedback"): - // { - - // break; - // } - // case("intfeedback"): - // { - - // break; - // } - //} - - var boolFeedback = deviceFeedback as BoolFeedback; - var intFeedback = deviceFeedback as IntFeedback; - - switch (buttonKey) + case ("volumedown"): { - case ("power"): + if (buttonEventTypes == null) + _touchpanel.DisableVolumeDownButton(); + + break; + } + case ("volumefeedback"): + { + + break; + } + case ("mute"): + { + if (buttonEventTypes == null) + _touchpanel.DisableMuteButton(); + else + _touchpanel.EnableMuteButton(); + + break; + } + default: + { + if (buttonNumber == 0) + break; + + if (buttonEventTypes == null) + _touchpanel.DisableNumericalButton((uint) buttonNumber); + else + _touchpanel.EnableNumericalButton((uint) buttonNumber); + + break; + } + } + } + } + + public void SetupButtonFeedbacks() + { + if (_buttons == null) + { + Debug.Console(1, this, "Button properties are null, failed to setup buttons for events. Verify button configuraiton."); + return; + } + + // check button config + foreach (var button in _buttons) + { + var buttonKey = button.Key.ToLower(); + var buttonConfig = button.Value; + if (buttonConfig == null) + { + Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); + continue; + } + + int buttonNumber; + if (TryParseInt(buttonKey, out buttonNumber)) + Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); + else + Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + + // Link up the button feedbacks to the specified device feedback + var buttonFeedback = buttonConfig.Feedback; + if (buttonFeedback == null) + { + Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); + continue; + } + + var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; + if (device == null) + { + Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", + buttonFeedback.DeviceKey); + continue; + } + + var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); + Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); + //switch (feedback.GetType().Name.ToLower()) + //{ + // case("boolfeedback"): + // { + + // break; + // } + // case("intfeedback"): + // { + + // break; + // } + //} + + var boolFeedback = deviceFeedback as BoolFeedback; + var intFeedback = deviceFeedback as IntFeedback; + + switch (buttonKey) + { + case ("power"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); + break; + } + case ("volumeup"): + { + break; + } + case ("volumedown"): + { + break; + } + case ("volumefeedback"): + { + if (intFeedback != null) { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); - break; + var volumeFeedback = intFeedback; + volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); } - case ("volumeup"): - { - break; - } - case ("volumedown"): - { - break; - } - case ("volumefeedback"): - { - if (intFeedback != null) - { - var volumeFeedback = intFeedback; - volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); - } - break; - } - case ("mute"): - { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); - break; - } - default: - { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); - break; - } - } - } - }); - } + break; + } + case ("mute"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); + break; + } + default: + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); + break; + } + } + } + } - public bool TryParseInt(string str, out int result) - { - result = 0; + public bool TryParseInt(string str, out int result) + { + try + { + result = int.Parse(str); + return true; + } + catch + { + result = 0; + return false; + } + } - foreach (var c in str) - { - if(c < '0' || c > '9') - return false; + public bool TryExtractInt(string str, out int result) + { + result = str.Where(c => c >= '0' && c <= '9').Aggregate(0, (current, c) => current * 10 + (c - '0')); - result = result*10 + (c - '0'); - } + //foreach (var c in str) + //{ + // if(c < '0' || c > '9') + // //return false + // continue; - return true; - } + // result = result*10 + (c - '0'); + //} - void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) - { - Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState); - var type = args.NewButtonState.ToString(); + Debug.Console(0, this, "TryParseInt: str-'{0}', result-'{1}'", str, result); + return result != 0; + } - if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture))) - { - Press(args.Button.Number.ToString(CultureInfo.InvariantCulture), type); - } - else if(_buttons.ContainsKey(args.Button.Name.ToString())) - { - Press(args.Button.Name.ToString(), type); - } - } + void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) + { + Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState); + var type = args.NewButtonState.ToString(); - /// - /// Runs the function associated with this button/type. One of the following strings: - /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased - /// - /// - /// - public void Press(string buttonKey, string type) - { - // TODO: In future, consider modifying this to generate actions at device activation time - // to prevent the need to dynamically call the method via reflection on each button press - if (!_buttons.ContainsKey(buttonKey)) return; + if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture))) + { + Press(args.Button.Number.ToString(CultureInfo.InvariantCulture), type); + } + else if (_buttons.ContainsKey(args.Button.Name.ToString())) + { + Press(args.Button.Name.ToString(), type); + } + } - var button = _buttons[buttonKey]; - if (!button.EventTypes.ContainsKey(type)) return; + /// + /// Runs the function associated with this button/type. One of the following strings: + /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased + /// + /// + /// + public void Press(string buttonKey, string type) + { + // TODO: In future, consider modifying this to generate actions at device activation time + // to prevent the need to dynamically call the method via reflection on each button press + if (!_buttons.ContainsKey(buttonKey)) return; - foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType); - } - } + var button = _buttons[buttonKey]; + if (!button.EventTypes.ContainsKey(type)) return; - /// - /// Represents the configuration of a keypad button - /// - public class KeypadButton - { + foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType); + } + } + + /// + /// Represents the configuration of a keypad button + /// + public class KeypadButton + { [JsonProperty("eventTypes")] - public Dictionary EventTypes { get; set; } + public Dictionary EventTypes { get; set; } [JsonProperty("feedback")] - public KeypadButtonFeedback Feedback { get; set; } + public KeypadButtonFeedback Feedback { get; set; } - public KeypadButton() - { - EventTypes = new Dictionary(); - Feedback = new KeypadButtonFeedback(); - } - } + public KeypadButton() + { + EventTypes = new Dictionary(); + Feedback = new KeypadButtonFeedback(); + } + } /// /// Represents the configuration of a keypad button feedback From 316d545bda853569792c2e56b337470a4661c576 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 8 Sep 2023 15:20:29 -0500 Subject: [PATCH 6/7] refactor(wip): updates keypad initializeFeedbacks method --- .../Touchpanels/Mpc3Touchpanel.cs | 402 +++++------------- 1 file changed, 118 insertions(+), 284 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 2cab16e6..f4611a70 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Globalization; -using System.Linq; using Crestron.SimplSharpPro; using Newtonsoft.Json; using PepperDash.Core; @@ -29,191 +28,47 @@ namespace PepperDash.Essentials.Core.Touchpanels _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange; _buttons = buttons; - - AddPostActivationAction(() => - { - SetupButtonsForEvents(); - SetupButtonFeedbacks(); - - // check button config - //foreach (var button in _buttons) - //{ - // var buttonKey = button.Key.ToLower(); - // var buttonConfig = button.Value; - // if (buttonConfig == null) - // { - // Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); - // continue; - // } - - // int buttonNumber; - // if (TryParseInt(buttonKey, out buttonNumber)) - // Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); - // else - // Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); - - - // // button event type configuration enables/disables keypad button - // var buttonEventTypes = buttonConfig.EventTypes; - // switch (buttonKey) - // { - // case ("power"): - // { - // if (buttonEventTypes == null) - // _touchpanel.DisablePowerButton(); - // else - // _touchpanel.EnablePowerButton(); - - // break; - // } - // case ("volumeup"): - // { - // if (buttonEventTypes == null) - // _touchpanel.DisableVolumeUpButton(); - - // break; - // } - // case ("volumedown"): - // { - // if(buttonEventTypes == null) - // _touchpanel.DisableVolumeDownButton(); - - // break; - // } - // case ("volumefeedback"): - // { - - // break; - // } - // case ("mute"): - // { - // if(buttonEventTypes == null) - // _touchpanel.DisableMuteButton(); - // else - // _touchpanel.EnableMuteButton(); - - // break; - // } - // default: - // { - // if(buttonNumber == 0) - // break; - - // if (buttonEventTypes == null) - // _touchpanel.DisableNumericalButton((uint)buttonNumber); - // else - // _touchpanel.EnableNumericalButton((uint)buttonNumber); - - // break; - // } - // } - - - // // Link up the button feedbacks to the specified device feedback - // var buttonFeedback = buttonConfig.Feedback; - // if (buttonFeedback == null) - // { - // Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); - // continue; - // } - - // var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; - // if (device == null) - // { - // Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", - // buttonFeedback.DeviceKey); - // continue; - // } - - // var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); - // Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); - // //switch (feedback.GetType().Name.ToLower()) - // //{ - // // case("boolfeedback"): - // // { - - // // break; - // // } - // // case("intfeedback"): - // // { - - // // break; - // // } - // //} - - // var boolFeedback = deviceFeedback as BoolFeedback; - // var intFeedback = deviceFeedback as IntFeedback; - - // switch (buttonKey) - // { - // case ("power"): - // { - // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); - // break; - // } - // case ("volumeup"): - // { - // break; - // } - // case ("volumedown"): - // { - // break; - // } - // case ("volumefeedback"): - // { - // if (intFeedback != null) - // { - // var volumeFeedback = intFeedback; - // volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); - // } - // break; - // } - // case ("mute"): - // { - // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); - // break; - // } - // default: - // { - // if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); - // break; - // } - // } - //} - }); - } - - public void SetupButtonsForEvents() - { if (_buttons == null) { - Debug.Console(1, this, "Button properties are null, failed to setup buttons for events. Verify button configuraiton."); + Debug.Console(1, this, + "Button properties are null, failed to setup MPC3 Touch Controller, check configuration"); return; } - // check button config - foreach (var button in _buttons) + AddPostActivationAction(() => { - var buttonKey = button.Key.ToLower(); - var buttonConfig = button.Value; - if (buttonConfig == null) + foreach (var button in _buttons) { - Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); - continue; + var buttonKey = button.Key.ToLower(); + var buttonConfig = button.Value; + + InitializeButton(buttonKey, buttonConfig); + InitializeButtonFeedback(buttonKey, buttonConfig); } + }); + } - int buttonNumber; - if (TryParseInt(buttonKey, out buttonNumber)) - Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); - else - Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + /// + /// Enables/disables buttons based on event type configuration + /// + /// + /// + public void InitializeButton(string key, KeypadButton config) + { + if (config == null) + { + Debug.Console(1, this, "Button '{0}' config is null, unable to initialize", key); + return; + } + int buttonNumber; + TryParseInt(key, out buttonNumber); - // button event type configuration enables/disables keypad button - var buttonEventTypes = buttonConfig.EventTypes; - switch (buttonKey) - { - case ("power"): + var buttonEventTypes = config.EventTypes; + + switch (key) + { + case ("power"): { if (buttonEventTypes == null) _touchpanel.DisablePowerButton(); @@ -222,26 +77,26 @@ namespace PepperDash.Essentials.Core.Touchpanels break; } - case ("volumeup"): + case ("volumeup"): { if (buttonEventTypes == null) _touchpanel.DisableVolumeUpButton(); break; } - case ("volumedown"): + case ("volumedown"): { if (buttonEventTypes == null) _touchpanel.DisableVolumeDownButton(); break; } - case ("volumefeedback"): + case ("volumefeedback"): { break; } - case ("mute"): + case ("mute"): { if (buttonEventTypes == null) _touchpanel.DisableMuteButton(); @@ -250,120 +105,116 @@ namespace PepperDash.Essentials.Core.Touchpanels break; } - default: + default: { if (buttonNumber == 0) break; if (buttonEventTypes == null) - _touchpanel.DisableNumericalButton((uint) buttonNumber); + _touchpanel.DisableNumericalButton((uint)buttonNumber); else - _touchpanel.EnableNumericalButton((uint) buttonNumber); + _touchpanel.EnableNumericalButton((uint)buttonNumber); break; } - } } + + Debug.Console(1, this, "Button '{0}' {1}", key, buttonEventTypes == null + ? "is disabled, verify eventTypes are configured." + : "is enabled"); } - public void SetupButtonFeedbacks() + /// + /// Links button feedback if configured + /// + /// + /// + public void InitializeButtonFeedback(string key, KeypadButton config) { - if (_buttons == null) + if (config == null) { - Debug.Console(1, this, "Button properties are null, failed to setup buttons for events. Verify button configuraiton."); + Debug.Console(1, this, "Button '{0}' config is null, unable to initialize feedback", key); return; } - // check button config - foreach (var button in _buttons) + int buttonNumber; + TryParseInt(key, out buttonNumber); + + // Link up the button feedbacks to the specified device feedback + var buttonFeedback = config.Feedback; + if (buttonFeedback == null) { - var buttonKey = button.Key.ToLower(); - var buttonConfig = button.Value; - if (buttonConfig == null) - { - Debug.Console(1, this, "Unable to get button config for {0}-{1}", Key, button.Key); - continue; - } + Debug.Console(1, this, "Button '{0}' feedback not configured and will not be implemented. Verify feedback is configured if required.", key); + return; + } - int buttonNumber; - if (TryParseInt(buttonKey, out buttonNumber)) - Debug.Console(0, this, "buttonFeedback: tryIntParse successful, buttonNumber = {0}", buttonNumber); - else - Debug.Console(0, this, "buttonFeedback: tryIntParse failed, buttonKey = {0}", buttonKey); + var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; + if (device == null) + { + Debug.Console(1, this, "Button '{0}' feedback device with key '{0}' not found, feedback will not be implemented. Verify feedback deviceKey is properly configured.", + buttonFeedback.DeviceKey); + return; + } - // Link up the button feedbacks to the specified device feedback - var buttonFeedback = buttonConfig.Feedback; - if (buttonFeedback == null) - { - Debug.Console(1, this, "Button '{0}' feedback not configured, feedback will not be implemented", buttonKey); - continue; - } + // TODO [ ] verify if this can replace the current method + var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); + Debug.Console(0, this, "deviceFeedback.GetType().Name: '{0}'", deviceFeedback.GetType().Name); + //switch (feedback.GetType().Name.ToLower()) + //{ + // case("boolfeedback"): + // { + // break; + // } + // case("intfeedback"): + // { + // break; + // } + // case("stringfeedback"): + // { + // break; + // } + //} - var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; - if (device == null) - { - Debug.Console(1, this, "Unable to get device with key {0}, feedback will not be implemented", - buttonFeedback.DeviceKey); - continue; - } + var boolFeedback = deviceFeedback as BoolFeedback; + var intFeedback = deviceFeedback as IntFeedback; - var deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); - Debug.Console(0, this, "deviceFeedback.GetType().Name: {0}", deviceFeedback.GetType().Name); - //switch (feedback.GetType().Name.ToLower()) - //{ - // case("boolfeedback"): - // { - - // break; - // } - // case("intfeedback"): - // { - - // break; - // } - //} - - var boolFeedback = deviceFeedback as BoolFeedback; - var intFeedback = deviceFeedback as IntFeedback; - - switch (buttonKey) - { - case ("power"): + switch (key) + { + case ("power"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); + break; + } + case ("volumeup"): + case ("volumedown"): + case ("volumefeedback"): + { + if (intFeedback != null) { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower); - break; + var volumeFeedback = intFeedback; + volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); } - case ("volumeup"): - { - break; - } - case ("volumedown"): - { - break; - } - case ("volumefeedback"): - { - if (intFeedback != null) - { - var volumeFeedback = intFeedback; - volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph); - } - break; - } - case ("mute"): - { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); - break; - } - default: - { - if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); - break; - } - } + break; + } + case ("mute"): + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute); + break; + } + default: + { + if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]); + break; + } } } + /// + /// Try parse int helper method + /// + /// + /// + /// public bool TryParseInt(string str, out int result) { try @@ -378,24 +229,7 @@ namespace PepperDash.Essentials.Core.Touchpanels } } - public bool TryExtractInt(string str, out int result) - { - result = str.Where(c => c >= '0' && c <= '9').Aggregate(0, (current, c) => current * 10 + (c - '0')); - - //foreach (var c in str) - //{ - // if(c < '0' || c > '9') - // //return false - // continue; - - // result = result*10 + (c - '0'); - //} - - Debug.Console(0, this, "TryParseInt: str-'{0}', result-'{1}'", str, result); - return result != 0; - } - - void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) + private void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) { Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState); var type = args.NewButtonState.ToString(); From 2afa9df705ffb5d6e473861968da0e886825253b Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 14:08:20 -0500 Subject: [PATCH 7/7] fix: removes HdPsXxx controller, propertiesConfig and join map --- PepperDashEssentials/ControlSystem.cs | 49 +- .../JoinMaps/HdPsXxxControllerJoinMap.cs | 190 ----- .../PepperDash_Essentials_Core.csproj | 1 - .../Chassis/HdPsXxxController.cs | 657 ------------------ .../Config/HdPsXxxPropertiesConfig.cs | 30 - .../PepperDash_Essentials_DM.csproj | 2 - 6 files changed, 28 insertions(+), 901 deletions(-) delete mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs delete mode 100644 essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs delete mode 100644 essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 0ebfd927..1bafbbac 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -392,45 +392,51 @@ namespace PepperDash.Essentials { Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt); - var propertiesConfig = JsonConvert.DeserializeObject(devConf.Properties.ToString()) ?? - new DM.Config.DmpsRoutingPropertiesConfig(); + var propertiesConfig = JsonConvert.DeserializeObject(devConf.Properties.ToString()); - DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig)); + if(propertiesConfig == null) + propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig(); + + DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig)); } else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1) { - Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController."); + Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController."); - var butToken = devConf.Properties["buttons"]; - if (butToken == null) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, - "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); + var butToken = devConf.Properties["buttons"]; + if (butToken == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, + "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); continue; - } - - var buttons = butToken.ToObject>(); - var tpController = new Core.Touchpanels.Mpc3TouchpanelController( - string.Format("{0}-keypadButtons", devConf.Key), devConf.Name, Global.ControlSystem, buttons); + } - DeviceManager.AddDevice(tpController); + var buttons = butToken.ToObject>(); + var tpController = new Core.Touchpanels.Mpc3TouchpanelController( + string.Format("{0}-keypadButtons", devConf.Key), devConf.Name, Global.ControlSystem, buttons); + + DeviceManager.AddDevice(tpController); } else { Debug.Console(2, "************Processor is not DMPS type***************"); } + + continue; } // Try local factories first - var newDev = null ?? PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); + IKeyed newDev = null; - if (newDev == null) - Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", - devConf.Type, devConf.Key); - else - DeviceManager.AddDevice(newDev); + if (newDev == null) + newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); + + if (newDev != null) + DeviceManager.AddDevice(newDev); + else + Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); } catch (Exception e) { @@ -438,6 +444,7 @@ namespace PepperDash.Essentials } } Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); + } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs deleted file mode 100644 index 3f2901c9..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using PepperDash.Essentials.Core; - -namespace PepperDash_Essentials_Core.Bridges -{ - public class HdPsXxxControllerJoinMap : JoinMapBaseAdvanced - { - - #region Digital - - [JoinName("EnableAutoRoute")] - public JoinDataComplete EnableAutoRoute = new JoinDataComplete( - new JoinData - { - JoinNumber = 1, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Enable Automatic Routing on Xx1 Switchers", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("InputSync")] - public JoinDataComplete InputSync = new JoinDataComplete( - new JoinData - { - JoinNumber = 2, - JoinSpan = 8 - }, - new JoinMetadata - { - Description = "Device Input Sync", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("EnableInputHdcp")] - public JoinDataComplete EnableInputHdcp = new JoinDataComplete( - new JoinData - { - JoinNumber = 11, - JoinSpan = 8 - }, - new JoinMetadata - { - Description = "Device Enable Input Hdcp", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("DisableInputHdcp")] - public JoinDataComplete DisableInputHdcp = new JoinDataComplete( - new JoinData - { - JoinNumber = 21, - JoinSpan = 8 - }, - new JoinMetadata - { - Description = "Device Disnable Input Hdcp", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("IsOnline")] - public JoinDataComplete IsOnline = new JoinDataComplete( - new JoinData - { - JoinNumber = 30, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Device Onlne", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - #endregion - - - #region Analog - - [JoinName("OutputRoute")] - public JoinDataComplete OutputRoute = new JoinDataComplete( - new JoinData - { - JoinNumber = 11, - JoinSpan = 2 - }, - new JoinMetadata - { - Description = "Device Output Route Set/Get", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - #endregion - - - #region Serial - - [JoinName("Name")] - public JoinDataComplete Name = new JoinDataComplete( - new JoinData - { - JoinNumber = 1, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Device Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - - [JoinName("InputName")] - public JoinDataComplete InputName = new JoinDataComplete( - new JoinData - { - JoinNumber = 2, - JoinSpan = 8 - }, - new JoinMetadata - { - Description = "Device Input Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - - [JoinName("OutputName")] - public JoinDataComplete OutputName = new JoinDataComplete( - new JoinData - { - JoinNumber = 11, - JoinSpan = 2 - }, - new JoinMetadata - { - Description = "Device Output Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - - [JoinName("OutputRoutedName")] - public JoinDataComplete OutputRoutedName = new JoinDataComplete( - new JoinData - { - JoinNumber = 16, - JoinSpan = 2 - }, - new JoinMetadata - { - Description = "Device Output Route Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - - #endregion - - /// - /// Constructor to use when instantiating this join map without inheriting from it - /// - /// Join this join map will start at - public HdPsXxxControllerJoinMap(uint joinStart) - : this(joinStart, typeof(HdPsXxxControllerJoinMap)) - { - } - - /// - /// Constructor to use when extending this Join map - /// - /// Join this join map will start at - /// Type of the child join map - protected HdPsXxxControllerJoinMap(uint joinStart, Type type) - : base(joinStart, type) - { - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 0d9aa9bc..75d4626d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -127,7 +127,6 @@ - diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs deleted file mode 100644 index d923949e..00000000 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ /dev/null @@ -1,657 +0,0 @@ -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 Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.Core.Config; -using PepperDash_Essentials_Core.Bridges; -using PepperDash_Essentials_DM.Config; - -namespace PepperDash_Essentials_DM.Chassis -{ - [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback - { - - private readonly HdPsXxx _chassis; - private readonly HdPs401 _chassis401; - private readonly HdPs621 _chassis621; - - public RoutingPortCollection InputPorts { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } - - public Dictionary InputNames { get; set; } - public Dictionary OutputNames { get; set; } - - public FeedbackCollection InputNameFeedbacks { get; private set; } - public FeedbackCollection InputHdcpEnableFeedback { get; private set; } - - public FeedbackCollection OutputNameFeedbacks { get; private set; } - public FeedbackCollection OutputRouteNameFeedback { get; private set; } - - public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } - public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } - - public StringFeedback DeviceNameFeedback { get; private set; } - public BoolFeedback AutoRouteFeedback { get; private set; } - - public event EventHandler NumericSwitchChange; - - /// - /// Constructor - /// - /// - /// - /// HdPs401 device instance - /// - public HdPsXxxController(string key, string name, HdPsXxx chassis, HdPsXxxPropertiesConfig props) - : base(key, name, chassis) - { - _chassis = chassis; - Name = name; - - if (props == null) - { - Debug.Console(1, this, "HdPsXxxController properties are null, failed to build device"); - return; - } - - InputPorts = new RoutingPortCollection(); - InputNameFeedbacks = new FeedbackCollection(); - InputHdcpEnableFeedback = new FeedbackCollection(); - InputNames = new Dictionary(); - //InputNames = props.Inputs; - - OutputPorts = new RoutingPortCollection(); - OutputNameFeedbacks = new FeedbackCollection(); - OutputRouteNameFeedback = new FeedbackCollection(); - OutputNames = new Dictionary(); - //OutputNames = props.Outputs; - - VideoInputSyncFeedbacks = new FeedbackCollection(); - VideoOutputRouteFeedbacks = new FeedbackCollection(); - - if (_chassis.NumberOfOutputs == 1) - { - if (_chassis is HdPs401) - _chassis401 = _chassis as HdPs401; - if (_chassis is HdPs621) - _chassis621 = _chassis as HdPs621; - - AutoRouteFeedback = new BoolFeedback(() => _chassis401.PriorityRouteOnFeedback.BoolValue); - } - - SetupInputs(props.Inputs); - SetupOutputs(props.Outputs); - - AddPostActivationAction(AddFeedbackCollecitons); - } - - // input setup - private void SetupInputs(Dictionary dict) - { - if (dict == null) - { - Debug.Console(1, this, "Failed to setup inputs, properties are null"); - return; - } - foreach (var kvp in dict) - { - Debug.Console(1, this, "props.Input[{0}]: {1}", kvp.Key, kvp.Value); - } - InputNames = dict; - - for (uint i = 1; i <= _chassis.NumberOfInputs; i++) - { - var index = i; - var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("Input {0}", index) : InputNames[index]; - var input = _chassis.Inputs[index]; - var hdmiInput = _chassis.HdmiInputs[index]; - var dmLiteInput = _chassis.DmLiteInputs[index]; - - InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); - - // TODO [ ] verify which input type is needed - input.Name.StringValue = name; - hdmiInput.Name.StringValue = name; - dmLiteInput.Name.StringValue = name; - - var port = new RoutingInputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) - { - FeedbackMatchObject = input - }; - InputPorts.Add(port); - - InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => hdmiInput.InputPort.HdcpSupportOnFeedback.BoolValue)); - - VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); - } - - _chassis.DMInputChange += _chassis_InputChange; - } - - // output setup - private void SetupOutputs(Dictionary dict) - { - if (dict == null) - { - Debug.Console(1, this, "Failed to setup outputs, properties are null"); - return; - } - foreach (var kvp in dict) - { - Debug.Console(1, this, "props.Output[{0}]: {1}", kvp.Key, kvp.Value); - } - OutputNames = dict; - - for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) - { - var index = i; - var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) : OutputNames[index]; - var output = _chassis.Outputs[index]; - var hdmiDmLiteOutput = _chassis.HdmiDmLiteOutputs[index]; - - OutputNameFeedbacks.Add(new StringFeedback(name, () => OutputNames[index])); - - // TODO [ ] verify which output type is needed - output.Name.StringValue = name; - hdmiDmLiteOutput.Name.StringValue = name; - - var port = new RoutingOutputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) - { - FeedbackMatchObject = output - }; - OutputPorts.Add(port); - - OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); - - VideoOutputRouteFeedbacks.Add(new IntFeedback(name, () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); - } - - _chassis.DMOutputChange += _chassis_OutputChange; - } - - - #region BridgeLinking - - /// - /// Link device to API - /// - /// - /// - /// - /// - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new HdPsXxxControllerJoinMap(joinStart); - - 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]); - - _chassis.OnlineStatusChange += _chassis_OnlineStatusChange; - - if (_chassis401 != null) LinkChassis401ToApi(trilist, joinMap); - - if (_chassis621 != null) LinkChassis621ToApi(trilist, joinMap); - - LinkChassisInputsToApi(trilist, joinMap); - LinkChassisOutputsToApi(trilist, joinMap); - - trilist.OnlineStatusChange += (sender, args) => - { - if (!args.DeviceOnLine) return; - }; - } - - - // links inputs to API - private void LinkChassisInputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) - { - for (uint i = 1; i <= _chassis.NumberOfInputs; i++) - { - var input = i; - var inputName = InputNames[input]; - var indexWithOffset = input - 1; - - trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + indexWithOffset, () => EnableHdcp(input)); - trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + indexWithOffset, () => DisableHdcp(input)); - - InputHdcpEnableFeedback[inputName].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]); - InputHdcpEnableFeedback[inputName].LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]); - - VideoInputSyncFeedbacks[inputName].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + indexWithOffset]); - - InputNameFeedbacks[inputName].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + indexWithOffset]); - } - } - - - // links outputs to API - private void LinkChassisOutputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) - { - for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) - { - var output = i; - var outputName = OutputNames[output]; - var indexWithOffset = output - 1; - - trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + indexWithOffset, (a) => - ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); - - OutputNameFeedbacks[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + indexWithOffset]); - OutputRouteNameFeedback[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + indexWithOffset]); - - VideoOutputRouteFeedbacks[outputName].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + indexWithOffset]); - } - } - - - // links HdPs401 chassis to API - private void LinkChassis401ToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) - { - trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis401.AutoRouteOn()); - trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis401.AutoRouteOff()); - - AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); - } - - - // links HdPs621 chassis to API - private void LinkChassis621ToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap) - { - trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis621.AutoRouteOn()); - trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _chassis621.AutoRouteOff()); - - AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); - } - - - #endregion - - - /// - /// Executes a device switch using objects - /// - /// - /// - /// - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - var input = inputSelector as HdPsXxxHdmiInput; - var output = outputSelector as HdPsXxxHdmiOutput; - - Debug.Console(2, this, "ExecuteSwitch: input={0}, output={1}", input, output); - - if (output == null) - { - Debug.Console(0, this, "Unable to make switch, output selector is not HdPsXxxHdmiOutput"); - return; - } - - // TODO [ ] Validate if sending the same input toggles the switch - var current = output.VideoOut; - if (current != input) - output.VideoOut = input; - } - - - /// - /// Executes a device switch using numeric values - /// - /// - /// - /// - public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) - { - var input = inputSelector == 0 ? null : _chassis.Inputs[inputSelector]; - var output = _chassis.Outputs[outputSelector]; - - Debug.Console(2, this, "ExecuteNumericSwitch: input={0}, output={1}", input, output); - - ExecuteSwitch(input, output, signalType); - } - - - /// - /// Enables Hdcp on the provided port - /// - /// - public void EnableHdcp(uint port) - { - if (port <= 0 || port > _chassis.NumberOfInputs) return; - - _chassis.HdmiInputs[port].InputPort.HdcpSupportOn(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } - - - /// - /// Disables Hdcp on the provided port - /// - /// - public void DisableHdcp(uint port) - { - if (port <= 0 || port > _chassis.NumberOfInputs) return; - - _chassis.HdmiInputs[port].InputPort.HdcpSupportOff(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } - - - /// - /// Enables switcher auto route - /// - public void EnableAutoRoute() - { - if (_chassis.NumberOfInputs != 1) return; - - if (_chassis401 != null) - { - _chassis401.AutoRouteOn(); - } - - if (_chassis621 != null) - { - _chassis621.AutoRouteOn(); - } - } - - - /// - /// Disables switcher auto route - /// - public void DisableAutoRoute() - { - if (_chassis.NumberOfInputs != 1) return; - - if (_chassis401 != null) - { - _chassis401.AutoRouteOff(); - } - - if (_chassis621 != null) - { - _chassis621.AutoRouteOff(); - } - } - - #region Events - - - // _chassis online/offline event - private void _chassis_OnlineStatusChange(GenericBase currentDevice, - OnlineOfflineEventArgs args) - { - IsOnline.FireUpdate(); - - if (!args.DeviceOnLine) return; - - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } - } - - - // _chassis input change event - private void _chassis_InputChange(Switch device, DMInputEventArgs args) - { - var eventId = args.EventId; - - switch (eventId) - { - case DMInputEventIds.VideoDetectedEventId: - { - Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", eventId); - foreach (var item in VideoInputSyncFeedbacks) - { - item.FireUpdate(); - } - break; - } - case DMInputEventIds.InputNameFeedbackEventId: - case DMInputEventIds.InputNameEventId: - case DMInputEventIds.NameFeedbackEventId: - { - Debug.Console(1, this, "Event ID {0}: Updating name feedbacks", eventId); - - var input = args.Number; - var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; - - Debug.Console(1, this, "Input {0} Name {1}", input, name); - break; - } - default: - { - Debug.Console(1, this, "Uhandled DM Input Event ID {0}", eventId); - break; - } - } - } - - - // _chassis output change event - private void _chassis_OutputChange(Switch device, DMOutputEventArgs args) - { - if (args.EventId != DMOutputEventIds.VideoOutEventId) return; - - var output = args.Number; - - var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null - ? 0 - : _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback.Number; - - var outputName = OutputNames[output]; - - var feedback = VideoOutputRouteFeedbacks[outputName]; - if (feedback == null) return; - - var inputPort = InputPorts.FirstOrDefault( - p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback); - - var outputPort = OutputPorts.FirstOrDefault( - p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output]); - - feedback.FireUpdate(); - - OnSwitchChange(new RoutingNumericEventArgs( - output, input, outputPort, inputPort, eRoutingSignalType.AudioVideo)); - } - - - /// - /// Raise an event when the status of a switch object changes. - /// - /// Argumetns defined as IKeyName sender, output, input, & eRoutingSignalType - private void OnSwitchChange(RoutingNumericEventArgs args) - { - var newEvent = NumericSwitchChange; - if (newEvent != null) newEvent(this, args); - } - - - #endregion - - - #region FeedbacksAndFeedbackCollections - - - /// - /// Add feedback colleciton arrays to feedback collections - /// - /// BoolFeedback[] arrays - public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) - { - foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) - { - AddCollectionsToList(item); - } - } - - - /// - /// Add feedback colleciton arrays to feedback collections - /// - /// IntFeedback[] arrays - public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) - { - foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) - { - AddCollectionsToList(item); - } - } - - - /// - /// Add feedback colleciton arrays to feedback collections - /// - /// StringFeedback[] arrays - public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) - { - foreach (var item in feedbackCollections.SelectMany(feedbackCollection => feedbackCollections)) - { - AddCollectionsToList(item); - } - } - - - /// - /// Adds feedback colleciton to feedback collections - /// - /// BoolFeedback - public void AddCollectionToList(FeedbackCollection feedbackCollection) - { - foreach (var item in feedbackCollection.Where(item => item != null)) - { - AddFeedbackToList(item); - } - } - - - /// - /// Adds feedback colleciton to feedback collections - /// - /// IntFeedback - public void AddCollectionToList(FeedbackCollection feedbackCollection) - { - foreach (var item in feedbackCollection.Where(item => item != null)) - { - AddFeedbackToList(item); - } - } - - - /// - /// Adds feedback colleciton to feedback collections - /// - /// StringFeedback - public void AddCollectionToList(FeedbackCollection feedbackCollection) - { - foreach (var item in feedbackCollection.Where(item => item != null)) - { - AddFeedbackToList(item); - } - } - - - /// - /// Adds individual feedbacks to feedback collection - /// - /// Feedback - public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback fb) - { - if (fb == null || Feedbacks.Contains(fb)) return; - - Feedbacks.Add(fb); - } - - - /// - /// Adds provided feedbacks to feedback collection list - /// - public void AddFeedbackCollecitons() - { - AddFeedbackToList(DeviceNameFeedback); - AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); - AddCollectionsToList(VideoOutputRouteFeedbacks); - AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedback); - } - - - #endregion - - - #region Factory - - - public class HdSp401ControllerFactory : EssentialsDeviceFactory - { - public HdSp401ControllerFactory() - { - TypeNames = new List() { "hdps401", "hdps402", "hdps621", "hdps622" }; - } - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new HD-PSXxx device"); - - var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); - if (props == null) - { - Debug.Console(1, "Factory failed to create new HD-PSXxx device, properties config was null"); - return null; - } - - var key = dc.Key; - var name = dc.Name; - var type = dc.Type.ToLower(); - var control = props.Control; - var ipid = control.IpIdInt; - //var address = control.TcpSshProperties.Address; - - switch (type) - { - case ("hdps401"): - { - return new HdPsXxxController(key, name, new HdPs401(ipid, Global.ControlSystem), props); - } - case ("hdps402"): - { - return new HdPsXxxController(key, name, new HdPs402(ipid, Global.ControlSystem), props); - } - case ("hdps621"): - { - return new HdPsXxxController(key, name, new HdPs621(ipid, Global.ControlSystem), props); - } - case ("hdps622"): - { - return new HdPsXxxController(key, name, new HdPs622(ipid, Global.ControlSystem), props); - } - default: - { - Debug.Console(1, "Factory failed to create new {0} device", type); - return null; - } - } - } - } - - - #endregion - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs deleted file mode 100644 index c02fc511..00000000 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.DM.Config; - -namespace PepperDash_Essentials_DM.Config -{ - public class HdPsXxxPropertiesConfig - { - [JsonProperty("control")] - public ControlPropertiesConfig Control { get; set; } - - [JsonProperty("inputs")] - //public Dictionary Inputs { get; set; } - public Dictionary Inputs { get; set; } - - [JsonProperty("outputs")] - //public Dictionary Outputs { get; set; } - public Dictionary Outputs { get; set; } - - public HdPsXxxPropertiesConfig() - { - //Inputs = new Dictionary(); - //Outputs = new Dictionary(); - - Inputs = new Dictionary(); - Outputs = new Dictionary(); - } - } -} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj index 0011c305..adfddbe3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -104,8 +104,6 @@ - -