From 531c37c7528e463b8ebcbca34cb65e193e006f85 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Tue, 28 Apr 2020 17:15:38 -0500 Subject: [PATCH] resolves #135 - Adds new controller class for DM-RMC-4K-Z-100-C Extends existing controller class for RmcX100C devices and gives it additional connection metadata to report --- .../Receivers/DmRmc4kZScalerCController.cs | 151 +++++++++ .../Endpoints/Receivers/DmRmcHelper.cs | 9 +- .../Receivers/RmRmc4kZ100CController.cs | 95 ++++++ .../PepperDash_Essentials_DM.csproj | 317 +++++++++--------- 4 files changed, 410 insertions(+), 162 deletions(-) create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/RmRmc4kZ100CController.cs diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs new file mode 100644 index 00000000..a42b6771 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Receivers; + +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Core; + +namespace PepperDash.Essentials.DM +{ + public class DmRmc4kZScalerCController : DmRmcControllerBase, IRmcRouting, + IIROutputPorts, IComPorts, ICec + { + public DmRmc4kzScalerC Rmc { get; private set; } + + public RoutingInputPort DmIn { get; private set; } + public RoutingInputPort HdmiIn { get; private set; } + public RoutingOutputPort HdmiOut { get; private set; } + + /// + /// The value of the current video source for the HDMI output on the receiver + /// + public IntFeedback AudioVideoSourceNumericFeedback { get; private set; } + + public RoutingPortCollection InputPorts + { + get { return new RoutingPortCollection { DmIn, HdmiIn }; } + } + + public RoutingPortCollection OutputPorts + { + get { return new RoutingPortCollection { HdmiOut }; } + } + + public DmRmc4kZScalerCController(string key, string name, DmRmc4kzScalerC rmc) + : base(key, name, rmc) + { + Rmc = rmc; + DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 0, this); + HdmiIn = new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 0, this); + HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + EdidManufacturerFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue); + EdidNameFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.Name.StringValue); + EdidPreferredTimingFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue); + EdidSerialNumberFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue); + + VideoOutputResolutionFeedback = new StringFeedback(() => Rmc.HdmiOutput.GetVideoResolutionString()); + + Rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange; + Rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange; + + // Set Ports for CEC + HdmiOut.Port = Rmc.HdmiOutput; + + AudioVideoSourceNumericFeedback = new IntFeedback(() => (ushort)(Rmc.SelectedSourceFeedback)); + } + + void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args) + { + if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId || + args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId) + { + VideoOutputResolutionFeedback.FireUpdate(); + } + + if (args.EventId == EndpointOutputStreamEventIds.SelectedSourceFeedbackEventId) + { + AudioVideoSourceNumericFeedback.FireUpdate(); + } + } + + void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args) + { + if (args.EventId == ConnectedDeviceEventIds.ManufacturerEventId) + { + EdidManufacturerFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.NameEventId) + { + EdidNameFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.PreferredTimingEventId) + { + EdidPreferredTimingFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.SerialNumberEventId) + { + EdidSerialNumberFeedback.FireUpdate(); + } + } + + public override bool CustomActivate() + { + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region IIROutputPorts Members + public CrestronCollection IROutputPorts { get { return Rmc.IROutputPorts; } } + public int NumberOfIROutputPorts { get { return Rmc.NumberOfIROutputPorts; } } + #endregion + + #region IComPorts Members + public CrestronCollection ComPorts { get { return Rmc.ComPorts; } } + public int NumberOfComPorts { get { return Rmc.NumberOfComPorts; } } + #endregion + + #region ICec Members + /// + /// Gets the CEC stream directly from the HDMI port. + /// + public Cec StreamCec { get { return Rmc.HdmiOutput.StreamCec; } } + #endregion + + + #region IRmcRouting Members + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + Debug.Console(2, this, "Attempting a route from input {0} to HDMI Output", inputSelector); + + var number = Convert.ToUInt16(inputSelector); + + Rmc.AudioVideoSource = (DmRmc4kzScalerC.eAudioVideoSource)number; + } + + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) + { + Debug.Console(2, this, "Attempting a route from input {0} to HDMI Output", inputSelector); + + Rmc.AudioVideoSource = (DmRmc4kzScalerC.eAudioVideoSource)inputSelector; + } + #endregion + + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs index da3e587a..64b84fe9 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs @@ -146,7 +146,7 @@ namespace PepperDash.Essentials.DM if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(ipid, Global.ControlSystem)); if (typeName.StartsWith("dmrmc4kz100c")) - return new DmRmcX100CController(key, name, new DmRmc4kz100C(ipid, Global.ControlSystem)); + return new RmRmc4kZ100CController(key, name, new DmRmc4kz100C(ipid, Global.ControlSystem)); if (typeName.StartsWith("dmrmc150s")) return new DmRmc150SController(key, name, new DmRmc150S(ipid, Global.ControlSystem)); if (typeName.StartsWith("dmrmc200c")) @@ -219,7 +219,7 @@ namespace PepperDash.Essentials.DM if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4kz100c")) - return new DmRmcX100CController(key, name, new DmRmc4kz100C(chassis.Outputs[num])); + return new RmRmc4kZ100CController(key, name, new DmRmc4kz100C(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc150s")) return new DmRmc150SController(key, name, new DmRmc150S(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc200c")) @@ -252,7 +252,7 @@ namespace PepperDash.Essentials.DM if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4kz100c")) - return new DmRmcX100CController(key, name, new DmRmc4kz100C(ipid, chassis.Outputs[num])); + return new RmRmc4kZ100CController(key, name, new DmRmc4kz100C(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc150s")) return new DmRmc150SController(key, name, new DmRmc150S(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc200c")) @@ -288,7 +288,8 @@ namespace PepperDash.Essentials.DM public DmRmcControllerFactory() { TypeNames = new List() { "hdbasetrx", "dmrmc4k100c1g", "dmrmc100c", "dmrmc100s", "dmrmc4k100c", "dmrmc150s", - "dmrmc200c", "dmrmc200s", "dmrmc200s2", "dmrmcscalerc", "dmrmcscalers", "dmrmcscalers2", "dmrmc4kscalerc", "dmrmc4kscalercdsp" }; + "dmrmc200c", "dmrmc200s", "dmrmc200s2", "dmrmcscalerc", "dmrmcscalers", "dmrmcscalers2", "dmrmc4kscalerc", "dmrmc4kscalercdsp", + "dmrmc4kz100c" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/RmRmc4kZ100CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/RmRmc4kZ100CController.cs new file mode 100644 index 00000000..1ff5ec80 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/RmRmc4kZ100CController.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Receivers; + +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.DM +{ + public class RmRmc4kZ100CController : DmRmcX100CController + { + public new DmRmc4kz100C Rmc { get; private set; } + + public RoutingInputPort DmIn { get; private set; } + public RoutingOutputPort HdmiOut { get; private set; } + + public RoutingPortCollection InputPorts + { + get { return new RoutingPortCollection { DmIn }; } + } + + public RoutingPortCollection OutputPorts + { + get { return new RoutingPortCollection { HdmiOut }; } + } + + public RmRmc4kZ100CController(string key, string name, DmRmc4kz100C rmc) + : base(key, name, rmc) + { + Rmc = rmc; + DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 0, this); + HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + // Set Ports for CEC + HdmiOut.Port = Rmc; // Unique case, this class has no HdmiOutput port and ICec is implemented on the receiver class itself + + EdidManufacturerFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue); + EdidNameFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.Name.StringValue); + EdidPreferredTimingFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue); + EdidSerialNumberFeedback = new StringFeedback(() => Rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue); + + Rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange; + Rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange; + } + + void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args) + { + if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId || + args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId) + { + VideoOutputResolutionFeedback.FireUpdate(); + } + } + + void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args) + { + if (args.EventId == ConnectedDeviceEventIds.ManufacturerEventId) + { + EdidManufacturerFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.NameEventId) + { + EdidNameFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.PreferredTimingEventId) + { + EdidPreferredTimingFeedback.FireUpdate(); + } + else if (args.EventId == ConnectedDeviceEventIds.SerialNumberEventId) + { + EdidSerialNumberFeedback.FireUpdate(); + } + } + + public override bool CustomActivate() + { + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge); + } + } +} \ 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 f8ea57a9..bb165f92 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -1,159 +1,160 @@ - - - Release - AnyCPU - 9.0.30729 - 2.0 - {9199CE8A-0C9F-4952-8672-3EED798B284F} - Library - Properties - PepperDash_Essentials_DM - PepperDash_Essentials_DM - {0B4745B0-194B-4BB6-8E21-E9057CA92300};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - WindowsCE - E2BECB1F-8C8C-41ba-B736-9BE7D946A398 - 5.0 - SmartDeviceProject1 - v3.5 - Windows CE - - - - - .allowedReferenceRelatedFileExtensions - true - full - false - bin\ - DEBUG;TRACE; - prompt - 4 - 512 - true - true - off - - - .allowedReferenceRelatedFileExtensions - none - true - bin\ - prompt - 4 - 512 - true - true - off - - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll - - - - False - ..\..\pepperdashcore-builds\PepperDash_Core.dll - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll - False - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll - False - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll - - - False - ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe - False - - - False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} - PepperDash_Essentials_Core - - - - - - - - - rem S# Pro preparation will execute after these operations - + + + Release + AnyCPU + 9.0.30729 + 2.0 + {9199CE8A-0C9F-4952-8672-3EED798B284F} + Library + Properties + PepperDash_Essentials_DM + PepperDash_Essentials_DM + {0B4745B0-194B-4BB6-8E21-E9057CA92300};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + WindowsCE + E2BECB1F-8C8C-41ba-B736-9BE7D946A398 + 5.0 + SmartDeviceProject1 + v3.5 + Windows CE + + + + + .allowedReferenceRelatedFileExtensions + true + full + false + bin\ + DEBUG;TRACE; + prompt + 4 + 512 + true + true + off + + + .allowedReferenceRelatedFileExtensions + none + true + bin\ + prompt + 4 + 512 + true + true + off + + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll + + + + False + ..\..\pepperdashcore-builds\PepperDash_Core.dll + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + False + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + False + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + + + False + ..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + False + + + False + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} + PepperDash_Essentials_Core + + + + + + + + + rem S# Pro preparation will execute after these operations + \ No newline at end of file