From 43f06d216786701a10edfb152f6b459b1f6e8552 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Jun 2023 14:26:52 -0500 Subject: [PATCH 01/46] feature: Add USB-C as eRoutingPortConnectionType option --- .../PepperDashEssentialsBase/Routing/RoutingPort.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs index 79dd4eda..8dc8fc4e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs @@ -42,7 +42,7 @@ namespace PepperDash.Essentials.Core public enum eRoutingPortConnectionType { None, BackplaneOnly, DisplayPort, Dvi, Hdmi, Rgb, Vga, LineAudio, DigitalAudio, Sdi, - Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming + Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming, UsbC } /// From 0ee6322684e62e1dec9b9d01a0eb0a4f3518e4e9 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Jun 2023 14:50:10 -0500 Subject: [PATCH 02/46] feature: Add USBCIn and Out Names for RoutingPortNames --- .../Routing/RoutingPortNames.cs | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs index 00e85191..beef0dae 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs @@ -199,5 +199,37 @@ namespace PepperDash.Essentials.Core.Routing /// MediaPlayer /// public const string MediaPlayer = "mediaPlayer"; - } + /// + /// UsbCIn + /// + public const string UsbCIn = "usbCIn"; + /// + /// UsbCIn1 + /// + public const string UsbCIn1 = "usbCIn1"; + /// + /// UsbCIn2 + /// + public const string UsbCIn2 = "usbCIn2"; + /// + /// UsbCIn3 + /// + public const string UsbCIn3 = "usbCIn3"; + /// + /// UsbCOut + /// + public const string UsbCOut = "usbCOut"; + /// + /// UsbCOut1 + /// + public const string UsbCOut1 = "usbCOut1"; + /// + /// UsbCOut2 + /// + public const string UsbCOut2 = "usbCOut2"; + /// + /// UsbCOut3 + /// + public const string UsbCOut3 = "usbCOut3"; + } } \ No newline at end of file From a04bfd1fcb172d20ef73fd31a08a3bb937fadada Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Jun 2023 14:56:21 -0500 Subject: [PATCH 03/46] feature: Add HdBaseTIn and HdBaseTOut as RoutingPortNames --- .../PepperDashEssentialsBase/Routing/RoutingPortNames.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs index beef0dae..7029443b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs @@ -231,5 +231,13 @@ namespace PepperDash.Essentials.Core.Routing /// UsbCOut3 /// public const string UsbCOut3 = "usbCOut3"; + /// + /// HdBaseTIn + /// + public const string HdBaseTIn = "hdBaseTIn"; + /// + /// HdBaseTOut + /// + public const string HdBaseTOut = "hdBaseTOut"; } } \ No newline at end of file From f4af1b6e7c853dc1df0e4f9d9319f3e64e190c8e Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Jun 2023 14:57:48 -0500 Subject: [PATCH 04/46] feature: Add HdBaseT as a eRoutingPortConnectionType --- .../PepperDashEssentialsBase/Routing/RoutingPort.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs index 8dc8fc4e..ab64f15e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs @@ -42,7 +42,7 @@ namespace PepperDash.Essentials.Core public enum eRoutingPortConnectionType { None, BackplaneOnly, DisplayPort, Dvi, Hdmi, Rgb, Vga, LineAudio, DigitalAudio, Sdi, - Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming, UsbC + Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming, UsbC, HdBaseT } /// From cab0b01a089f790c46509f0c0cd54a280b3ea93f Mon Sep 17 00:00:00 2001 From: jdevito Date: Tue, 27 Jun 2023 15:20:01 -0500 Subject: [PATCH 05/46] fix: updates systemMonitor class to append Essentials version number to the ProgramName that is passed across the bridge --- .../Monitoring/SystemMonitorController.cs | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index 319a0a3c..8a7f379a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -563,11 +563,11 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramUnregisteredFeedback = new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); ProgramUnregisteredFeedback.FireUpdate(); - - ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + + ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); + EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); - CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); - EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); GetProgramInfo(); @@ -620,9 +620,9 @@ namespace PepperDash.Essentials.Core.Monitoring // Assume no valid program info. Constructing a new object will wipe all properties ProgramInfo = new ProgramInfo(Program.Number) { - OperatingState = Program.OperatingState, + OperatingState = Program.OperatingState, RegistrationState = Program.RegistrationState - }; + }; UpdateFeedbacks(); @@ -639,13 +639,20 @@ namespace PepperDash.Essentials.Core.Monitoring if (ProgramInfo.ProgramFile.Contains(".dll")) { - // SSP Program + // SSP Program ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", "\n"); ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); + + ProgramInfo.ProgramFile += string.Format(" {0}.{1}.{2}", + ProgramInfo.CompilerRevisionInfo.Major, + ProgramInfo.CompilerRevisionInfo.Minor, + ProgramInfo.CompilerRevisionInfo.Build); + + ProgramInfo.Environment = ProgramInfo.ProgramTool; } else if (ProgramInfo.ProgramFile.Contains(".smw")) { @@ -736,6 +743,15 @@ namespace PepperDash.Essentials.Core.Monitoring [JsonProperty("compilerRevision")] public string CompilerRevision { get; set; } + [JsonIgnore] + public Version CompilerRevisionInfo + { + get + { + return new Version(CompilerRevision); + } + } + [JsonProperty("compileTime")] public string CompileTime { get; set; } @@ -776,7 +792,7 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramFile = ""; FriendlyName = ""; CompilerRevision = ""; - CompileTime = ""; + CompileTime = ""; Include4Dat = ""; SystemName = ""; From 3f6b2f05a28dab2bf0e394bf70d9c4d428cf1921 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Tue, 4 Jul 2023 23:53:31 -0500 Subject: [PATCH 06/46] feature: Add Static Class to assist with getting network information about connected devices feature: Add overload to 'Contains' extension method to allow for some more verbose comparisons feature: Add 'TrimAll' string extension method to TrimStart and TrimEnd with an overload to set the character to trim docs: improve XML summary comments for string extensions --- .../Device Info/NetworkDeviceHelpers.cs | 218 ++++++++++++++++++ .../Extensions/StringExtensions.cs | 54 +++++ .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 273 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs new file mode 100644 index 00000000..04e697c9 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PepperDash.Core; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.DeviceInfo +{ + public static class NetworkDeviceHelpers + { + /// + /// Event raised when ArpTable changes + /// + public static event ArpTableEventHandler ArpTableUpdated; + + /// + /// Delegate called by ArpTableUpdated + /// + /// contains the entire ARP table and a bool to note if there was an error in retrieving the data + public delegate void ArpTableEventHandler(ArpTableEventArgs args); + + private static readonly char NewLineSplitter = CrestronEnvironment.NewLine.ToCharArray().First(); + private static readonly string NewLine = CrestronEnvironment.NewLine; + + private static readonly CCriticalSection Lock = new CCriticalSection(); + + /// + /// Last resolved ARP table - it is recommended to refresh the arp before using this. + /// + public static List ArpTable { get; private set; } + + /// + /// Force recheck of ARP table + /// + public static void RefreshArp() + { + var error = false; + try + { + Lock.Enter(); + var consoleResponse = string.Empty; + if (!CrestronConsole.SendControlSystemCommand("showarptable", ref consoleResponse)) return; + if (string.IsNullOrEmpty(consoleResponse)) + { + error = true; + return; + } + ArpTable.Clear(); + + Debug.Console(2, "ConsoleResponse of 'showarptable' : {0}{1}", NewLine, consoleResponse); + + var myLines = + consoleResponse.Split(NewLineSplitter) + .ToList() + .Where(o => (o.Contains(':') && !o.Contains("Type", StringComparison.OrdinalIgnoreCase))) + .ToList(); + foreach (var line in myLines) + { + var item = line; + var seperator = item.Contains('\t') ? '\t' : ' '; + var dataPoints = item.Split(seperator); + if (dataPoints == null || dataPoints.Length < 2) continue; + var ipAddress = SanitizeIpAddress(dataPoints.First().TrimAll()); + var macAddress = dataPoints.Last(); + ArpTable.Add(new ArpEntry(ipAddress, macAddress)); + } + } + catch (Exception ex) + { + Debug.Console(0, "Exception in \"RefreshArp\" : {0}", ex.Message); + error = true; + } + finally + { + Lock.Leave(); + OnArpTableUpdated(new ArpTableEventArgs(ArpTable, error)); + } + } + + + private static void OnArpTableUpdated(ArpTableEventArgs args) + { + if (args == null) return; + var handler = ArpTableUpdated; + if (handler == null) return; + handler.Invoke(args); + } + + static NetworkDeviceHelpers() + { + ArpTable = new List(); + } + + /// + /// Removes leading zeros, leading whitespace, and trailing whitespace from an IPAddress string + /// + /// Ip Address to Santitize + /// Sanitized Ip Address + public static string SanitizeIpAddress(string ipAddressIn) + { + try + { + var ipAddress = IPAddress.Parse(ipAddressIn.TrimStart('0')); + return ipAddress.ToString(); + } + catch (Exception ex) + { + Debug.Console(0, "Unable to Santize Ip : {0}", ex.Message); + return ipAddressIn; + } + } + + /// + /// Resolves a hostname by IP Address using DNS + /// + /// IP Address to resolve from + /// Resolved Hostname - on failure to determine hostname, will return IP Address + public static string ResolveHostnameFromIp(string ipAddress) + { + try + { + var santitizedIp = SanitizeIpAddress(ipAddress); + var hostEntry = Dns.GetHostEntry(santitizedIp); + return hostEntry == null ? ipAddress : hostEntry.HostName; + } + catch (Exception ex) + { + Debug.Console(0, "Exception Resolving Hostname from IP Address : {0}", ex.Message); + return ipAddress; + } + } + + /// + /// Resolves an IP Address by hostname using DNS + /// + /// Hostname to resolve from + /// Resolved IP Address - on a failure to determine IP Address, will return hostname + public static string ResolveIpFromHostname(string hostName) + { + try + { + var hostEntry = Dns.GetHostEntry(hostName); + return hostEntry == null ? hostName : hostEntry.AddressList.First().ToString(); + } + catch (Exception ex) + { + Debug.Console(0, "Exception Resolving IP Address from Hostname : {0}", ex.Message); + return hostName; + } + } + + } + + /// + /// Object to hold data about an arp entry + /// + public class ArpEntry + { + public readonly IPAddress IpAddress; + public readonly string MacAddress; + + /// + /// Constructs new ArpEntry object + /// + /// string formatted as ipv4 address + /// mac address string - format is unimportant + public ArpEntry(string ipAddress, string macAddress) + { + if (string.IsNullOrEmpty(ipAddress)) + { + throw new ArgumentException("\"ipAddress\" cannot be null or empty"); + } + if (string.IsNullOrEmpty(macAddress)) + { + throw new ArgumentException("\"macAddress\" cannot be null or empty"); + } + IpAddress = IPAddress.Parse(ipAddress.TrimStart().TrimStart('0').TrimEnd()); + MacAddress = macAddress; + } + } + + /// + /// Arguments passed by the ArpTableUpdated event + /// + public class ArpTableEventArgs : EventArgs + { + /// + /// The retrieved ARP Table + /// + public readonly List ArpTable; + /// + /// True if there was a problem retrieving the ARP Table + /// + public readonly bool Error; + + /// + /// Constructor for ArpTableEventArgs + /// + /// The entirety of the retrieved ARP table + /// True of an error was encountered updating the ARP table + public ArpTableEventArgs(List arpTable, bool error) + { + ArpTable = arpTable; + Error = error; + } + + /// + /// Constructor for ArpTableEventArgs - assumes no error encountered in retrieving ARP Table + /// + /// The entirety of the retrieved ARP table + public ArpTableEventArgs(List arpTable) + { + ArpTable = arpTable; + Error = false; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs index 39501387..7bf8d5a5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,17 +9,70 @@ namespace PepperDash.Essentials.Core { public static class StringExtensions { + /// + /// Returns null if a string is empty, otherwise returns the string + /// + /// string input + /// null if the string is emtpy, otherwise returns the string public static string NullIfEmpty(this string s) { return string.IsNullOrEmpty(s) ? null : s; } + + /// + /// Returns null if a string is empty or made of only whitespace characters, otherwise returns the string + /// + /// string input + /// null if the string is wempty or made of only whitespace characters, otherwise returns the string public static string NullIfWhiteSpace(this string s) { return string.IsNullOrEmpty(s.Trim()) ? null : s; } + + /// + /// Returns a replacement string if the input string is empty or made of only whitespace characters, otherwise returns the input string + /// + /// input string + /// string to replace with if input string is empty or whitespace + /// returns newString if s is null, emtpy, or made of whitespace characters, otherwise returns s public static string ReplaceIfNullOrEmpty(this string s, string newString) { return string.IsNullOrEmpty(s) ? newString : s; } + + /// + /// Overload for Contains that allows setting an explicit String Comparison + /// + /// Source String + /// String to check in Source String + /// Comparison parameters + /// true of string contains "toCheck" + public static bool Contains(this string source, string toCheck, StringComparison comp) + { + if (string.IsNullOrEmpty(source)) return false; + return source.IndexOf(toCheck, comp) >= 0; + } + + /// + /// Performs TrimStart() and TrimEnd() on source string + /// + /// String to Trim + /// Trimmed String + public static string TrimAll(this string source) + { + return string.IsNullOrEmpty(source) ? string.Empty : source.TrimStart().TrimEnd(); + } + + /// + /// Performs TrimStart(chars char[]) and TrimEnd(chars char[]) on source string. + /// + /// String to Trim + /// Char Array to trim from string + /// Trimmed String + public static string TrimAll(this string source, char[] chars) + { + return string.IsNullOrEmpty(source) ? string.Empty : source.TrimStart(chars).TrimEnd(chars); + } + } } \ 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 7930f49e..aff99ea7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -200,6 +200,7 @@ + From 97c0bddb48aa4ed3dbdc82cd2fc231c7daa3ae86 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 11 Sep 2023 14:49:46 -0500 Subject: [PATCH 07/46] fix(wip): refactors SetupInputs() and SetupOutputs() to handle io types --- .../Chassis/HdPsXxxController.cs | 192 ++++++++---------- 1 file changed, 80 insertions(+), 112 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index d923949e..9884be8e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -21,8 +21,6 @@ namespace PepperDash_Essentials_DM.Chassis { private readonly HdPsXxx _chassis; - private readonly HdPs401 _chassis401; - private readonly HdPs621 _chassis621; public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -63,33 +61,35 @@ namespace PepperDash_Essentials_DM.Chassis return; } - InputPorts = new RoutingPortCollection(); + InputPorts = new RoutingPortCollection(); InputNameFeedbacks = new FeedbackCollection(); InputHdcpEnableFeedback = new FeedbackCollection(); - InputNames = new Dictionary(); - //InputNames = props.Inputs; + InputNames = new Dictionary(); 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; + //if (_chassis is HdPs401) + // _chassis401 = _chassis as HdPs401; + //if (_chassis is HdPs621) + // _chassis621 = _chassis as HdPs621; - AutoRouteFeedback = new BoolFeedback(() => _chassis401.PriorityRouteOnFeedback.BoolValue); + AutoRouteFeedback = new BoolFeedback(() => _chassis.PriorityRouteOnFeedback.BoolValue); } - SetupInputs(props.Inputs); - SetupOutputs(props.Outputs); + + InputNames = props.Inputs; + SetupInputs(InputNames); + + OutputNames = props.Outputs; + SetupOutputs(OutputNames); AddPostActivationAction(AddFeedbackCollecitons); } @@ -106,35 +106,49 @@ namespace PepperDash_Essentials_DM.Chassis { Debug.Console(1, this, "props.Input[{0}]: {1}", kvp.Key, kvp.Value); } - InputNames = dict; - for (uint i = 1; i <= _chassis.NumberOfInputs; i++) + foreach (var item in _chassis.HdmiInputs) { - 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]; - + var input = item; + var index = item.Number; + var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("HDMI Input {0}", index) : InputNames[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)); + InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); } - _chassis.DMInputChange += _chassis_InputChange; + foreach (var item in _chassis.DmLiteInputs) + { + var input = item; + var index = item.Number; + + var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("DM Input {0}", index) : InputNames[index]; + input.Name.StringValue = name; + + InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); + + var port = new RoutingInputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) + { + FeedbackMatchObject = input + }; + InputPorts.Add(port); + + + InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); + + VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + } + + _chassis.DMInputChange += _chassis_InputChange; } // output setup @@ -149,20 +163,14 @@ namespace PepperDash_Essentials_DM.Chassis { Debug.Console(1, this, "props.Output[{0}]: {1}", kvp.Key, kvp.Value); } - OutputNames = dict; - for (uint i = 1; i <= _chassis.NumberOfOutputs; i++) + foreach (var item in _chassis.HdmiDmLiteOutputs) { - var index = i; + var output = item; + var index = item.Number; + 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) { @@ -206,10 +214,6 @@ namespace PepperDash_Essentials_DM.Chassis _chassis.OnlineStatusChange += _chassis_OnlineStatusChange; - if (_chassis401 != null) LinkChassis401ToApi(trilist, joinMap); - - if (_chassis621 != null) LinkChassis621ToApi(trilist, joinMap); - LinkChassisInputsToApi(trilist, joinMap); LinkChassisOutputsToApi(trilist, joinMap); @@ -252,36 +256,17 @@ namespace PepperDash_Essentials_DM.Chassis var indexWithOffset = output - 1; trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + indexWithOffset, (a) => - ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); + 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 @@ -359,17 +344,9 @@ namespace PepperDash_Essentials_DM.Chassis /// public void EnableAutoRoute() { - if (_chassis.NumberOfInputs != 1) return; + if (_chassis.NumberOfInputs == 1) return; - if (_chassis401 != null) - { - _chassis401.AutoRouteOn(); - } - - if (_chassis621 != null) - { - _chassis621.AutoRouteOn(); - } + _chassis.AutoRouteOn(); } @@ -378,20 +355,12 @@ namespace PepperDash_Essentials_DM.Chassis /// public void DisableAutoRoute() { - if (_chassis.NumberOfInputs != 1) return; + if (_chassis.NumberOfInputs == 1) return; - if (_chassis401 != null) - { - _chassis401.AutoRouteOff(); - } - - if (_chassis621 != null) - { - _chassis621.AutoRouteOff(); - } + _chassis.AutoRouteOff(); } - #region Events + #region Events // _chassis online/offline event @@ -417,31 +386,31 @@ namespace PepperDash_Essentials_DM.Chassis switch (eventId) { case DMInputEventIds.VideoDetectedEventId: - { - Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", eventId); - foreach (var item in VideoInputSyncFeedbacks) { - item.FireUpdate(); + Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", eventId); + foreach (var item in VideoInputSyncFeedbacks) + { + item.FireUpdate(); + } + break; } - break; - } case DMInputEventIds.InputNameFeedbackEventId: case DMInputEventIds.InputNameEventId: case DMInputEventIds.NameFeedbackEventId: - { - Debug.Console(1, this, "Event ID {0}: Updating name feedbacks", eventId); + { + Debug.Console(1, this, "Event ID {0}: Updating name feedbacks", eventId); - var input = args.Number; - var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; + var input = args.Number; + var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; - Debug.Console(1, this, "Input {0} Name {1}", input, name); - break; - } + Debug.Console(1, this, "Input {0} Name {1}", input, name); + break; + } default: - { - Debug.Console(1, this, "Uhandled DM Input Event ID {0}", eventId); - break; - } + { + Debug.Console(1, this, "Uhandled DM Input Event ID {0}", eventId); + break; + } } } @@ -493,7 +462,7 @@ namespace PepperDash_Essentials_DM.Chassis /// - /// Add feedback colleciton arrays to feedback collections + /// Add feedback collection arrays to feedback collections /// /// BoolFeedback[] arrays public void AddCollectionsToList(params FeedbackCollection[] feedbackCollections) @@ -587,10 +556,10 @@ namespace PepperDash_Essentials_DM.Chassis /// public void AddFeedbackCollecitons() { - AddFeedbackToList(DeviceNameFeedback); - AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); - AddCollectionsToList(VideoOutputRouteFeedbacks); - AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedback); + //AddFeedbackToList(DeviceNameFeedback); + //AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); + //AddCollectionsToList(VideoOutputRouteFeedbacks); + //AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedback); } @@ -608,7 +577,11 @@ namespace PepperDash_Essentials_DM.Chassis } public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.Console(1, "Factory Attempting to create new HD-PSXxx device"); + var key = dc.Key; + var name = dc.Name; + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new {0} device", type); var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); if (props == null) @@ -617,12 +590,7 @@ namespace PepperDash_Essentials_DM.Chassis 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; + var ipid = props.Control.IpIdInt; switch (type) { From 08af6370a6124800aacca276b4ec6a56d597e64f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 11 Sep 2023 15:48:34 -0500 Subject: [PATCH 08/46] fix(wip): adds Debug.Console() statements to identify keys per input; adds ICec interface, pending implementation --- .../Chassis/HdPsXxxController.cs | 164 +++++------------- 1 file changed, 41 insertions(+), 123 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 9884be8e..f4c725f0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -17,7 +17,7 @@ using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis { [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, ICec, IHasHdmiInHdcp, IHasFeedback { private readonly HdPsXxx _chassis; @@ -75,15 +75,7 @@ namespace PepperDash_Essentials_DM.Chassis 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(() => _chassis.PriorityRouteOnFeedback.BoolValue); - } - InputNames = props.Inputs; SetupInputs(InputNames); @@ -91,7 +83,7 @@ namespace PepperDash_Essentials_DM.Chassis OutputNames = props.Outputs; SetupOutputs(OutputNames); - AddPostActivationAction(AddFeedbackCollecitons); + //AddPostActivationAction(); } // input setup @@ -107,6 +99,20 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "props.Input[{0}]: {1}", kvp.Key, kvp.Value); } + // TODO [ ] testing + var hdmiKeys = _chassis.HdmiInputs.Keys; + foreach (var key in hdmiKeys) + { + Debug.Console(0, this, "HDMI Input key-'{0}'", key); + } + + var dmKeys = _chassis.DmLiteInputs.Keys; + foreach (var key in dmKeys) + { + Debug.Console(0, this, "DM Input key-'{0}'", key); + } + + foreach (var item in _chassis.HdmiInputs) { var input = item; @@ -123,7 +129,7 @@ namespace PepperDash_Essentials_DM.Chassis InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); } foreach (var item in _chassis.DmLiteInputs) @@ -164,9 +170,17 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "props.Output[{0}]: {1}", kvp.Key, kvp.Value); } + + // TODO [ ] testing + var keys = _chassis.HdmiDmLiteOutputs.Keys; + foreach (var key in keys) + { + Debug.Console(0, this, "HdmiDmLite Output key-'{0}'", key); + } + foreach (var item in _chassis.HdmiDmLiteOutputs) { - var output = item; + var output = item; var index = item.Number; var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) : OutputNames[index]; @@ -182,7 +196,7 @@ namespace PepperDash_Essentials_DM.Chassis VideoOutputRouteFeedbacks.Add(new IntFeedback(name, () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); } - + _chassis.DMOutputChange += _chassis_OutputChange; } @@ -268,7 +282,7 @@ namespace PepperDash_Essentials_DM.Chassis } #endregion - + /// /// Executes a device switch using objects @@ -455,115 +469,7 @@ namespace PepperDash_Essentials_DM.Chassis } - #endregion - - - #region FeedbacksAndFeedbackCollections - - - /// - /// Add feedback collection 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 + #endregion #region Factory @@ -621,5 +527,17 @@ namespace PepperDash_Essentials_DM.Chassis #endregion + + // TODO [ ] Implement CEC control + // return _chassis.HdmiDmLiteOutputs[0].DmLiteOutput.DmLiteOutputPort.StreamCec; + public Cec StreamCec { get; private set; } + + public IntFeedback HdmiInHdcpStateFeedback { get; private set; } + public void SetHdmiInHdcpState(eHdcpCapabilityType hdcpState) + { + throw new NotImplementedException(); + } + + public eHdcpCapabilityType HdmiInHdcpCapability { get; private set; } } } \ No newline at end of file From 4e33743f5015742798a556096b61d47905a777eb Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 11 Sep 2023 19:24:21 -0500 Subject: [PATCH 09/46] refactor: SetupInput() and SetupOutput() methods to set standard keys for ports that are instantiated --- .../Chassis/HdPsXxxController.cs | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index f4c725f0..8bfab826 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -1,8 +1,6 @@ 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; @@ -19,7 +17,6 @@ namespace PepperDash_Essentials_DM.Chassis [Description("Wrapper class for all HdPsXxx switchers")] public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, ICec, IHasHdmiInHdcp, IHasFeedback { - private readonly HdPsXxx _chassis; public RoutingPortCollection InputPorts { get; private set; } @@ -99,32 +96,20 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "props.Input[{0}]: {1}", kvp.Key, kvp.Value); } - // TODO [ ] testing - var hdmiKeys = _chassis.HdmiInputs.Keys; - foreach (var key in hdmiKeys) - { - Debug.Console(0, this, "HDMI Input key-'{0}'", key); - } - - var dmKeys = _chassis.DmLiteInputs.Keys; - foreach (var key in dmKeys) - { - Debug.Console(0, this, "DM Input key-'{0}'", key); - } - - foreach (var item in _chassis.HdmiInputs) { var input = item; var index = item.Number; + var key = string.Format("hdmiIn{0}", index); var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("HDMI Input {0}", index) : InputNames[index]; InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); - var port = new RoutingInputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) + var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) { FeedbackMatchObject = input }; + Debug.Console(1, this, "Adding HDMI Input port: {0}", port.Key); InputPorts.Add(port); InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); @@ -136,7 +121,7 @@ namespace PepperDash_Essentials_DM.Chassis { var input = item; var index = item.Number; - + var key = string.Format("dmLiteIn{0}", index); var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("DM Input {0}", index) : InputNames[index]; input.Name.StringValue = name; @@ -146,8 +131,8 @@ namespace PepperDash_Essentials_DM.Chassis { FeedbackMatchObject = input }; + Debug.Console(0, this, "Adding DM Input port: {0}",port.Key); InputPorts.Add(port); - InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); @@ -170,26 +155,22 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "props.Output[{0}]: {1}", kvp.Key, kvp.Value); } - - // TODO [ ] testing - var keys = _chassis.HdmiDmLiteOutputs.Keys; - foreach (var key in keys) - { - Debug.Console(0, this, "HdmiDmLite Output key-'{0}'", key); - } - foreach (var item in _chassis.HdmiDmLiteOutputs) { - var output = item; + var output = item; var index = item.Number; - + var key = string.Format("hdmiDmLiteOut{0}", index); var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) : OutputNames[index]; output.Name.StringValue = name; - var port = new RoutingOutputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) + var port = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) { - FeedbackMatchObject = output + FeedbackMatchObject = output, + // set port for CEC + Port = output }; + Debug.Console(0, this, "Adding HdmiDmLite Output port: {0} {1}", + port.Key, port.ParentDevice); OutputPorts.Add(port); OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); @@ -530,7 +511,16 @@ namespace PepperDash_Essentials_DM.Chassis // TODO [ ] Implement CEC control // return _chassis.HdmiDmLiteOutputs[0].DmLiteOutput.DmLiteOutputPort.StreamCec; - public Cec StreamCec { get; private set; } + public Cec StreamCec + { + get + { + return _chassis.NumberOfOutputs == 1 + //? _chassis.HdmiDmLiteOutputs[0].DmLiteOutput.DmLiteOutputPort.StreamCec + ? _chassis.HdmiDmLiteOutputs[0].HdmiOutput.HdmiOutputPort.StreamCec + : null; + } + } public IntFeedback HdmiInHdcpStateFeedback { get; private set; } public void SetHdmiInHdcpState(eHdcpCapabilityType hdcpState) From 27bac4e83dfd83fdc46a861c1f113f072e73e76e Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 10:09:37 -0500 Subject: [PATCH 10/46] fix(wip): updates stream cec implementation to handle switchers with multiple outputs --- .../Chassis/HdPsXxxController.cs | 76 +++++++++++-------- 1 file changed, 43 insertions(+), 33 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 8bfab826..c7ef719c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -15,7 +15,7 @@ using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis { [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, ICec, IHasHdmiInHdcp, IHasFeedback + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback { private readonly HdPsXxx _chassis; @@ -61,7 +61,7 @@ namespace PepperDash_Essentials_DM.Chassis InputPorts = new RoutingPortCollection(); InputNameFeedbacks = new FeedbackCollection(); InputHdcpEnableFeedback = new FeedbackCollection(); - InputNames = new Dictionary(); + InputNames = new Dictionary(); OutputPorts = new RoutingPortCollection(); OutputNameFeedbacks = new FeedbackCollection(); @@ -79,8 +79,6 @@ namespace PepperDash_Essentials_DM.Chassis OutputNames = props.Outputs; SetupOutputs(OutputNames); - - //AddPostActivationAction(); } // input setup @@ -102,19 +100,19 @@ namespace PepperDash_Essentials_DM.Chassis var index = item.Number; var key = string.Format("hdmiIn{0}", index); var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("HDMI Input {0}", index) : InputNames[index]; - + InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) { FeedbackMatchObject = input }; - Debug.Console(1, this, "Adding HDMI Input port: {0}", port.Key); + Debug.Console(1, this, "Adding Input port: {0}", port.Key); InputPorts.Add(port); InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); } foreach (var item in _chassis.DmLiteInputs) @@ -127,13 +125,13 @@ namespace PepperDash_Essentials_DM.Chassis InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); - var port = new RoutingInputPort(name, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) + var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) { FeedbackMatchObject = input }; - Debug.Console(0, this, "Adding DM Input port: {0}",port.Key); + Debug.Console(0, this, "Adding Input port: {0}", port.Key); InputPorts.Add(port); - + InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); @@ -169,15 +167,35 @@ namespace PepperDash_Essentials_DM.Chassis // set port for CEC Port = output }; - Debug.Console(0, this, "Adding HdmiDmLite Output port: {0} {1}", - port.Key, port.ParentDevice); + Debug.Console(0, this, "Adding Output port: {0}", port.Key); 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)); + + // TODO [ ] Investigate setting input priorities per output + // {{in1-priority-level}, {in2-priority-level}, .... {in6-priority-level}} + // default priority level input 1-4 ascending + output.OutputPort.InputPriorities(new byte[] { 1, 2, 3, 4 }); + + if (port.Port == null) continue; + + var hdmiOutputStreamCec = output.HdmiOutput.HdmiOutputPort.StreamCec; + if (hdmiOutputStreamCec != null) + { + var streamCec = new StreamCecWrapper(string.Format("{0}-hdmiOut{1}-streamCec", Key, index), hdmiOutputStreamCec); + DeviceManager.AddDevice(streamCec); + } + + var dmLiteOutputStreamCec = output.DmLiteOutput.DmLiteOutputPort.StreamCec; + if (dmLiteOutputStreamCec != null) + { + var streamCec = new StreamCecWrapper(string.Format("{0}-dmLiteOut{1}-streamCec", Key, index), dmLiteOutputStreamCec); + DeviceManager.AddDevice(streamCec); + } } - + _chassis.DMOutputChange += _chassis_OutputChange; } @@ -263,7 +281,7 @@ namespace PepperDash_Essentials_DM.Chassis } #endregion - + /// /// Executes a device switch using objects @@ -450,7 +468,7 @@ namespace PepperDash_Essentials_DM.Chassis } - #endregion + #endregion #region Factory @@ -508,26 +526,18 @@ namespace PepperDash_Essentials_DM.Chassis #endregion + } - // TODO [ ] Implement CEC control - // return _chassis.HdmiDmLiteOutputs[0].DmLiteOutput.DmLiteOutputPort.StreamCec; - public Cec StreamCec + + public class StreamCecWrapper : IKeyed, ICec + { + public string Key { get; private set; } + public Cec StreamCec { get; private set; } + + public StreamCecWrapper(string key, Cec streamCec) { - get - { - return _chassis.NumberOfOutputs == 1 - //? _chassis.HdmiDmLiteOutputs[0].DmLiteOutput.DmLiteOutputPort.StreamCec - ? _chassis.HdmiDmLiteOutputs[0].HdmiOutput.HdmiOutputPort.StreamCec - : null; - } + Key = key; + StreamCec = streamCec; } - - public IntFeedback HdmiInHdcpStateFeedback { get; private set; } - public void SetHdmiInHdcpState(eHdcpCapabilityType hdcpState) - { - throw new NotImplementedException(); - } - - public eHdcpCapabilityType HdmiInHdcpCapability { get; private set; } } } \ No newline at end of file From 1aa95905872d5007f11ed7c55ba33184c30fa63c Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 13:23:18 -0500 Subject: [PATCH 11/46] feature: adds DmInputChange event --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index c7ef719c..1c6f8781 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -38,6 +38,7 @@ namespace PepperDash_Essentials_DM.Chassis public BoolFeedback AutoRouteFeedback { get; private set; } public event EventHandler NumericSwitchChange; + public event EventHandler DmInputChange; /// /// Constructor @@ -425,6 +426,8 @@ namespace PepperDash_Essentials_DM.Chassis break; } } + + OnDmInputChange(args); } @@ -457,16 +460,20 @@ namespace PepperDash_Essentials_DM.Chassis } - /// - /// Raise an event when the status of a switch object changes. - /// - /// Argumetns defined as IKeyName sender, output, input, & eRoutingSignalType + // Raise an event when the status of a switch object changes. private void OnSwitchChange(RoutingNumericEventArgs args) { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, args); } + // Raise an event when the DM input changes. + private void OnDmInputChange(DMInputEventArgs args) + { + var newEvent = DmInputChange; + if (newEvent != null) newEvent(this, args); + } + #endregion From da5d2d74f29d7be3a02f9147399fe8fb3420f4f8 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 14:36:17 -0500 Subject: [PATCH 12/46] fix: removes OutputPort.InputPriorities reference --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 1c6f8781..7c1e0431 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -10,6 +10,7 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash_Essentials_Core.Bridges; +using PepperDash_Essentials_DM; using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis @@ -173,12 +174,14 @@ namespace PepperDash_Essentials_DM.Chassis OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); - VideoOutputRouteFeedbacks.Add(new IntFeedback(name, () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); + VideoOutputRouteFeedbacks.Add(new IntFeedback(name, + () => output.VideoOutFeedback == null ? 0 : (int) output.VideoOutFeedback.Number)); // TODO [ ] Investigate setting input priorities per output // {{in1-priority-level}, {in2-priority-level}, .... {in6-priority-level}} - // default priority level input 1-4 ascending - output.OutputPort.InputPriorities(new byte[] { 1, 2, 3, 4 }); + // default priority level input 1-4 ascending + //var priorities = new byte[] {1,2,3,4}; + //output.OutputPort.InputPriorities(priorities); if (port.Port == null) continue; From 189c4706030e4d5cf8c1de496aee94130ef00b02 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 17:10:25 -0500 Subject: [PATCH 13/46] feature(wip): adds inputPriorities configuration property --- .../Chassis/HdPsXxxController.cs | 22 ++++++++++++++----- .../Config/HdPsXxxPropertiesConfig.cs | 12 +++++----- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 7c1e0431..2e998133 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -10,7 +10,6 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash_Essentials_Core.Bridges; -using PepperDash_Essentials_DM; using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis @@ -19,6 +18,7 @@ namespace PepperDash_Essentials_DM.Chassis public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback { private readonly HdPsXxx _chassis; + private byte[] _inputPriorityParams; public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -76,6 +76,12 @@ namespace PepperDash_Essentials_DM.Chassis if (_chassis.NumberOfOutputs == 1) AutoRouteFeedback = new BoolFeedback(() => _chassis.PriorityRouteOnFeedback.BoolValue); + if (props.InputPriorities != null) + { + _inputPriorityParams = new byte[_chassis.NumberOfInputs]; + _inputPriorityParams = GetInputPriorities(props); + } + InputNames = props.Inputs; SetupInputs(InputNames); @@ -83,6 +89,12 @@ namespace PepperDash_Essentials_DM.Chassis SetupOutputs(OutputNames); } + // get input priorities + private byte[] GetInputPriorities(HdPsXxxPropertiesConfig props) + { + throw new NotImplementedException(); + } + // input setup private void SetupInputs(Dictionary dict) { @@ -175,13 +187,13 @@ namespace PepperDash_Essentials_DM.Chassis OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); VideoOutputRouteFeedbacks.Add(new IntFeedback(name, - () => output.VideoOutFeedback == null ? 0 : (int) output.VideoOutFeedback.Number)); + () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); // TODO [ ] Investigate setting input priorities per output // {{in1-priority-level}, {in2-priority-level}, .... {in6-priority-level}} - // default priority level input 1-4 ascending - //var priorities = new byte[] {1,2,3,4}; - //output.OutputPort.InputPriorities(priorities); + // default priority level input 1-4 ascending + if (_inputPriorityParams != null && _inputPriorityParams.Count() > 0) + output.OutputPort.InputPriorities(_inputPriorityParams); if (port.Port == null) continue; diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs index c02fc511..576b74f0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; using PepperDash.Core; -using PepperDash.Essentials.DM.Config; namespace PepperDash_Essentials_DM.Config { @@ -11,18 +10,17 @@ 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; } + // "inputPriorities": "1,4,3,2" + [JsonProperty("inputPriorities")] + public string InputPriorities { get; set; } + public HdPsXxxPropertiesConfig() { - //Inputs = new Dictionary(); - //Outputs = new Dictionary(); - Inputs = new Dictionary(); Outputs = new Dictionary(); } From e590c7cedb251cf4b324b4e4a43bd49afaf0c85b Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 12 Sep 2023 19:26:55 -0500 Subject: [PATCH 14/46] feature(wip): adds inputPriorities configuration property --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 2e998133..bba85d25 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -18,7 +18,7 @@ namespace PepperDash_Essentials_DM.Chassis public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback { private readonly HdPsXxx _chassis; - private byte[] _inputPriorityParams; + //private byte[] _inputPriorityParams; public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -76,11 +76,11 @@ namespace PepperDash_Essentials_DM.Chassis if (_chassis.NumberOfOutputs == 1) AutoRouteFeedback = new BoolFeedback(() => _chassis.PriorityRouteOnFeedback.BoolValue); - if (props.InputPriorities != null) - { - _inputPriorityParams = new byte[_chassis.NumberOfInputs]; - _inputPriorityParams = GetInputPriorities(props); - } + //if (props.InputPriorities != null) + //{ + // _inputPriorityParams = new byte[_chassis.NumberOfInputs]; + // _inputPriorityParams = GetInputPriorities(props); + //} InputNames = props.Inputs; SetupInputs(InputNames); @@ -192,8 +192,8 @@ namespace PepperDash_Essentials_DM.Chassis // TODO [ ] Investigate setting input priorities per output // {{in1-priority-level}, {in2-priority-level}, .... {in6-priority-level}} // default priority level input 1-4 ascending - if (_inputPriorityParams != null && _inputPriorityParams.Count() > 0) - output.OutputPort.InputPriorities(_inputPriorityParams); + //if (_inputPriorityParams != null && _inputPriorityParams.Count() > 0) + // output.OutputPort.InputPriorities(_inputPriorityParams); if (port.Port == null) continue; From 334a62c32943d80337f9a382fe934a4af337662b Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 08:32:07 -0500 Subject: [PATCH 15/46] fix: wraps GetDeviceForKey and GetFeedbackProperty methods in a try/catch --- .../Touchpanels/Mpc3Touchpanel.cs | 73 ++++++++++++------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index f4611a70..f1153879 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using Crestron.SimplSharpPro; using Newtonsoft.Json; @@ -27,6 +28,7 @@ namespace PepperDash.Essentials.Core.Touchpanels } _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange; + _buttons = buttons; if (_buttons == null) { @@ -55,6 +57,8 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public void InitializeButton(string key, KeypadButton config) { + Debug.Console(1, this, "Initializing button '{0}'...", key); + if (config == null) { Debug.Console(1, this, "Button '{0}' config is null, unable to initialize", key); @@ -131,6 +135,8 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public void InitializeButtonFeedback(string key, KeypadButton config) { + Debug.Console(1, this, "Initializing button '{0}' feedback...", key); + if (config == null) { Debug.Console(1, this, "Button '{0}' config is null, unable to initialize feedback", key); @@ -144,37 +150,54 @@ namespace PepperDash.Essentials.Core.Touchpanels var buttonFeedback = config.Feedback; if (buttonFeedback == null) { - Debug.Console(1, this, "Button '{0}' feedback not configured and will not be implemented. Verify feedback is configured if required.", key); + Debug.Console(1, this, "Button '{0}' feedback not configured and will not be implemented. If feedback is required, verify configuration.", + key); return; } - var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; - if (device == null) + Feedback deviceFeedback = null; + + try { - 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); + var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; + if (device == null) + { + Debug.Console(1, this, "Button '{0}' feedback with deviceKey '{1}' not found, feedback will not be implemented. Verify feedback deviceKey is properly configured.", + key, buttonFeedback.DeviceKey); + return; + } + + // TODO [ ] verify if this can replace the current method + 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; + // } + //} + } + catch (Exception ex) + { + Debug.Console(0, this, "Failed to initialize button '{0}' feedback with deviceKey '{1}'. If feedback is required, verify configuration.", + key, buttonFeedback.DeviceKey); + + Debug.Console(1, this, "InitializeButtonFeedback Exception Message: {0}", ex.Message); + Debug.Console(2, this, "InitializeButtonFeedback Exception StackTrace: {0}", ex.StackTrace); + if (ex.InnerException != null) Debug.Console(2, this, "InitializeButtonFeedback Exception InnerExceptioni: {0}", ex.InnerException); + return; } - // 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 boolFeedback = deviceFeedback as BoolFeedback; var intFeedback = deviceFeedback as IntFeedback; From 0fad667fabfc1fc5f1776cd6891c228254ed38e0 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 08:56:13 -0500 Subject: [PATCH 16/46] fix: adds additional debug statements when attempting to get feedback property for device --- .../Touchpanels/Mpc3Touchpanel.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index f1153879..296965f9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -155,7 +155,7 @@ namespace PepperDash.Essentials.Core.Touchpanels return; } - Feedback deviceFeedback = null; + Feedback deviceFeedback; try { @@ -166,9 +166,16 @@ namespace PepperDash.Essentials.Core.Touchpanels key, buttonFeedback.DeviceKey); return; } + + deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); + if (deviceFeedback == null) + { + Debug.Console(1, this, "Button '{0}' feedback failed to get feedback property for '{1}', feedback will not be implemented. Verify feedback deviceKey is properly configured.", + key, buttonFeedback.FeedbackName); + return; + } // TODO [ ] verify if this can replace the current method - deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); //Debug.Console(0, this, "deviceFeedback.GetType().Name: '{0}'", deviceFeedback.GetType().Name); //switch (feedback.GetType().Name.ToLower()) //{ From 5a67a4060db2c715081f05cbb428218b919c9c76 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 09:31:25 -0500 Subject: [PATCH 17/46] feat: adds routing sync provider interface and delegate --- .../PepperDashEssentialsBase/Routing/RoutingInterfaces.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs index 467bf045..e24480ff 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs @@ -204,4 +204,11 @@ namespace PepperDash.Essentials.Core SigType = sigType; } } + + public interface IRoutingSyncProvider + { + event RoutingSyncProviderDelegate SyncChanged; + } + + public delegate void RoutingSyncProviderDelegate(uint inputNumber, bool hasSync); } \ No newline at end of file From 8b6a9db7e0a04aac3868e8b31d4883f52de7dc6c Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 09:32:44 -0500 Subject: [PATCH 18/46] refactor: refactors GetCecPort method --- .../Comm and IR/CommFactory.cs | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs index 9667b5b9..fd5fcfe2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs @@ -117,39 +117,37 @@ namespace PepperDash.Essentials.Core { var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey); - if (dev != null) - { - if (!String.IsNullOrEmpty(config.ControlPortName)) - { + Debug.Console(0, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null + ? "is not valid, failed to create build cec port" + : "found in device manager, attempting to build cec port"); - var inputPort = (dev as IRoutingInputsOutputs).InputPorts[config.ControlPortName]; + if (dev == null) + return null; - if (inputPort != null) - { - if (inputPort.Port is ICec) - return inputPort.Port as ICec; - } + if (String.IsNullOrEmpty(config.ControlPortName)) + { + Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey); + return null; + } - var outputPort = (dev as IRoutingInputsOutputs).OutputPorts[config.ControlPortName]; + var inputPort = (dev as IRoutingInputsOutputs).InputPorts[config.ControlPortName]; + if (inputPort != null) + { + if (inputPort.Port is ICec) + return inputPort.Port as ICec; + } - if (outputPort != null) - { - if (outputPort.Port is ICec) - return outputPort.Port as ICec; - } + var outputPort = (dev as IRoutingInputsOutputs).OutputPorts[config.ControlPortName]; + if (outputPort != null) + { + if (outputPort.Port is ICec) + return outputPort.Port as ICec; + } - else - Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called: '{1}'", - config.ControlPortDevKey, config.ControlPortName); - } - else - { - Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey); - } - } - Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey); + Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called: '{1}'", + config.ControlPortDevKey, config.ControlPortName); - return null; + return null; } /// From 9fb16f30b06ec392aa7194dbbacd2a7177c8520a Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 10:02:20 -0500 Subject: [PATCH 19/46] refactor: Changes IRoutingHasSync interface - Changed IRoutingHasSync interface to IRoutingHasVideoInputSyncFeedbacks. - Remvoed IRoutingHasSynDelegate - Added interface to HdPsXxxController class --- .../PepperDashEssentialsBase/Routing/RoutingInterfaces.cs | 8 +++----- .../Essentials_DM/Chassis/HdPsXxxController.cs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs index e24480ff..45245066 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs @@ -205,10 +205,8 @@ namespace PepperDash.Essentials.Core } } - public interface IRoutingSyncProvider + public interface IRoutingHasVideoInputSyncFeedbacks { - event RoutingSyncProviderDelegate SyncChanged; - } - - public delegate void RoutingSyncProviderDelegate(uint inputNumber, bool hasSync); + FeedbackCollection VideoInputSyncFeedbacks { get; } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index bba85d25..1bf40083 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -15,7 +15,7 @@ using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis { [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks { private readonly HdPsXxx _chassis; //private byte[] _inputPriorityParams; From 393033b6c9c4a80778e2c68c3921f97bc592db9d Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 10:13:39 -0500 Subject: [PATCH 20/46] refactor: Updates HdPsXxxController class - Modifies `SetupInput()` and `SetupOutput()` - Renames `GetInputPriorities()` to `SetInputPriorities()` --- .../Chassis/HdPsXxxController.cs | 106 ++++++++---------- 1 file changed, 46 insertions(+), 60 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 1bf40083..705061d2 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; @@ -18,7 +19,6 @@ namespace PepperDash_Essentials_DM.Chassis public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks { private readonly HdPsXxx _chassis; - //private byte[] _inputPriorityParams; public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -41,6 +41,7 @@ namespace PepperDash_Essentials_DM.Chassis public event EventHandler NumericSwitchChange; public event EventHandler DmInputChange; + /// /// Constructor /// @@ -76,12 +77,6 @@ namespace PepperDash_Essentials_DM.Chassis if (_chassis.NumberOfOutputs == 1) AutoRouteFeedback = new BoolFeedback(() => _chassis.PriorityRouteOnFeedback.BoolValue); - //if (props.InputPriorities != null) - //{ - // _inputPriorityParams = new byte[_chassis.NumberOfInputs]; - // _inputPriorityParams = GetInputPriorities(props); - //} - InputNames = props.Inputs; SetupInputs(InputNames); @@ -90,7 +85,7 @@ namespace PepperDash_Essentials_DM.Chassis } // get input priorities - private byte[] GetInputPriorities(HdPsXxxPropertiesConfig props) + private byte[] SetInputPriorities(HdPsXxxPropertiesConfig props) { throw new NotImplementedException(); } @@ -103,52 +98,59 @@ namespace PepperDash_Essentials_DM.Chassis 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); - } - + + // iterate through HDMI inputs foreach (var item in _chassis.HdmiInputs) { var input = item; var index = item.Number; var key = string.Format("hdmiIn{0}", index); - var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("HDMI Input {0}", index) : InputNames[index]; + input.Name.StringValue = string.IsNullOrEmpty(InputNames[index]) + ? string.Format("HDMI Input {0}", index) + : InputNames[index]; - InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + () => InputNames[index])); var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) { FeedbackMatchObject = input }; - Debug.Console(1, this, "Adding Input port: {0}", port.Key); + Debug.Console(1, this, "Adding Input port: {0} - {1}", port.Key, input.Name); InputPorts.Add(port); - InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); + InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + () => input.VideoDetectedFeedback.BoolValue)); } + // iterate through DM Lite inputs foreach (var item in _chassis.DmLiteInputs) { var input = item; var index = item.Number; var key = string.Format("dmLiteIn{0}", index); - var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("DM Input {0}", index) : InputNames[index]; - input.Name.StringValue = name; + input.Name.StringValue = string.IsNullOrEmpty(InputNames[index]) + ? string.Format("DM Input {0}", index) + : InputNames[index]; - InputNameFeedbacks.Add(new StringFeedback(name, () => InputNames[index])); + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + () => InputNames[index])); var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) { FeedbackMatchObject = input }; - Debug.Console(0, this, "Adding Input port: {0}", port.Key); + Debug.Console(0, this, "Adding Input port: {0} - {1}", port.Key, input.Name); InputPorts.Add(port); - InputHdcpEnableFeedback.Add(new BoolFeedback(name, () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); + InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(name, () => input.VideoDetectedFeedback.BoolValue)); + VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + () => input.VideoDetectedFeedback.BoolValue)); } _chassis.DMInputChange += _chassis_InputChange; @@ -162,54 +164,38 @@ namespace PepperDash_Essentials_DM.Chassis 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); - } foreach (var item in _chassis.HdmiDmLiteOutputs) { var output = item; var index = item.Number; var key = string.Format("hdmiDmLiteOut{0}", index); - var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) : OutputNames[index]; - output.Name.StringValue = name; + + output.Name.StringValue = string.IsNullOrEmpty(OutputNames[index]) + ? string.Format("Output {0}", index) + : OutputNames[index]; - var port = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) + var hdmiPort = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) { FeedbackMatchObject = output, - // set port for CEC - Port = output + Port = output.HdmiOutput.HdmiOutputPort.StreamCec }; - Debug.Console(0, this, "Adding Output port: {0}", port.Key); - OutputPorts.Add(port); + Debug.Console(1, this, "Adding Output port: {0} - {1}", hdmiPort.Key, output.Name); + OutputPorts.Add(hdmiPort); - OutputRouteNameFeedback.Add(new StringFeedback(name, () => output.VideoOutFeedback.NameFeedback.StringValue)); + var dmLitePort = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DmCat, output, this) + { + FeedbackMatchObject = output, + Port = output.DmLiteOutput.DmLiteOutputPort.StreamCec + }; + Debug.Console(1, this, "Adding Output port: {0} - {1}", dmLitePort.Key, output.Name); + OutputPorts.Add(dmLitePort); - VideoOutputRouteFeedbacks.Add(new IntFeedback(name, + OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + () => output.VideoOutFeedback.NameFeedback.StringValue)); + + VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); - - // TODO [ ] Investigate setting input priorities per output - // {{in1-priority-level}, {in2-priority-level}, .... {in6-priority-level}} - // default priority level input 1-4 ascending - //if (_inputPriorityParams != null && _inputPriorityParams.Count() > 0) - // output.OutputPort.InputPriorities(_inputPriorityParams); - - if (port.Port == null) continue; - - var hdmiOutputStreamCec = output.HdmiOutput.HdmiOutputPort.StreamCec; - if (hdmiOutputStreamCec != null) - { - var streamCec = new StreamCecWrapper(string.Format("{0}-hdmiOut{1}-streamCec", Key, index), hdmiOutputStreamCec); - DeviceManager.AddDevice(streamCec); - } - - var dmLiteOutputStreamCec = output.DmLiteOutput.DmLiteOutputPort.StreamCec; - if (dmLiteOutputStreamCec != null) - { - var streamCec = new StreamCecWrapper(string.Format("{0}-dmLiteOut{1}-streamCec", Key, index), dmLiteOutputStreamCec); - DeviceManager.AddDevice(streamCec); - } } _chassis.DMOutputChange += _chassis_OutputChange; @@ -547,7 +533,7 @@ namespace PepperDash_Essentials_DM.Chassis } - #endregion + #endregion } From 7ecb2ecf6dfeadcf2191d49cca1be0a03e10b54d Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Sep 2023 16:43:23 -0500 Subject: [PATCH 21/46] fix: updates SetupOutputs to create a hdmiOutX and dmLiteOutX port --- .../Chassis/HdPsXxxController.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 705061d2..cbcf2a7c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -105,10 +105,12 @@ namespace PepperDash_Essentials_DM.Chassis var input = item; var index = item.Number; var key = string.Format("hdmiIn{0}", index); - input.Name.StringValue = string.IsNullOrEmpty(InputNames[index]) - ? string.Format("HDMI Input {0}", index) + var name = string.IsNullOrEmpty(InputNames[index]) + ? string.Format("HDMI Input {0}", index) : InputNames[index]; + input.Name.StringValue = name; + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), () => InputNames[index])); @@ -116,7 +118,7 @@ namespace PepperDash_Essentials_DM.Chassis { FeedbackMatchObject = input }; - Debug.Console(1, this, "Adding Input port: {0} - {1}", port.Key, input.Name); + Debug.Console(1, this, "Adding Input port: {0} - {1}", port.Key, name); InputPorts.Add(port); InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), @@ -132,10 +134,12 @@ namespace PepperDash_Essentials_DM.Chassis var input = item; var index = item.Number; var key = string.Format("dmLiteIn{0}", index); - input.Name.StringValue = string.IsNullOrEmpty(InputNames[index]) + var name = string.IsNullOrEmpty(InputNames[index]) ? string.Format("DM Input {0}", index) : InputNames[index]; + input.Name.StringValue = name; + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), () => InputNames[index])); @@ -143,7 +147,7 @@ namespace PepperDash_Essentials_DM.Chassis { FeedbackMatchObject = input }; - Debug.Console(0, this, "Adding Input port: {0} - {1}", port.Key, input.Name); + Debug.Console(0, this, "Adding Input port: {0} - {1}", port.Key, name); InputPorts.Add(port); InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), @@ -169,26 +173,28 @@ namespace PepperDash_Essentials_DM.Chassis { var output = item; var index = item.Number; - var key = string.Format("hdmiDmLiteOut{0}", index); - - output.Name.StringValue = string.IsNullOrEmpty(OutputNames[index]) + var name = string.IsNullOrEmpty(OutputNames[index]) ? string.Format("Output {0}", index) - : OutputNames[index]; + : OutputNames[index]; + + output.Name.StringValue = name; - var hdmiPort = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) + var hdmiKey = string.Format("hdmiOut{0}", index); + var hdmiPort = new RoutingOutputPort(hdmiKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) { FeedbackMatchObject = output, Port = output.HdmiOutput.HdmiOutputPort.StreamCec }; - Debug.Console(1, this, "Adding Output port: {0} - {1}", hdmiPort.Key, output.Name); + Debug.Console(1, this, "Adding Output port: {0} - {1}", hdmiPort.Key, name); OutputPorts.Add(hdmiPort); - var dmLitePort = new RoutingOutputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DmCat, output, this) + var dmLiteKey = string.Format("dmLiteOut{0}", index); + var dmLitePort = new RoutingOutputPort(dmLiteKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DmCat, output, this) { FeedbackMatchObject = output, Port = output.DmLiteOutput.DmLiteOutputPort.StreamCec }; - Debug.Console(1, this, "Adding Output port: {0} - {1}", dmLitePort.Key, output.Name); + Debug.Console(1, this, "Adding Output port: {0} - {1}", dmLitePort.Key, name); OutputPorts.Add(dmLitePort); OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), From 6d020132cfb2283fbcd1fa3bee89f3f4081eedac Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 20 Sep 2023 15:38:25 -0500 Subject: [PATCH 22/46] refactor: GetCecPort method to handle exceptions --- .../Comm and IR/CommFactory.cs | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs index fd5fcfe2..549404e0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs @@ -115,39 +115,54 @@ namespace PepperDash.Essentials.Core /// public static ICec GetCecPort(ControlPropertiesConfig config) { - var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey); - - Debug.Console(0, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null - ? "is not valid, failed to create build cec port" - : "found in device manager, attempting to build cec port"); - - if (dev == null) - return null; - - if (String.IsNullOrEmpty(config.ControlPortName)) + try { - Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey); - return null; + var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey); + + Debug.Console(0, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null + ? "is not valid, failed to get cec port" + : "found in device manager, attempting to get cec port"); + + if (dev == null) + return null; + + if (String.IsNullOrEmpty(config.ControlPortName)) + { + Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey); + return null; + } + + + var inputsOutputs = dev as IRoutingInputsOutputs; + if (inputsOutputs == null) + { + Debug.Console(0, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'", + config.ControlPortDevKey, config.ControlPortName); + + return null; + } + + var inputPort = inputsOutputs.InputPorts[config.ControlPortName]; + if (inputPort != null && inputPort.Port is ICec) + return inputPort.Port as ICec; + + + var outputPort = inputsOutputs.OutputPorts[config.ControlPortName]; + if (outputPort != null && outputPort.Port is ICec) + return outputPort.Port as ICec; + } + catch (Exception ex) + { + Debug.Console(1, "GetCecPort Exception Message: {0}", ex.Message); + Debug.Console(2, "GetCecPort Exception StackTrace: {0}", ex.StackTrace); + if (ex.InnerException != null) + Debug.Console(0, "GetCecPort Exception InnerException: {0}", ex.InnerException); } - var inputPort = (dev as IRoutingInputsOutputs).InputPorts[config.ControlPortName]; - if (inputPort != null) - { - if (inputPort.Port is ICec) - return inputPort.Port as ICec; - } - - var outputPort = (dev as IRoutingInputsOutputs).OutputPorts[config.ControlPortName]; - if (outputPort != null) - { - if (outputPort.Port is ICec) - return outputPort.Port as ICec; - } - - Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called: '{1}'", + Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called '{1}'", config.ControlPortDevKey, config.ControlPortName); - return null; + return null; } /// From 1569c12450a11c8b99b1b8f6f0d917b0d35a0dde Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 20 Sep 2023 15:41:06 -0500 Subject: [PATCH 23/46] fix: Updates SetupOutputs method Corrects the port referencece to exclude `.StreamCec` when building the port. --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index cbcf2a7c..bf9f72cc 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -183,7 +183,7 @@ namespace PepperDash_Essentials_DM.Chassis var hdmiPort = new RoutingOutputPort(hdmiKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this) { FeedbackMatchObject = output, - Port = output.HdmiOutput.HdmiOutputPort.StreamCec + Port = output.HdmiOutput.HdmiOutputPort }; Debug.Console(1, this, "Adding Output port: {0} - {1}", hdmiPort.Key, name); OutputPorts.Add(hdmiPort); @@ -192,13 +192,13 @@ namespace PepperDash_Essentials_DM.Chassis var dmLitePort = new RoutingOutputPort(dmLiteKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DmCat, output, this) { FeedbackMatchObject = output, - Port = output.DmLiteOutput.DmLiteOutputPort.StreamCec + Port = output.DmLiteOutput.DmLiteOutputPort }; Debug.Console(1, this, "Adding Output port: {0} - {1}", dmLitePort.Key, name); OutputPorts.Add(dmLitePort); - + OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), - () => output.VideoOutFeedback.NameFeedback.StringValue)); + () => output.VideoOutFeedback.NameFeedback.StringValue)); VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); From 6c41b8e19de5a4b0a6af374afa6c83598d1dff1e Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 24 Oct 2023 15:24:44 -0500 Subject: [PATCH 24/46] fix: updates executeSwitch, add helper method 1. Updated executeSwitch object casting to resolve routing issues. 2. Added ListRoutingPorts method. --- .../Chassis/HdPsXxxController.cs | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index bf9f72cc..216f3d19 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -208,6 +208,38 @@ namespace PepperDash_Essentials_DM.Chassis } + public void ListRoutingPorts() + { + try + { + foreach (var port in InputPorts) + { + Debug.Console(0, this, @"Input Port Key: {0} +Port: {1} +Type: {2} +ConnectionType: {3} +Selector: {4} +", port.Key, port.Port, port.Type, port.ConnectionType, port.Selector); + } + + foreach (var port in OutputPorts) + { + Debug.Console(0, this, @"Output Port Key: {0} +Port: {1} +Type: {2} +ConnectionType: {3} +Selector: {4} +", port.Key, port.Port, port.Type, port.ConnectionType, port.Selector); + } + } + catch (Exception ex) + { + Debug.Console(0, this, "ListRoutingPorts Exception Message: {0}", ex.Message); + Debug.Console(0, this, "ListRoutingPorts Exception StackTrace: {0}", ex.StackTrace); + if (ex.InnerException != null) Debug.Console(0, this, "ListRoutingPorts InnerException: {0}", ex.InnerException); + } + } + #region BridgeLinking /// @@ -299,9 +331,12 @@ namespace PepperDash_Essentials_DM.Chassis /// public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { - var input = inputSelector as HdPsXxxHdmiInput; - var output = outputSelector as HdPsXxxHdmiOutput; + //var input = inputSelector as HdPsXxxHdmiInput; + //var output = outputSelector as HdPsXxxHdmiOutput; + var input = inputSelector as HdPsXxxInput; + var output = outputSelector as HdPsXxxOutput; + Debug.Console(2, this, "ExecuteSwitch: input={0}, output={1}", input, output); if (output == null) From 53b96d54e69e2108ac9c8aa67c6f35437a3b514c Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 24 Oct 2023 15:36:04 -0500 Subject: [PATCH 25/46] fix: removes old selector casting statements --- .../Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 216f3d19..36e99bc6 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -331,9 +331,6 @@ Selector: {4} /// public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { - //var input = inputSelector as HdPsXxxHdmiInput; - //var output = outputSelector as HdPsXxxHdmiOutput; - var input = inputSelector as HdPsXxxInput; var output = outputSelector as HdPsXxxOutput; From 6698dcb46e7cdc6824d5725ecf9528385e5fe03a Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 25 Oct 2023 15:26:42 -0500 Subject: [PATCH 26/46] refactor: update init methods and add events - Updated InitializeButton method to enable/disable buttons based on config. - Updated InitializeButtonFeedback method debug statements. - Added BaseEvent event subscription. - Added PanelStateChnage event subscription. --- .../Touchpanels/Mpc3Touchpanel.cs | 109 +++++++++++------- 1 file changed, 68 insertions(+), 41 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 296965f9..2d36fe49 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -27,7 +27,15 @@ namespace PepperDash.Essentials.Core.Touchpanels return; } + if (_touchpanel.Registerable) + { + _touchpanel.Register(); + Debug.Console(0, this, ""); + } + + _touchpanel.BaseEvent += _touchpanel_BaseEvent; _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange; + _touchpanel.PanelStateChange += _touchpanel_PanelStateChange; _buttons = buttons; if (_buttons == null) @@ -57,8 +65,6 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public void InitializeButton(string key, KeypadButton config) { - Debug.Console(1, this, "Initializing button '{0}'...", key); - if (config == null) { Debug.Console(1, this, "Button '{0}' config is null, unable to initialize", key); @@ -69,63 +75,72 @@ namespace PepperDash.Essentials.Core.Touchpanels TryParseInt(key, out buttonNumber); var buttonEventTypes = config.EventTypes; + BoolOutputSig enabledFb = null; + BoolOutputSig disabledFb = null; switch (key) { case ("power"): { - if (buttonEventTypes == null) + if (buttonEventTypes == null || buttonEventTypes.Keys == 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"): - { + + enabledFb = _touchpanel.PowerButtonEnabledFeedBack; + disabledFb = _touchpanel.PowerButtonDisabledFeedBack; break; } + //case ("volumeup"): + // { + // break; + // } + //case ("volumedown"): + // { + // break; + // } + //case ("volumefeedback"): + // { + // break; + // } case ("mute"): { - if (buttonEventTypes == null) + if (buttonEventTypes == null || buttonEventTypes.Keys == null) _touchpanel.DisableMuteButton(); else _touchpanel.EnableMuteButton(); + + enabledFb = _touchpanel.MuteButtonEnabledFeedBack; + disabledFb = _touchpanel.MuteButtonDisabledFeedBack; + break; } default: { - if (buttonNumber == 0) + if (buttonNumber == 0 || buttonNumber > 9) break; - if (buttonEventTypes == null) + if (buttonEventTypes == null || buttonEventTypes.Keys == null) _touchpanel.DisableNumericalButton((uint)buttonNumber); else _touchpanel.EnableNumericalButton((uint)buttonNumber); + + if (_touchpanel.NumericalButtonEnabledFeedBack != null) + enabledFb = _touchpanel.NumericalButtonEnabledFeedBack[(uint)buttonNumber]; + + if (_touchpanel.NumericalButtonDisabledFeedBack != null) + disabledFb = _touchpanel.NumericalButtonDisabledFeedBack[(uint)buttonNumber]; + break; } } - Debug.Console(1, this, "Button '{0}' {1}", key, buttonEventTypes == null - ? "is disabled, verify eventTypes are configured." - : "is enabled"); + Debug.Console(0, this, "InitializeButton: key-'{0}' enabledFb-'{1}', disabledFb-'{2}'", + key, enabledFb ?? (object)"null", disabledFb ?? (object)"null"); } /// @@ -135,11 +150,11 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public void InitializeButtonFeedback(string key, KeypadButton config) { - Debug.Console(1, this, "Initializing button '{0}' feedback...", key); + //Debug.Console(1, this, "Initializing button '{0}' feedback...", key); if (config == null) { - Debug.Console(1, this, "Button '{0}' config is null, unable to initialize feedback", key); + Debug.Console(1, this, "Button '{0}' config is null, skipping.", key); return; } @@ -148,9 +163,9 @@ namespace PepperDash.Essentials.Core.Touchpanels // Link up the button feedbacks to the specified device feedback var buttonFeedback = config.Feedback; - if (buttonFeedback == null) + if (buttonFeedback == null || string.IsNullOrEmpty(buttonFeedback.DeviceKey)) { - Debug.Console(1, this, "Button '{0}' feedback not configured and will not be implemented. If feedback is required, verify configuration.", + Debug.Console(1, this, "Button '{0}' feedback not configured, skipping.", key); return; } @@ -162,15 +177,15 @@ namespace PepperDash.Essentials.Core.Touchpanels var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device; if (device == null) { - Debug.Console(1, this, "Button '{0}' feedback with deviceKey '{1}' not found, feedback will not be implemented. Verify feedback deviceKey is properly configured.", + Debug.Console(1, this, "Button '{0}' feedback deviceKey '{1}' not found.", key, buttonFeedback.DeviceKey); return; } - + deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName); if (deviceFeedback == null) { - Debug.Console(1, this, "Button '{0}' feedback failed to get feedback property for '{1}', feedback will not be implemented. Verify feedback deviceKey is properly configured.", + Debug.Console(1, this, "Button '{0}' feedbackName property '{1}' not found.", key, buttonFeedback.FeedbackName); return; } @@ -195,12 +210,12 @@ namespace PepperDash.Essentials.Core.Touchpanels } catch (Exception ex) { - Debug.Console(0, this, "Failed to initialize button '{0}' feedback with deviceKey '{1}'. If feedback is required, verify configuration.", - key, buttonFeedback.DeviceKey); - - Debug.Console(1, this, "InitializeButtonFeedback Exception Message: {0}", ex.Message); - Debug.Console(2, this, "InitializeButtonFeedback Exception StackTrace: {0}", ex.StackTrace); - if (ex.InnerException != null) Debug.Console(2, this, "InitializeButtonFeedback Exception InnerExceptioni: {0}", ex.InnerException); + Debug.Console(1, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception Message: {0}", + ex.Message, key, buttonFeedback.DeviceKey); + Debug.Console(2, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception StackTrace: {0}", + ex.StackTrace, key, buttonFeedback.DeviceKey); + if (ex.InnerException != null) Debug.Console(2, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') InnerException: {0}", + ex.InnerException, key, buttonFeedback.DeviceKey); return; } @@ -259,9 +274,14 @@ namespace PepperDash.Essentials.Core.Touchpanels } } + private void _touchpanel_BaseEvent(GenericBase device, BaseEventArgs args) + { + Debug.Console(1, this, "BaseEvent: eventId-'{0}', index-'{1}'", args.EventId, args.Index); + } + 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); + Debug.Console(1, this, "ButtonStateChange: buttonNumber-'{0}' buttonName-'{1}', buttonState-'{2}'", args.Button.Number, args.Button.Name, args.NewButtonState); var type = args.NewButtonState.ToString(); if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture))) @@ -274,6 +294,11 @@ namespace PepperDash.Essentials.Core.Touchpanels } } + private void _touchpanel_PanelStateChange(GenericBase device, BaseEventArgs args) + { + Debug.Console(1, this, "PanelStateChange: eventId-'{0}', index-'{1}'", args.EventId, args.Index); + } + /// /// Runs the function associated with this button/type. One of the following strings: /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased @@ -282,6 +307,8 @@ namespace PepperDash.Essentials.Core.Touchpanels /// public void Press(string buttonKey, string type) { + Debug.Console(2, this, "Press: buttonKey-'{0}', type-'{1}'", buttonKey, 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; From d1d1d81165ce61ad21c7c4563ceff801c2184c30 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 25 Oct 2023 15:44:39 -0500 Subject: [PATCH 27/46] fix: update registration debug statement to include response --- .../PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 2d36fe49..2f6074dd 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -29,8 +29,8 @@ namespace PepperDash.Essentials.Core.Touchpanels if (_touchpanel.Registerable) { - _touchpanel.Register(); - Debug.Console(0, this, ""); + var registrationResponse = _touchpanel.Register(); + Debug.Console(0, this, "touchpanel registration response: {0}", registrationResponse); } _touchpanel.BaseEvent += _touchpanel_BaseEvent; From 4da2f25c3d57aa867dac162ae6a8e4812eae5dc1 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 27 Oct 2023 12:14:07 -0500 Subject: [PATCH 28/46] fix: list available buttons on startup --- .../Touchpanels/Mpc3Touchpanel.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs index 2f6074dd..44a758f8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -55,6 +55,8 @@ namespace PepperDash.Essentials.Core.Touchpanels InitializeButton(buttonKey, buttonConfig); InitializeButtonFeedback(buttonKey, buttonConfig); } + + ListButtons(); }); } @@ -318,6 +320,23 @@ namespace PepperDash.Essentials.Core.Touchpanels foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType); } + + + public void ListButtons() + { + var line = new string('-', 35); + + Debug.Console(0, this, line); + + Debug.Console(0, this, "MPC3 Controller {0} - Available Butons", Key); + + foreach (var button in _buttons) + { + Debug.Console(0, this, "Key: {0}", button.Key); + } + + Debug.Console(0, this, line); + } } /// From 1df8d3f6177efb7d5eecad054e1b0b8f6f86768e Mon Sep 17 00:00:00 2001 From: jkdevito Date: Thu, 2 Nov 2023 11:54:44 -0500 Subject: [PATCH 29/46] feat: create branch to add volume control --- .../Chassis/HdPsXxxController.cs | 35 +++++++++++++++++-- .../Config/HdPsXxxPropertiesConfig.cs | 3 ++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 36e99bc6..f676c80c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -16,9 +16,11 @@ using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis { [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks, IHasVolumeControlWithFeedback { private readonly HdPsXxx _chassis; + private readonly string _defaultAudioKey = ""; + public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -82,6 +84,9 @@ namespace PepperDash_Essentials_DM.Chassis OutputNames = props.Outputs; SetupOutputs(OutputNames); + + if (!string.IsNullOrEmpty(props.DefaultAudioKey)) + _defaultAudioKey = props.DefaultAudioKey; } // get input priorities @@ -413,6 +418,31 @@ Selector: {4} _chassis.AutoRouteOff(); } + #region IHasVolumeWithFeedback Members + + public void VolumeUp(bool pressRelease) + { + + } + + public void VolumeDown(bool pressRelease) + { + throw new NotImplementedException(); + } + + public void SetVolume(ushort level) + { + throw new NotImplementedException(); + } + + public IntFeedback VolumeLevelFeedback { get; private set; } + + + + #endregion + + + #region Events @@ -517,6 +547,7 @@ Selector: {4} #endregion + #region Factory @@ -571,7 +602,7 @@ Selector: {4} } - #endregion + #endregion } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs index 576b74f0..9b988dd1 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs @@ -15,6 +15,9 @@ namespace PepperDash_Essentials_DM.Config [JsonProperty("outputs")] public Dictionary Outputs { get; set; } + [JsonProperty("defaultAudioKey")] + public string DefaultAudioKey { get; set; } + // "inputPriorities": "1,4,3,2" [JsonProperty("inputPriorities")] public string InputPriorities { get; set; } From 355e9cde12b76b0433018f98652cff4aa96b0be8 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Thu, 2 Nov 2023 11:55:48 -0500 Subject: [PATCH 30/46] chore(wip): save updates --- .../Essentials_DM/Chassis/HdPsXxxController.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index f676c80c..9a2a17f4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Runtime.InteropServices; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; @@ -207,6 +208,14 @@ namespace PepperDash_Essentials_DM.Chassis VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); + + var audioKey = string.Format("audioOut{0}", index); + var audioPort = new RoutingOutputPort(audioKey, eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio, + output, this) + { + FeedbackMatchObject = output, + Port = output.OutputPort.AudioOutput; + }; } _chassis.DMOutputChange += _chassis_OutputChange; From c528fecb9a9ead1631a68303c59308fb9171af8f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 2 Nov 2023 17:52:27 -0500 Subject: [PATCH 31/46] feat(wip): add HdPsXxx audio control --- .../HdPsXxxAnalogAuxMixerController.cs | 98 +++++++++++++++++++ .../Chassis/HdPsXxxController.cs | 50 +++------- .../Config/HdPsXxxPropertiesConfig.cs | 4 +- .../PepperDash_Essentials_DM.csproj | 1 + 4 files changed, 114 insertions(+), 39 deletions(-) create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs new file mode 100644 index 00000000..3fac2cf7 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -0,0 +1,98 @@ +using System; +using Crestron.SimplSharpPro.DM; +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash_Essentials_DM.Chassis +{ + public class HdPsXxxAnalogAuxMixerController : IKeyed, IBasicVolumeWithFeedback + { + public string Key { get; private set; } + + public HdPsXxxAnalogAuxMixer Mixer { get; set; } + + public HdPsXxxAnalogAuxMixerController(string parent, uint mixer, HdPsXxx chassis) + { + Key = string.Format("{0}-analogMixer{1}", parent, mixer); + + Mixer = chassis.AnalogAuxiliaryMixer[mixer]; + + VolumeLevelFeedback = new IntFeedback(VolumeFeedbackFunc); + MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + } + + #region Volume + + public IntFeedback VolumeLevelFeedback { get; private set; } + + protected Func VolumeFeedbackFunc + { + get { return () => Mixer.VolumeFeedback.UShortValue; } + } + + public void SetVolume(ushort level) + { + Mixer.Volume.UShortValue = level; + } + + public void VolumeUp(bool pressRelease) + { + if (pressRelease) + { + var remainingRatio = (65535 - Mixer.Volume.UShortValue)/65535; + Mixer.Volume.CreateRamp(65535, 400); + } + else + { + Mixer.Volume.StopRamp(); + } + } + + public void VolumeDown(bool pressRelease) + { + if (pressRelease) + { + var remainingRatio = Mixer.Volume.UShortValue/65535; + Mixer.Volume.CreateRamp(0, (uint)(400 * remainingRatio)); + } + else + { + Mixer.Volume.StopRamp(); + } + } + + #endregion + + + #region Mute + + private bool _isMuted; + + public BoolFeedback MuteFeedback { get; private set; } + + protected Func MuteFeedbackFunc + { + get { return () => _isMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; } + } + + public void MuteOn() + { + Mixer.AuxiliaryMuteControl.MuteOn(); + } + + public void MuteOff() + { + Mixer.AuxiliaryMuteControl.MuteOff(); + } + + public void MuteToggle() + { + if (_isMuted) + MuteOff(); + else + MuteOn(); + } + + #endregion + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 9a2a17f4..1cece4e4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.InteropServices; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; @@ -17,11 +16,9 @@ using PepperDash_Essentials_DM.Config; namespace PepperDash_Essentials_DM.Chassis { [Description("Wrapper class for all HdPsXxx switchers")] - public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks, IHasVolumeControlWithFeedback + public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks { private readonly HdPsXxx _chassis; - private readonly string _defaultAudioKey = ""; - public RoutingPortCollection InputPorts { get; private set; } public RoutingPortCollection OutputPorts { get; private set; } @@ -86,8 +83,11 @@ namespace PepperDash_Essentials_DM.Chassis OutputNames = props.Outputs; SetupOutputs(OutputNames); - if (!string.IsNullOrEmpty(props.DefaultAudioKey)) - _defaultAudioKey = props.DefaultAudioKey; + foreach (var mixer in _chassis.AnalogAuxiliaryMixer) + { + var mixerDevice = new HdPsXxxAnalogAuxMixerController(Key, mixer.MixerNumber, _chassis); + DeviceManager.AddDevice(mixerDevice); + } } // get input priorities @@ -208,14 +208,13 @@ namespace PepperDash_Essentials_DM.Chassis VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); + } - var audioKey = string.Format("audioOut{0}", index); - var audioPort = new RoutingOutputPort(audioKey, eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio, - output, this) - { - FeedbackMatchObject = output, - Port = output.OutputPort.AudioOutput; - }; + Debug.Console(0, this, "----> AnalogAuxillaryMixer.Count-{0}", _chassis.AnalogAuxiliaryMixer.Count); + foreach (var item in _chassis.AnalogAuxiliaryMixer) + { + Debug.Console(0, this, "----> AnalogAuxillaryMixer[{0}].LineMuteVolumeControl.Count-{1}", item.MixerNumber, item.LineMuteVolumeControl.Count); + Debug.Console(0, this, "----> AnalogAuxillaryMixer[{0}].SourceMuteVolumeControl.Count-{1}", item.MixerNumber, item.SourceMuteVolumeControl.Count); } _chassis.DMOutputChange += _chassis_OutputChange; @@ -427,29 +426,6 @@ Selector: {4} _chassis.AutoRouteOff(); } - #region IHasVolumeWithFeedback Members - - public void VolumeUp(bool pressRelease) - { - - } - - public void VolumeDown(bool pressRelease) - { - throw new NotImplementedException(); - } - - public void SetVolume(ushort level) - { - throw new NotImplementedException(); - } - - public IntFeedback VolumeLevelFeedback { get; private set; } - - - - #endregion - #region Events @@ -564,7 +540,7 @@ Selector: {4} { public HdSp401ControllerFactory() { - TypeNames = new List() { "hdps401", "hdps402", "hdps621", "hdps622" }; + TypeNames = new List { "hdps401", "hdps402", "hdps621", "hdps622" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) { diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs index 9b988dd1..f5eb9d39 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs @@ -15,8 +15,8 @@ namespace PepperDash_Essentials_DM.Config [JsonProperty("outputs")] public Dictionary Outputs { get; set; } - [JsonProperty("defaultAudioKey")] - public string DefaultAudioKey { get; set; } + [JsonProperty("volumeMixerId")] + public uint VolumeMixerId { get; set; } // "inputPriorities": "1,4,3,2" [JsonProperty("inputPriorities")] 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..5840945f 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,7 @@ + From a64b5240ad2b385eb6141bcdd2eaab8d07edc942 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 3 Nov 2023 18:14:53 -0500 Subject: [PATCH 32/46] feat: add output audio controller --- .../HdPsXxxAnalogAuxMixerController.cs | 13 ++- .../Chassis/HdPsXxxController.cs | 19 ++-- .../Chassis/HdPsXxxOutputAudioController.cs | 99 +++++++++++++++++++ .../PepperDash_Essentials_DM.csproj | 1 + 4 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs index 3fac2cf7..bd6893ee 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -1,15 +1,17 @@ using System; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using PepperDash.Core; using PepperDash.Essentials.Core; namespace PepperDash_Essentials_DM.Chassis { - public class HdPsXxxAnalogAuxMixerController : IKeyed, IBasicVolumeWithFeedback + public class HdPsXxxAnalogAuxMixerController : IKeyed, + IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback // || IBasicVolumeWithFeedback { public string Key { get; private set; } - public HdPsXxxAnalogAuxMixer Mixer { get; set; } + public HdPsXxxAnalogAuxMixer Mixer { get; private set; } public HdPsXxxAnalogAuxMixerController(string parent, uint mixer, HdPsXxx chassis) { @@ -17,10 +19,17 @@ namespace PepperDash_Essentials_DM.Chassis Mixer = chassis.AnalogAuxiliaryMixer[mixer]; + Mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange; + VolumeLevelFeedback = new IntFeedback(VolumeFeedbackFunc); MuteFeedback = new BoolFeedback(MuteFeedbackFunc); } + private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args) + { + Debug.Console(2, this, "AuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.ToString(), args.Index, args.EventId); + } + #region Volume public IntFeedback VolumeLevelFeedback { get; private set; } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 1cece4e4..a4bef385 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -83,10 +83,15 @@ namespace PepperDash_Essentials_DM.Chassis OutputNames = props.Outputs; SetupOutputs(OutputNames); - foreach (var mixer in _chassis.AnalogAuxiliaryMixer) + foreach (var item in _chassis.HdmiDmLiteOutputs) { - var mixerDevice = new HdPsXxxAnalogAuxMixerController(Key, mixer.MixerNumber, _chassis); - DeviceManager.AddDevice(mixerDevice); + var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis); + DeviceManager.AddDevice(audioDevice); + } + foreach (var item in _chassis.AnalogAuxiliaryMixer) + { + var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); + DeviceManager.AddDevice(audioDevice); } } @@ -180,7 +185,7 @@ namespace PepperDash_Essentials_DM.Chassis var output = item; var index = item.Number; var name = string.IsNullOrEmpty(OutputNames[index]) - ? string.Format("Output {0}", index) + ? string.Format("Port {0}", index) : OutputNames[index]; output.Name.StringValue = name; @@ -191,7 +196,7 @@ namespace PepperDash_Essentials_DM.Chassis FeedbackMatchObject = output, Port = output.HdmiOutput.HdmiOutputPort }; - Debug.Console(1, this, "Adding Output port: {0} - {1}", hdmiPort.Key, name); + Debug.Console(1, this, "Adding Port port: {0} - {1}", hdmiPort.Key, name); OutputPorts.Add(hdmiPort); var dmLiteKey = string.Format("dmLiteOut{0}", index); @@ -200,7 +205,7 @@ namespace PepperDash_Essentials_DM.Chassis FeedbackMatchObject = output, Port = output.DmLiteOutput.DmLiteOutputPort }; - Debug.Console(1, this, "Adding Output port: {0} - {1}", dmLitePort.Key, name); + Debug.Console(1, this, "Adding Port port: {0} - {1}", dmLitePort.Key, name); OutputPorts.Add(dmLitePort); OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), @@ -237,7 +242,7 @@ Selector: {4} foreach (var port in OutputPorts) { - Debug.Console(0, this, @"Output Port Key: {0} + Debug.Console(0, this, @"Port Port Key: {0} Port: {1} Type: {2} ConnectionType: {3} diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs new file mode 100644 index 00000000..9716ba1e --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs @@ -0,0 +1,99 @@ +using System; +using Crestron.SimplSharpPro.DM; +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash_Essentials_DM.Chassis +{ + public class HdPsXxxOutputAudioController : IKeyed, + IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback // || IBasicVolumeWithFeedback + { + public string Key { get; private set; } + + public HdPsXxxOutputPort Port { get; private set; } + + public HdPsXxxOutputAudioController(string parent, uint output, HdPsXxx chassis) + { + Key = string.Format("{0}-audioOut{1}", parent, output); + + Port = chassis.HdmiDmLiteOutputs[output].OutputPort; + + VolumeLevelFeedback = new IntFeedback(VolumeFeedbackFunc); + MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + } + + #region Volume + + public IntFeedback VolumeLevelFeedback { get; private set; } + + protected Func VolumeFeedbackFunc + { + get { return () => Port.AudioOutput.VolumeFeedback.UShortValue; } + } + + public void SetVolume(ushort level) + { + Port.AudioOutput.Volume.UShortValue = level; + } + + public void VolumeUp(bool pressRelease) + { + if (pressRelease) + { + var remainingRatio = (65535 - Port.AudioOutput.Volume.UShortValue)/65535; + Port.AudioOutput.Volume.CreateRamp(65535, 400); + } + else + { + Port.AudioOutput.Volume.StopRamp(); + } + } + + public void VolumeDown(bool pressRelease) + { + if (pressRelease) + { + var remainingRatio = Port.AudioOutput.Volume.UShortValue/65535; + Port.AudioOutput.Volume.CreateRamp(0, (uint)(400 * remainingRatio)); + } + else + { + Port.AudioOutput.Volume.StopRamp(); + } + } + + #endregion + + + #region Mute + + private bool _isMuted; + + public BoolFeedback MuteFeedback { get; private set; } + + protected Func MuteFeedbackFunc + { + get { return () => _isMuted = Port.MuteOnFeedback.BoolValue; } + } + + public void MuteOn() + { + Port.MuteOn(); + } + + public void MuteOff() + { + Port.MuteOff(); + } + + public void MuteToggle() + { + if (_isMuted) + MuteOff(); + else + MuteOn(); + } + + #endregion + } +} \ 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 5840945f..41136d0d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -106,6 +106,7 @@ + From d713abf614dd8e3ccf330c260e2c1dbcd962bb34 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 9 Nov 2023 23:36:54 -0600 Subject: [PATCH 33/46] fix: update hd-ps audio controllers to resolve control issues --- .../HdPsXxxAnalogAuxMixerController.cs | 105 ++++++++++++++---- .../Chassis/HdPsXxxOutputAudioController.cs | 80 +++++++++---- 2 files changed, 143 insertions(+), 42 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs index bd6893ee..fc8ed0e2 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -1,4 +1,4 @@ -using System; +using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using PepperDash.Core; @@ -20,36 +20,72 @@ namespace PepperDash_Essentials_DM.Chassis Mixer = chassis.AnalogAuxiliaryMixer[mixer]; Mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange; + Mixer.AuxiliaryMuteControl.MuteAndVolumeControlPropertyChange += OnMuteAndVolumeControlPropertyChange; - VolumeLevelFeedback = new IntFeedback(VolumeFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); - } + VolumeLevelFeedback = new IntFeedback(() => VolumeLevel); + MuteFeedback = new BoolFeedback(() => IsMuted); - private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args) - { - Debug.Console(2, this, "AuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.ToString(), args.Index, args.EventId); + VolumeLevel = Mixer.VolumeFeedback.ShortValue; + IsMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; } #region Volume - public IntFeedback VolumeLevelFeedback { get; private set; } - - protected Func VolumeFeedbackFunc + private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args) { - get { return () => Mixer.VolumeFeedback.UShortValue; } + Debug.Console(2, this, "AuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.GetType().ToString(), args.Index, args.EventId); + + switch (args.EventId) + { + case (3): + { + VolumeLevel = Mixer.VolumeFeedback.ShortValue; + break; + } + } } + private const ushort CrestronLevelMin = 0; + private const ushort CrestronLevelMax = 65535; + + private const int DeviceLevelMin = -800; + private const int DeviceLevelMax = 200; + + private const int RampTime = 5000; + + private int _volumeLevel; + + public int VolumeLevel + { + get { return _volumeLevel; } + set + { + var level = value; + _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); + + Debug.Console(1, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); + + VolumeLevelFeedback.FireUpdate(); + } + } + + public IntFeedback VolumeLevelFeedback { get; private set; } + public void SetVolume(ushort level) { - Mixer.Volume.UShortValue = level; + var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, + DeviceLevelMin); + + Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); + + Mixer.Volume.ShortValue = (short)scaled; } public void VolumeUp(bool pressRelease) { if (pressRelease) { - var remainingRatio = (65535 - Mixer.Volume.UShortValue)/65535; - Mixer.Volume.CreateRamp(65535, 400); + Mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); } else { @@ -61,8 +97,10 @@ namespace PepperDash_Essentials_DM.Chassis { if (pressRelease) { - var remainingRatio = Mixer.Volume.UShortValue/65535; - Mixer.Volume.CreateRamp(0, (uint)(400 * remainingRatio)); + //var remainingRatio = Mixer.Volume.UShortValue/CrestronLevelMax; + //Mixer.Volume.CreateRamp(CrestronLevelMin, (uint)(RampTime * remainingRatio)); + + Mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); } else { @@ -73,17 +111,42 @@ namespace PepperDash_Essentials_DM.Chassis #endregion + + #region Mute + private void OnMuteAndVolumeControlPropertyChange(MuteControl device, GenericEventArgs args) + { + Debug.Console(2, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2}", device.ToString(), args.Index, args.EventId); + + switch (args.EventId) + { + case (1): + case (2): + { + IsMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; + break; + } + } + } + private bool _isMuted; - public BoolFeedback MuteFeedback { get; private set; } - - protected Func MuteFeedbackFunc + public bool IsMuted { - get { return () => _isMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; } + get { return _isMuted; } + set + { + _isMuted = value; + + Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted); + + MuteFeedback.FireUpdate(); + } } + public BoolFeedback MuteFeedback { get; private set; } + public void MuteOn() { Mixer.AuxiliaryMuteControl.MuteOn(); @@ -96,7 +159,7 @@ namespace PepperDash_Essentials_DM.Chassis public void MuteToggle() { - if (_isMuted) + if (IsMuted) MuteOff(); else MuteOn(); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs index 9716ba1e..d8583f19 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs @@ -1,47 +1,76 @@ -using System; +using Crestron.SimplSharp; using Crestron.SimplSharpPro.DM; using PepperDash.Core; using PepperDash.Essentials.Core; namespace PepperDash_Essentials_DM.Chassis { - public class HdPsXxxOutputAudioController : IKeyed, + public class HdPsXxxOutputAudioController : IKeyed, IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback // || IBasicVolumeWithFeedback { public string Key { get; private set; } - + public HdPsXxxOutputPort Port { get; private set; } - + public HdPsXxxOutputAudioController(string parent, uint output, HdPsXxx chassis) { Key = string.Format("{0}-audioOut{1}", parent, output); - + Port = chassis.HdmiDmLiteOutputs[output].OutputPort; - VolumeLevelFeedback = new IntFeedback(VolumeFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + VolumeLevelFeedback = new IntFeedback(() => VolumeLevel); + MuteFeedback = new BoolFeedback(() => IsMuted); + + //if(Port.AudioOutput.Volume != null) + // VolumeLevel = Port.AudioOutput.VolumeFeedback.UShortValue; + + IsMuted = Port.MuteOnFeedback.BoolValue; } #region Volume - public IntFeedback VolumeLevelFeedback { get; private set; } + private const ushort CrestronLevelMin = 0; + private const ushort CrestronLevelMax = 65535; - protected Func VolumeFeedbackFunc + private const int DeviceLevelMin = -800; + private const int DeviceLevelMax = 200; + + private const int RampTime = 5000; + + private int _volumeLevel; + + public int VolumeLevel { - get { return () => Port.AudioOutput.VolumeFeedback.UShortValue; } + get { return _volumeLevel; } + set + { + var level = value; + //_volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); + _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); + + Debug.Console(2, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); + + VolumeLevelFeedback.FireUpdate(); + } } + public IntFeedback VolumeLevelFeedback { get; private set; } + public void SetVolume(ushort level) { - Port.AudioOutput.Volume.UShortValue = level; + var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, + DeviceLevelMin); + + Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); + + Port.AudioOutput.Volume.ShortValue = (short)scaled; } public void VolumeUp(bool pressRelease) { if (pressRelease) { - var remainingRatio = (65535 - Port.AudioOutput.Volume.UShortValue)/65535; - Port.AudioOutput.Volume.CreateRamp(65535, 400); + Port.AudioOutput.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); } else { @@ -52,9 +81,8 @@ namespace PepperDash_Essentials_DM.Chassis public void VolumeDown(bool pressRelease) { if (pressRelease) - { - var remainingRatio = Port.AudioOutput.Volume.UShortValue/65535; - Port.AudioOutput.Volume.CreateRamp(0, (uint)(400 * remainingRatio)); + { + Port.AudioOutput.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); } else { @@ -65,17 +93,27 @@ namespace PepperDash_Essentials_DM.Chassis #endregion + + #region Mute private bool _isMuted; - public BoolFeedback MuteFeedback { get; private set; } + public bool IsMuted + { + get { return _isMuted; } + set + { + _isMuted = value; - protected Func MuteFeedbackFunc - { - get { return () => _isMuted = Port.MuteOnFeedback.BoolValue; } + Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted); + + MuteFeedback.FireUpdate(); + } } + public BoolFeedback MuteFeedback { get; private set; } + public void MuteOn() { Port.MuteOn(); @@ -88,7 +126,7 @@ namespace PepperDash_Essentials_DM.Chassis public void MuteToggle() { - if (_isMuted) + if (IsMuted) MuteOff(); else MuteOn(); From 6f5fa2c3b83bc2cb0cbf8ee9152172f672375230 Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Tue, 12 Dec 2023 15:29:41 -0500 Subject: [PATCH 34/46] fix: clear selected causes thread abort in 3 series - the old method was using _directoryCode, _directoryTrilist, _directoryJoinmap which were never initialized --- .../Essentials Devices Common/VideoCodec/VideoCodecBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index 187cc855..1a842bc5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -994,7 +994,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec //Special Change for protected directory clear - trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(_directoryCodec, 0, _directoryTrilist, _directoryJoinmap)); + trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(codec, 0, trilist, joinMap)); // Report feedback for number of contact methods for selected contact From 1c5aca03d295c0cb07fc509a65675a3d1adab181 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Dec 2023 12:36:45 -0600 Subject: [PATCH 35/46] fix: resolves hdPsXxx audio controllers scaleWithLimits exception --- .../Chassis/HdPsXxxAnalogAuxMixerController.cs | 7 +++++-- .../Essentials_DM/Chassis/HdPsXxxController.cs | 4 +++- .../Chassis/HdPsXxxOutputAudioController.cs | 12 ++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs index fc8ed0e2..694dbb21 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -61,6 +61,9 @@ namespace PepperDash_Essentials_DM.Chassis set { var level = value; + Debug.Console(1, this, "VolumeLevel: value-'{0}', level-'{1}'", value, level); + + // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); Debug.Console(1, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); @@ -73,8 +76,8 @@ namespace PepperDash_Essentials_DM.Chassis public void SetVolume(ushort level) { - var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, - DeviceLevelMin); + // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) + var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index a4bef385..defe9c02 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -86,11 +86,13 @@ namespace PepperDash_Essentials_DM.Chassis foreach (var item in _chassis.HdmiDmLiteOutputs) { var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis); + Debug.Console(0, this, "HdPsXxxController: created HdPsXxxOutputAudioController Key-{0}', Output-'{1}'", audioDevice.Key, item.Number); DeviceManager.AddDevice(audioDevice); } foreach (var item in _chassis.AnalogAuxiliaryMixer) { - var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); + var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); + Debug.Console(0, this, "HdPsXxxController: created HdPsXxAnalogAuxMixerCOntorller Key-{0}', Output-'{1}'", audioDevice.Key, item.MixerNumber); DeviceManager.AddDevice(audioDevice); } } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs index d8583f19..608f2465 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs @@ -45,8 +45,10 @@ namespace PepperDash_Essentials_DM.Chassis set { var level = value; - //_volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); - _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); + Debug.Console(1, this, "VolumeLevel: value-'{0}', level-'{1}'", value, level); + + // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) + _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); Debug.Console(2, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); @@ -58,8 +60,10 @@ namespace PepperDash_Essentials_DM.Chassis public void SetVolume(ushort level) { - var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, - DeviceLevelMin); + // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) + var scaled = CrestronEnvironment.ScaleWithLimits(level, + CrestronLevelMax, CrestronLevelMin, + DeviceLevelMax, DeviceLevelMin); Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); From 67e037880657831838d70230fc130a81da453360 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Dec 2023 12:41:45 -0600 Subject: [PATCH 36/46] fix: cleanup debug statements --- .../Chassis/HdPsXxxAnalogAuxMixerController.cs | 1 - .../Essentials_DM/Chassis/HdPsXxxController.cs | 14 +++++++------- .../Chassis/HdPsXxxOutputAudioController.cs | 5 +---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs index 694dbb21..c6829c9b 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -61,7 +61,6 @@ namespace PepperDash_Essentials_DM.Chassis set { var level = value; - Debug.Console(1, this, "VolumeLevel: value-'{0}', level-'{1}'", value, level); // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index defe9c02..c0363387 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -86,13 +86,13 @@ namespace PepperDash_Essentials_DM.Chassis foreach (var item in _chassis.HdmiDmLiteOutputs) { var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis); - Debug.Console(0, this, "HdPsXxxController: created HdPsXxxOutputAudioController Key-{0}', Output-'{1}'", audioDevice.Key, item.Number); + Debug.Console(2, this, "Adding HdPsXxxOutputAudioController '{0}' for output '{1}'", audioDevice.Key, item.Number); DeviceManager.AddDevice(audioDevice); } foreach (var item in _chassis.AnalogAuxiliaryMixer) { var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); - Debug.Console(0, this, "HdPsXxxController: created HdPsXxAnalogAuxMixerCOntorller Key-{0}', Output-'{1}'", audioDevice.Key, item.MixerNumber); + Debug.Console(2, this, "Adding HdPsXxAnalogAuxMixerCOntorller '{0}' for output '{1}'", audioDevice.Key, item.MixerNumber); DeviceManager.AddDevice(audioDevice); } } @@ -216,14 +216,14 @@ namespace PepperDash_Essentials_DM.Chassis VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); } - - Debug.Console(0, this, "----> AnalogAuxillaryMixer.Count-{0}", _chassis.AnalogAuxiliaryMixer.Count); + /* + Debug.Console(2, this, "----> AnalogAuxillaryMixer.Count-{0}", _chassis.AnalogAuxiliaryMixer.Count); foreach (var item in _chassis.AnalogAuxiliaryMixer) { - Debug.Console(0, this, "----> AnalogAuxillaryMixer[{0}].LineMuteVolumeControl.Count-{1}", item.MixerNumber, item.LineMuteVolumeControl.Count); - Debug.Console(0, this, "----> AnalogAuxillaryMixer[{0}].SourceMuteVolumeControl.Count-{1}", item.MixerNumber, item.SourceMuteVolumeControl.Count); + Debug.Console(2, this, "----> AnalogAuxillaryMixer[{0}].LineMuteVolumeControl.Count-{1}", item.MixerNumber, item.LineMuteVolumeControl.Count); + Debug.Console(2, this, "----> AnalogAuxillaryMixer[{0}].SourceMuteVolumeControl.Count-{1}", item.MixerNumber, item.SourceMuteVolumeControl.Count); } - + */ _chassis.DMOutputChange += _chassis_OutputChange; } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs index 608f2465..3f28d91f 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs @@ -45,7 +45,6 @@ namespace PepperDash_Essentials_DM.Chassis set { var level = value; - Debug.Console(1, this, "VolumeLevel: value-'{0}', level-'{1}'", value, level); // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); @@ -61,9 +60,7 @@ namespace PepperDash_Essentials_DM.Chassis public void SetVolume(ushort level) { // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) - var scaled = CrestronEnvironment.ScaleWithLimits(level, - CrestronLevelMax, CrestronLevelMin, - DeviceLevelMax, DeviceLevelMin); + var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); From 5530c91b75fb907ce6033bd10f2f2758c2928cd0 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 13 Dec 2023 16:01:15 -0600 Subject: [PATCH 37/46] refactor: HdPsXxxOutputAudioController & HdPsXxxAnalogAuxMixerController - Updated audio controllers to implement `Volume(Feedback).ShortValue` per documentation for set and get - Changed `VolumeLevel` set to private set - Removed `VolumeLevel` and `IsMuted` set from constructors --- .../HdPsXxxAnalogAuxMixerController.cs | 77 +++++++++++-------- .../Chassis/HdPsXxxController.cs | 2 +- .../Chassis/HdPsXxxOutputAudioController.cs | 67 +++++++++++----- 3 files changed, 94 insertions(+), 52 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs index c6829c9b..7d27d35b 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs @@ -7,39 +7,47 @@ using PepperDash.Essentials.Core; namespace PepperDash_Essentials_DM.Chassis { public class HdPsXxxAnalogAuxMixerController : IKeyed, - IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback // || IBasicVolumeWithFeedback + IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback { public string Key { get; private set; } - public HdPsXxxAnalogAuxMixer Mixer { get; private set; } + private readonly HdPsXxxAnalogAuxMixer _mixer; public HdPsXxxAnalogAuxMixerController(string parent, uint mixer, HdPsXxx chassis) { Key = string.Format("{0}-analogMixer{1}", parent, mixer); - Mixer = chassis.AnalogAuxiliaryMixer[mixer]; + _mixer = chassis.AnalogAuxiliaryMixer[mixer]; - Mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange; - Mixer.AuxiliaryMuteControl.MuteAndVolumeControlPropertyChange += OnMuteAndVolumeControlPropertyChange; + _mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange; + _mixer.AuxiliaryMuteControl.MuteAndVolumeControlPropertyChange += OnMuteAndVolumeControlPropertyChange; VolumeLevelFeedback = new IntFeedback(() => VolumeLevel); MuteFeedback = new BoolFeedback(() => IsMuted); - - VolumeLevel = Mixer.VolumeFeedback.ShortValue; - IsMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; } #region Volume private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args) { - Debug.Console(2, this, "AuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.GetType().ToString(), args.Index, args.EventId); + Debug.Console(2, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.ToString(), args.Index, args.EventId); switch (args.EventId) { - case (3): + case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId: { - VolumeLevel = Mixer.VolumeFeedback.ShortValue; + VolumeLevel = _mixer.VolumeFeedback.ShortValue; + break; + } + case MuteAndVolumeContorlEventIds.MuteOnEventId: + case MuteAndVolumeContorlEventIds.MuteOffEventId: + { + IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; + break; + } + default: + { + Debug.Console(1, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", sender.ToString(), args.Index, args.EventId); break; } } @@ -58,13 +66,12 @@ namespace PepperDash_Essentials_DM.Chassis public int VolumeLevel { get { return _volumeLevel; } - set + private set { var level = value; - // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); - + Debug.Console(1, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); VolumeLevelFeedback.FireUpdate(); @@ -72,26 +79,25 @@ namespace PepperDash_Essentials_DM.Chassis } public IntFeedback VolumeLevelFeedback { get; private set; } - + public void SetVolume(ushort level) { - // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) - var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); + var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); - Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); - - Mixer.Volume.ShortValue = (short)scaled; + Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled); + + _mixer.Volume.ShortValue = (short)levelScaled; } public void VolumeUp(bool pressRelease) { if (pressRelease) { - Mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); + _mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); } else { - Mixer.Volume.StopRamp(); + _mixer.Volume.StopRamp(); } } @@ -99,14 +105,11 @@ namespace PepperDash_Essentials_DM.Chassis { if (pressRelease) { - //var remainingRatio = Mixer.Volume.UShortValue/CrestronLevelMax; - //Mixer.Volume.CreateRamp(CrestronLevelMin, (uint)(RampTime * remainingRatio)); - - Mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); + _mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); } else { - Mixer.Volume.StopRamp(); + _mixer.Volume.StopRamp(); } } @@ -123,12 +126,22 @@ namespace PepperDash_Essentials_DM.Chassis switch (args.EventId) { - case (1): - case (2): + case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId: { - IsMuted = Mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; + VolumeLevel = _mixer.VolumeFeedback.ShortValue; break; } + case MuteAndVolumeContorlEventIds.MuteOnEventId: + case MuteAndVolumeContorlEventIds.MuteOffEventId: + { + IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue; + break; + } + default: + { + Debug.Console(1, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", device.ToString(), args.Index, args.EventId); + break; + } } } @@ -151,12 +164,12 @@ namespace PepperDash_Essentials_DM.Chassis public void MuteOn() { - Mixer.AuxiliaryMuteControl.MuteOn(); + _mixer.AuxiliaryMuteControl.MuteOn(); } public void MuteOff() { - Mixer.AuxiliaryMuteControl.MuteOff(); + _mixer.AuxiliaryMuteControl.MuteOff(); } public void MuteToggle() diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index c0363387..6b0f8520 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -88,7 +88,7 @@ namespace PepperDash_Essentials_DM.Chassis var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis); Debug.Console(2, this, "Adding HdPsXxxOutputAudioController '{0}' for output '{1}'", audioDevice.Key, item.Number); DeviceManager.AddDevice(audioDevice); - } + } foreach (var item in _chassis.AnalogAuxiliaryMixer) { var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs index 3f28d91f..57067bde 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs @@ -6,25 +6,56 @@ using PepperDash.Essentials.Core; namespace PepperDash_Essentials_DM.Chassis { public class HdPsXxxOutputAudioController : IKeyed, - IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback // || IBasicVolumeWithFeedback + IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback { public string Key { get; private set; } - public HdPsXxxOutputPort Port { get; private set; } + private readonly HdPsXxxHdmiDmLiteOutputMixer _mixer; // volume/volumeFeedback + private readonly HdPsXxxOutputPort _port; // mute/muteFeedback public HdPsXxxOutputAudioController(string parent, uint output, HdPsXxx chassis) { Key = string.Format("{0}-audioOut{1}", parent, output); - Port = chassis.HdmiDmLiteOutputs[output].OutputPort; + _port = chassis.HdmiDmLiteOutputs[output].OutputPort; + _mixer = chassis.HdmiDmLiteOutputs[output].Mixer; + + chassis.DMOutputChange += ChassisOnDmOutputChange; VolumeLevelFeedback = new IntFeedback(() => VolumeLevel); MuteFeedback = new BoolFeedback(() => IsMuted); + } - //if(Port.AudioOutput.Volume != null) - // VolumeLevel = Port.AudioOutput.VolumeFeedback.UShortValue; + private void ChassisOnDmOutputChange(Switch device, DMOutputEventArgs args) + { + switch (args.EventId) + { + case (DMOutputEventIds.VolumeEventId): + { + Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - AudioMute/UnmuteEventId", + device.ToString(), args.Index, args.EventId, args.Number); - IsMuted = Port.MuteOnFeedback.BoolValue; + VolumeLevel = _mixer.VolumeFeedback.ShortValue; + + break; + } + case DMOutputEventIds.MuteOnEventId: + case DMOutputEventIds.MuteOffEventId: + { + Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - MuteOnEventId/MuteOffEventId", + device.ToString(), args.Index, args.EventId, args.Number); + + IsMuted = _port.MuteOnFeedback.BoolValue; + + break; + } + default: + { + Debug.Console(1, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - unhandled eventId", + device.ToString(), args.Index, args.EventId, args.Number); + break; + } + } } #region Volume @@ -42,11 +73,10 @@ namespace PepperDash_Essentials_DM.Chassis public int VolumeLevel { get { return _volumeLevel; } - set + private set { var level = value; - - // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) + _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin); Debug.Console(2, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel); @@ -59,23 +89,22 @@ namespace PepperDash_Essentials_DM.Chassis public void SetVolume(ushort level) { - // ScaleWithLimits(inputValue, InputUpperBound, InputLowerBound, OutputUpperBound, OutputLowerBound) - var scaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); + var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin); - Debug.Console(1, this, "SetVolume: level-'{0}', scaled-'{1}'", level, scaled); + Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled); - Port.AudioOutput.Volume.ShortValue = (short)scaled; + _mixer.Volume.ShortValue = (short)levelScaled; } public void VolumeUp(bool pressRelease) { if (pressRelease) { - Port.AudioOutput.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); + _mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime); } else { - Port.AudioOutput.Volume.StopRamp(); + _mixer.Volume.StopRamp(); } } @@ -83,11 +112,11 @@ namespace PepperDash_Essentials_DM.Chassis { if (pressRelease) { - Port.AudioOutput.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); + _mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime); } else { - Port.AudioOutput.Volume.StopRamp(); + _mixer.Volume.StopRamp(); } } @@ -117,12 +146,12 @@ namespace PepperDash_Essentials_DM.Chassis public void MuteOn() { - Port.MuteOn(); + _port.MuteOn(); } public void MuteOff() { - Port.MuteOff(); + _port.MuteOff(); } public void MuteToggle() From 533ca05ac20f1257df85be6aaabf97fd2fe06d9c Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 14 Dec 2023 12:43:46 -0600 Subject: [PATCH 38/46] feat: adds additional dm input/output event cases to event handlers --- .../Chassis/HdPsXxxController.cs | 146 ++++++++++++------ 1 file changed, 99 insertions(+), 47 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 6b0f8520..45510a88 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -88,7 +88,7 @@ namespace PepperDash_Essentials_DM.Chassis var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis); Debug.Console(2, this, "Adding HdPsXxxOutputAudioController '{0}' for output '{1}'", audioDevice.Key, item.Number); DeviceManager.AddDevice(audioDevice); - } + } foreach (var item in _chassis.AnalogAuxiliaryMixer) { var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis); @@ -111,7 +111,7 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "Failed to setup inputs, properties are null"); return; } - + // iterate through HDMI inputs foreach (var item in _chassis.HdmiInputs) { @@ -124,7 +124,7 @@ namespace PepperDash_Essentials_DM.Chassis input.Name.StringValue = name; - InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), () => InputNames[index])); var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) @@ -134,10 +134,10 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(1, this, "Adding Input port: {0} - {1}", port.Key, name); InputPorts.Add(port); - InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), () => input.VideoDetectedFeedback.BoolValue)); } @@ -147,13 +147,13 @@ namespace PepperDash_Essentials_DM.Chassis var input = item; var index = item.Number; var key = string.Format("dmLiteIn{0}", index); - var name = string.IsNullOrEmpty(InputNames[index]) - ? string.Format("DM Input {0}", index) + var name = string.IsNullOrEmpty(InputNames[index]) + ? string.Format("DM Input {0}", index) : InputNames[index]; input.Name.StringValue = name; - InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), () => InputNames[index])); var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this) @@ -163,10 +163,10 @@ namespace PepperDash_Essentials_DM.Chassis Debug.Console(0, this, "Adding Input port: {0} - {1}", port.Key, name); InputPorts.Add(port); - InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); - VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), + VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), () => input.VideoDetectedFeedback.BoolValue)); } @@ -186,10 +186,10 @@ namespace PepperDash_Essentials_DM.Chassis { var output = item; var index = item.Number; - var name = string.IsNullOrEmpty(OutputNames[index]) - ? string.Format("Port {0}", index) + var name = string.IsNullOrEmpty(OutputNames[index]) + ? string.Format("Port {0}", index) : OutputNames[index]; - + output.Name.StringValue = name; var hdmiKey = string.Format("hdmiOut{0}", index); @@ -209,11 +209,11 @@ namespace PepperDash_Essentials_DM.Chassis }; Debug.Console(1, this, "Adding Port port: {0} - {1}", dmLitePort.Key, name); OutputPorts.Add(dmLitePort); - - OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), - () => output.VideoOutFeedback.NameFeedback.StringValue)); - VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), + OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture), + () => output.VideoOutFeedback.NameFeedback.StringValue)); + + VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture), () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number)); } /* @@ -352,8 +352,8 @@ Selector: {4} public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { var input = inputSelector as HdPsXxxInput; - var output = outputSelector as HdPsXxxOutput; - + var output = outputSelector as HdPsXxxOutput; + Debug.Console(2, this, "ExecuteSwitch: input={0}, output={1}", input, output); if (output == null) @@ -456,24 +456,58 @@ Selector: {4} // _chassis input change event private void _chassis_InputChange(Switch device, DMInputEventArgs args) { - var eventId = args.EventId; - - switch (eventId) + switch (args.EventId) { + case DMInputEventIds.RemoteTransmitterDetectedEventId: + { + // signal found on HD-PSXxx > Inputs > Inputs DM Lite X + Debug.Console(2, this, "{0} DM Input Event ID {1}-RemoteTransmitterDetected | Number {2}", + device.ToString(), args.EventId, args.Number); + break; + } + case DMInputEventIds.SourceSyncEventId: + { + // signal found on HD-PSXxx > Inputs > HDMI/DM Lite X + Debug.Console(1, this, "{0} DM Input Event ID {1}-SourceSync | Number {2}: Updating VideoInputSyncFeedbacks", + device.ToString(), args.EventId, args.Number); + + var input = args.Number; + + var feedback = VideoInputSyncFeedbacks[(int)input]; + if (feedback == null) return; + + feedback.FireUpdate(); + + //foreach (var item in VideoInputSyncFeedbacks) + //{ + // item.FireUpdate(); + //} + break; + } case DMInputEventIds.VideoDetectedEventId: { - Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", eventId); - foreach (var item in VideoInputSyncFeedbacks) - { - item.FireUpdate(); - } + Debug.Console(1, this, "{0} DM Input Event ID {1}-VideoDetected | Number {2}: Updating VideoInputSyncFeedbacks", + device.ToString(), args.EventId, args.Number); + + var input = args.Number; + + var feedback = VideoInputSyncFeedbacks[(int) input]; + if (feedback == null) return; + + feedback.FireUpdate(); + + //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); + Debug.Console(1, this, "{0} DM Input Event ID {1}-Name | Number {2}: Updating name feedbacks", + device.ToString(), args.EventId, args.Number); var input = args.Number; var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; @@ -483,7 +517,8 @@ Selector: {4} } default: { - Debug.Console(1, this, "Uhandled DM Input Event ID {0}", eventId); + Debug.Console(1, this, "{0} DM Input Event ID {1} | Number {2}: Uhandled", + device.ToString(), args.EventId, args.Number); break; } } @@ -491,33 +526,50 @@ Selector: {4} OnDmInputChange(args); } - // _chassis output change event private void _chassis_OutputChange(Switch device, DMOutputEventArgs args) { - if (args.EventId != DMOutputEventIds.VideoOutEventId) return; + switch (args.EventId) + { + case DMOutputEventIds.VideoOutEventId: + { + var output = args.Number; - var output = args.Number; + var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null + ? 0 + : _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback.Number; - var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null - ? 0 - : _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback.Number; + var outputName = OutputNames[output]; - var outputName = OutputNames[output]; + var feedback = VideoOutputRouteFeedbacks[outputName]; + if (feedback == null) return; - var feedback = VideoOutputRouteFeedbacks[outputName]; - if (feedback == null) return; + var inputPort = InputPorts.FirstOrDefault( + p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback); - var inputPort = InputPorts.FirstOrDefault( - p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback); + var outputPort = OutputPorts.FirstOrDefault( + p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output]); - var outputPort = OutputPorts.FirstOrDefault( - p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output]); + feedback.FireUpdate(); - feedback.FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs(output, input, outputPort, inputPort, eRoutingSignalType.AudioVideo)); - OnSwitchChange(new RoutingNumericEventArgs( - output, input, outputPort, inputPort, eRoutingSignalType.AudioVideo)); + break; + } + case DMOutputEventIds.RemoteReceiverDetectedEventId: + { + // signal found on HD-PSXxx > Output[s] > Output [X] > DM Lite [X] + Debug.Console(2, this, "{0} DM Output Event Id {1} | Number:{2} | Index {3}: RemoteRecevierDetectedEventId", + device.ToString(), args.EventId, args.Number, args.Index); + break; + } + default: + { + Debug.Console(2, this, "{0} DM Output Event Id {1} | Number:{2} | Index:{3}: Unhandled", + device.ToString(), args.EventId, args.Number, args.Index); + break; + } + } } @@ -543,9 +595,9 @@ Selector: {4} #region Factory - public class HdSp401ControllerFactory : EssentialsDeviceFactory + public class HdPsXxxControllerFactory : EssentialsDeviceFactory { - public HdSp401ControllerFactory() + public HdPsXxxControllerFactory() { TypeNames = new List { "hdps401", "hdps402", "hdps621", "hdps622" }; } From 19f2c6aa7976580b8da1695a8c5459fddb63ba79 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 14 Dec 2023 16:32:22 -0600 Subject: [PATCH 39/46] fix: update dm event handlers, adds debug statements --- .../Chassis/HdPsXxxController.cs | 48 ++++++------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index 45510a88..c0723893 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -138,7 +138,7 @@ namespace PepperDash_Essentials_DM.Chassis () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), - () => input.VideoDetectedFeedback.BoolValue)); + () => input.InputPort.SyncDetectedFeedback.BoolValue)); } // iterate through DM Lite inputs @@ -167,7 +167,7 @@ namespace PepperDash_Essentials_DM.Chassis () => input.InputPort.HdcpSupportOnFeedback.BoolValue)); VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture), - () => input.VideoDetectedFeedback.BoolValue)); + () => input.InputPort.SyncDetectedFeedback.BoolValue)); } _chassis.DMInputChange += _chassis_InputChange; @@ -459,17 +459,18 @@ Selector: {4} switch (args.EventId) { case DMInputEventIds.RemoteTransmitterDetectedEventId: - { + { // signal found on HD-PSXxx > Inputs > Inputs DM Lite X Debug.Console(2, this, "{0} DM Input Event ID {1}-RemoteTransmitterDetected | Number {2}", device.ToString(), args.EventId, args.Number); break; } - case DMInputEventIds.SourceSyncEventId: + case DMInputEventIds.SourceSyncEventId: // id-14 + case DMInputEventIds.VideoDetectedEventId: // id-9 { // signal found on HD-PSXxx > Inputs > HDMI/DM Lite X Debug.Console(1, this, "{0} DM Input Event ID {1}-SourceSync | Number {2}: Updating VideoInputSyncFeedbacks", - device.ToString(), args.EventId, args.Number); + device.Name, args.EventId, args.Number); var input = args.Number; @@ -478,28 +479,6 @@ Selector: {4} feedback.FireUpdate(); - //foreach (var item in VideoInputSyncFeedbacks) - //{ - // item.FireUpdate(); - //} - break; - } - case DMInputEventIds.VideoDetectedEventId: - { - Debug.Console(1, this, "{0} DM Input Event ID {1}-VideoDetected | Number {2}: Updating VideoInputSyncFeedbacks", - device.ToString(), args.EventId, args.Number); - - var input = args.Number; - - var feedback = VideoInputSyncFeedbacks[(int) input]; - if (feedback == null) return; - - feedback.FireUpdate(); - - //foreach (var item in VideoInputSyncFeedbacks) - //{ - // item.FireUpdate(); - //} break; } case DMInputEventIds.InputNameFeedbackEventId: @@ -507,7 +486,7 @@ Selector: {4} case DMInputEventIds.NameFeedbackEventId: { Debug.Console(1, this, "{0} DM Input Event ID {1}-Name | Number {2}: Updating name feedbacks", - device.ToString(), args.EventId, args.Number); + device.Name, args.EventId, args.Number); var input = args.Number; var name = _chassis.HdmiInputs[input].NameFeedback.StringValue; @@ -518,7 +497,7 @@ Selector: {4} default: { Debug.Console(1, this, "{0} DM Input Event ID {1} | Number {2}: Uhandled", - device.ToString(), args.EventId, args.Number); + device.Name, args.EventId, args.Number); break; } } @@ -533,6 +512,9 @@ Selector: {4} { case DMOutputEventIds.VideoOutEventId: { + Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index {3}: VideoOutEventId", + device.Name, args.EventId, args.Number, args.Index); + var output = args.Number; var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null @@ -559,14 +541,14 @@ Selector: {4} case DMOutputEventIds.RemoteReceiverDetectedEventId: { // signal found on HD-PSXxx > Output[s] > Output [X] > DM Lite [X] - Debug.Console(2, this, "{0} DM Output Event Id {1} | Number:{2} | Index {3}: RemoteRecevierDetectedEventId", - device.ToString(), args.EventId, args.Number, args.Index); + Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index {3}: RemoteRecevierDetectedEventId", + device.Name, args.EventId, args.Number, args.Index); break; } default: { - Debug.Console(2, this, "{0} DM Output Event Id {1} | Number:{2} | Index:{3}: Unhandled", - device.ToString(), args.EventId, args.Number, args.Index); + Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index:{3}: Unhandled", + device.Name, args.EventId, args.Number, args.Index); break; } } From b24501642079c1f936f6c678aac474e4c7f651e6 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 14 Dec 2023 17:02:14 -0600 Subject: [PATCH 40/46] fix: updated dminputchange event debug message --- .../Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs index c0723893..c267acea 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs @@ -469,7 +469,7 @@ Selector: {4} case DMInputEventIds.VideoDetectedEventId: // id-9 { // signal found on HD-PSXxx > Inputs > HDMI/DM Lite X - Debug.Console(1, this, "{0} DM Input Event ID {1}-SourceSync | Number {2}: Updating VideoInputSyncFeedbacks", + Debug.Console(1, this, "{0} DM Input Event ID {1} | Number {2}: Updating VideoInputSyncFeedbacks", device.Name, args.EventId, args.Number); var input = args.Number; From be96adcc0667ac38f2cb212666a4aab42ec85f55 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Tue, 19 Dec 2023 10:50:55 -0600 Subject: [PATCH 41/46] feat: add cen-io-com102 and cen-io-com202 support --- .../CenIoCom/CenIoComController.cs | 85 +++++++++++++++++++ .../PepperDash_Essentials_Core.csproj | 1 + 2 files changed, 86 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs new file mode 100644 index 00000000..bbd496b4 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.GeneralIO; +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core.CrestronIO +{ + /// + /// Wrapper class for CEN-IO-COM-Xxx expander module + /// + [Description("Wrapper class for the CEN-IO-COM-102 & CEN-IO-COM-202 expander module")] + public class CenIoComController : CrestronGenericBaseDevice, IComPorts + { + private readonly CenIoCom _cenIoCom; + + public CenIoComController(string key, string name, CenIoCom cenIo) + :base(key, name, cenIo) + { + _cenIoCom = cenIo; + } + + #region Implementation of IComPorts + + public CrestronCollection ComPorts + { + get { return _cenIoCom.ComPorts; } + } + + public int NumberOfComPorts + { + get { return _cenIoCom.NumberOfComPorts; } + } + + #endregion + + } + + public class CenIoCom102ControllerFactory : EssentialsDeviceFactory + { + private const string CenIoCom102Type = "ceniocom102"; + private const string CenIoCom202Type = "ceniocom202"; + + public CenIoCom102ControllerFactory() + { + TypeNames = new List { CenIoCom102Type, CenIoCom202Type }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new CEN-IO-COM-Xxx Device"); + + var control = CommFactory.GetControlPropertiesConfig(dc); + if (control == null) + { + Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, control properties not found"); + return null; + } + + var ipid = control.IpIdInt; + if (ipid < 2) + { + Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid IP-ID found"); + return null; + } + + switch (dc.Type) + { + case CenIoCom102Type: + { + return new CenIoComController(dc.Key, dc.Name, new CenIoCom102(ipid, Global.ControlSystem)); + } + case CenIoCom202Type: + { + return new CenIoComController(dc.Key, dc.Name, new CenIoCom202(ipid, Global.ControlSystem)); + } + default: + { + Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid type '{0}'", dc.Type); + return null; + } + } + } + } +} \ 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 c1445edb..4c01cc6a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -184,6 +184,7 @@ + From 26f9118154b6b0ccb65a16097b89de1e2ff43c06 Mon Sep 17 00:00:00 2001 From: jtalborough Date: Thu, 25 Jan 2024 13:15:12 -0500 Subject: [PATCH 42/46] chore: update PepperDashCore package version --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 761b11cb..649b9bdb 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + From b52c13d8e877eda359c9d8d6bc87abf27ff30b49 Mon Sep 17 00:00:00 2001 From: jtalborough Date: Thu, 25 Jan 2024 13:50:44 -0500 Subject: [PATCH 43/46] fix: Update PepperDashCore package version to 1.3.2 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 649b9bdb..fa36e07d 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + From 8c1553a0269e36760fea6cdb1469201d8b49eae9 Mon Sep 17 00:00:00 2001 From: jtalborough Date: Mon, 26 Feb 2024 13:22:35 -0500 Subject: [PATCH 44/46] fix: Update PepperDashCore version to 1.3.3-hotfix-390 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index fa36e07d..eff6d8ce 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + From 4c466b425ce5f02ccaa84027c2ce1973eead39f6 Mon Sep 17 00:00:00 2001 From: Aviv Cohn Date: Thu, 25 Apr 2024 10:24:09 -0400 Subject: [PATCH 45/46] fix: Change console message to include "use eiscApiAdvanced" --- PepperDashEssentials/Bridges/EiscBridge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/Bridges/EiscBridge.cs b/PepperDashEssentials/Bridges/EiscBridge.cs index 21a220ef..c768924b 100644 --- a/PepperDashEssentials/Bridges/EiscBridge.cs +++ b/PepperDashEssentials/Bridges/EiscBridge.cs @@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Bridges catch (NullReferenceException) { Debug.ConsoleWithLog(0, this, - "Please update the bridge config to use EiscBridgeAdvanced with this device: {0}", device.Key); + "Please update the bridge config to use eiscApiAdvanced with this device: {0}", device.Key); } } Debug.Console(1, this, "Devices Linked."); From 9e588f4da5c26908631c62f7b989d7dd4278385b Mon Sep 17 00:00:00 2001 From: AECohn <34989255+AECohn@users.noreply.github.com> Date: Thu, 25 Apr 2024 10:42:40 -0400 Subject: [PATCH 46/46] fix: ghidra specific verbiage --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 890b7769..d44e7848 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,8 +91,8 @@ we receive and the availability of resources to evaluate contributions, we antic project remains dynamic and relevant. This may affect our responsiveness and ability to accept pull requests quickly. This does not mean we are ignoring them. - Not all innovative ideas need to be accepted as pull requests into this GitHub project to be valuable to the community. - There may be times when we recommend that you just share your code for some enhancement to Ghidra from your own - repository. As we identify and recognize extensions that are of general interest to the reverse engineering community, we + There may be times when we recommend that you just share your code for some enhancement to Essentials from your own + repository. As we identify and recognize extensions that are of general interest to Essentials, we may seek to incorporate them with our baseline. ## Legal