diff --git a/PepperDashEssentials/Bridges/BridgeBase.cs b/PepperDashEssentials/Bridges/BridgeBase.cs index 68ca0751..d14af594 100644 --- a/PepperDashEssentials/Bridges/BridgeBase.cs +++ b/PepperDashEssentials/Bridges/BridgeBase.cs @@ -107,6 +107,11 @@ namespace PepperDash.Essentials.Bridges (device as DmpsRoutingController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); continue; } + else if (device is DmpsAudioOutputController) + { + (device as DmpsAudioOutputController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); + continue; + } else if (device is DmTxControllerBase) { (device as DmTxControllerBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); @@ -136,6 +141,11 @@ namespace PepperDash.Essentials.Bridges { (device as IBridge).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); continue; + } + else if (device is HdMdxxxCEController) + { + (device as HdMdxxxCEController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); + continue; } //else if (device is LightingBase) //{ diff --git a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs index 14fa580c..90eea6b1 100644 --- a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs @@ -206,8 +206,10 @@ namespace PepperDash.Essentials.Bridges public class DmChassisControllerJoinMap : JoinMapBase { - //Digital + // Digtal/Analog public uint SystemId { get; set; } + + //Digital public uint IsOnline { get; set; } public uint OutputUsb { get; set; } public uint InputUsb { get; set; } @@ -233,7 +235,9 @@ namespace PepperDash.Essentials.Bridges public DmChassisControllerJoinMap() { - SystemId = 10; + //Digital/Analog + SystemId = 10; // Analog sets/gets SystemId, digital input applies and provides feedback of ID change busy + //Digital IsOnline = 11; VideoSyncStatus = 100; //101-299 @@ -261,8 +265,6 @@ namespace PepperDash.Essentials.Bridges OutputEndpointOnline = 700; //701-899 HdcpSupportState = 1000; //1001-1199 HdcpSupportCapability = 1200; //1201-1399 - - } public override void OffsetJoinNumbers(uint joinStart) diff --git a/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs b/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs new file mode 100644 index 00000000..16f74716 --- /dev/null +++ b/PepperDashEssentials/Bridges/DmpsAudioOutputControllerBridge.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.DM; + +namespace PepperDash.Essentials.Bridges +{ + public static class DmpsAudioOutputControllerApiExtensions + { + public static void LinkToApi(this DmpsAudioOutputController dmAudioOutputController, BasicTriList trilist, uint joinStart, string joinMapKey) + { + var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DmpsAudioOutputControllerJoinMap; + + if (joinMap == null) + joinMap = new DmpsAudioOutputControllerJoinMap(); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, dmAudioOutputController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + if (dmAudioOutputController.MasterVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.MasterVolumeLevel, joinMap.MasterVolume); + } + + if (dmAudioOutputController.SourceVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.SourceVolumeLevel, joinMap.SourceVolume); + } + + if (dmAudioOutputController.Codec1VolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.Codec1VolumeLevel, joinMap.Codec1Volume); + } + + if (dmAudioOutputController.Codec2VolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.Codec2VolumeLevel, joinMap.Codec2Volume); + } + + } + + static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart) + { + var volumeLevelJoin = joinStart; + var muteOnJoin = joinStart + 1; + var muteOffJoin = joinStart + 2; + var volumeUpJoin = joinStart + 3; + var volumeDownJoin = joinStart + 4; + + + trilist.SetUShortSigAction(volumeLevelJoin, new Action(o => output.SetVolume(o))); + output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); + + trilist.SetSigTrueAction(muteOnJoin, new Action(output.MuteOn)); + output.MuteFeedback.LinkInputSig(trilist.BooleanInput[muteOnJoin]); + trilist.SetSigTrueAction(muteOffJoin, new Action(output.MuteOff)); + output.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[muteOffJoin]); + + trilist.SetBoolSigAction(volumeUpJoin, new Action(b => output.VolumeUp(b))); + trilist.SetBoolSigAction(volumeDownJoin, new Action(b => output.VolumeDown(b))); + } + + public class DmpsAudioOutputControllerJoinMap: JoinMapBase + { + // Digital + public uint MasterVolume { get; set; } + public uint SourceVolume { get; set; } + public uint Codec1Volume { get; set; } + public uint Codec2Volume { get; set; } + + + public DmpsAudioOutputControllerJoinMap() + { + MasterVolume = 1; // 1-10 + SourceVolume = 11; // 11-20 + Codec1Volume = 21; // 21-30 + Codec2Volume = 31; // 31-40 + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart -1; + + MasterVolume = MasterVolume + joinOffset; + SourceVolume = SourceVolume + joinOffset; + Codec1Volume = Codec1Volume + joinOffset; + Codec2Volume = Codec2Volume + joinOffset; + } + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs b/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs index 1f61b1b6..9071f234 100644 --- a/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs @@ -139,7 +139,7 @@ namespace PepperDash.Essentials.Bridges public DmpsRoutingControllerJoinMap() - {; + { OutputVideo = 100; //101-299 OutputAudio = 300; //301-499 VideoSyncStatus = 100; //101-299 @@ -148,8 +148,8 @@ namespace PepperDash.Essentials.Bridges OutputCurrentVideoInputNames = 2000; //2001-2199 OutputCurrentAudioInputNames = 2200; //2201-2399 InputCurrentResolution = 2400; // 2401-2599 - InputEndpointOnline = 500; - OutputEndpointOnline = 700; + InputEndpointOnline = 500; //501-699 + OutputEndpointOnline = 700; //701-899 //HdcpSupport = 1000; //1001-1199 //HdcpSupportCapability = 1200; //1201-1399 diff --git a/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs b/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs new file mode 100644 index 00000000..1c21789c --- /dev/null +++ b/PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Receivers; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.DM; + +namespace PepperDash.Essentials.Bridges +{ + public static class HdMdxxxCEControllerApiExtensions + { + public static void LinkToApi(this HdMdxxxCEController hdMdPair, BasicTriList trilist, uint joinStart, string joinMapKey) + { + var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as HdMdxxxCEControllerJoinMap; + + if (joinMap == null) + joinMap = new HdMdxxxCEControllerJoinMap(); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, hdMdPair, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + hdMdPair.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + hdMdPair.RemoteEndDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RemoteEndDetected]); + + trilist.SetSigTrueAction(joinMap.AutoRouteOn, new Action(() => hdMdPair.AutoRouteOn())); + hdMdPair.AutoRouteOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutoRouteOn]); + trilist.SetSigTrueAction(joinMap.AutoRouteOff, new Action(() => hdMdPair.AutoRouteOff())); + hdMdPair.AutoRouteOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.AutoRouteOff]); + + trilist.SetSigTrueAction(joinMap.PriorityRoutingOn, new Action(() => hdMdPair.PriorityRouteOn())); + hdMdPair.PriorityRoutingOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOn]); + trilist.SetSigTrueAction(joinMap.PriorityRoutingOff, new Action(() => hdMdPair.PriorityRouteOff())); + hdMdPair.PriorityRoutingOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOff]); + + trilist.SetSigTrueAction(joinMap.InputOnScreenDisplayEnabled, new Action(() => hdMdPair.OnScreenDisplayEnable())); + hdMdPair.InputOnScreenDisplayEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayEnabled]); + trilist.SetSigTrueAction(joinMap.AutoRouteOff, new Action(() => hdMdPair.OnScreenDisplayDisable())); + hdMdPair.InputOnScreenDisplayEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayDisabled]); + + trilist.SetUShortSigAction(joinMap.VideoSource, new Action((i) => hdMdPair.ExecuteSwitch(i, null, eRoutingSignalType.Video | eRoutingSignalType.Audio))); + hdMdPair.VideoSourceFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoSource]); + + trilist.UShortInput[joinMap.SourceCount].UShortValue = (ushort)hdMdPair.InputPorts.Count; + + foreach (var input in hdMdPair.InputPorts) + { + var number = Convert.ToUInt16(input.Selector); + hdMdPair.SyncDetectedFeedbacks[number].LinkInputSig(trilist.BooleanInput[joinMap.SyncDetected + number]); + trilist.StringInput[joinMap.SourceNames + number].StringValue = input.Key; + } + + } + + public class HdMdxxxCEControllerJoinMap : JoinMapBase + { + #region Digitals + /// + /// High when the pair is online + /// + public uint IsOnline { get; set; } + + /// + /// High when the remote end device is online + /// + public uint RemoteEndDetected { get; set; } + + /// + /// Sets Auto Route On and provides feedback + /// + public uint AutoRouteOn { get; set; } + + /// + /// Sets Auto Route Off and provides feedback + /// + public uint AutoRouteOff { get; set; } + + /// + /// Sets Priority Routing On and provides feedback + /// + public uint PriorityRoutingOn { get; set; } + + /// + /// Sets Priority Routing Off and provides feedback + /// + public uint PriorityRoutingOff { get; set; } + + /// + /// Enables OSD and provides feedback + /// + public uint InputOnScreenDisplayEnabled { get; set; } + + /// + /// Disables OSD and provides feedback + /// + public uint InputOnScreenDisplayDisabled { get; set; } + + /// + /// Provides Video Sync Detected feedback for each input + /// + public uint SyncDetected { get; set; } + #endregion + + #region Analogs + /// + /// Sets the video source for the receiver's HDMI out and provides feedback + /// + public uint VideoSource { get; set; } + + /// + /// Indicates the number of sources supported by the Tx/Rx pair + /// + public uint SourceCount { get; set; } + #endregion + + #region Serials + /// + /// Indicates the name of each input port + /// + public uint SourceNames { get; set; } + #endregion + + public HdMdxxxCEControllerJoinMap() + { + //Digital + IsOnline = 1; + RemoteEndDetected = 2; + AutoRouteOn = 3; + AutoRouteOff = 4; + PriorityRoutingOn = 5; + PriorityRoutingOff = 6; + InputOnScreenDisplayEnabled = 7; + InputOnScreenDisplayDisabled = 8; + SyncDetected = 10; // 11-15 + + //Analog + VideoSource = 1; + SourceCount = 2; + + //Serials + SourceNames = 10; // 11-15 + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + IsOnline = IsOnline + joinOffset; + RemoteEndDetected = RemoteEndDetected + joinOffset; + AutoRouteOn = AutoRouteOn + joinOffset; + AutoRouteOff = AutoRouteOff + joinOffset; + PriorityRoutingOn = PriorityRoutingOn + joinOffset; + PriorityRoutingOff = PriorityRoutingOff + joinOffset; + InputOnScreenDisplayEnabled = InputOnScreenDisplayEnabled + joinOffset; + InputOnScreenDisplayDisabled = InputOnScreenDisplayDisabled + joinOffset; + SyncDetected = SyncDetected + joinOffset; + + VideoSource = VideoSource + joinOffset; + SourceCount = SourceCount + joinOffset; + + SourceNames = SourceNames + joinOffset; + } + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 795a4228..c89f4948 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -365,7 +365,10 @@ namespace PepperDash.Essentials Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt); var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, new DM.Config.DmpsRoutingPropertiesConfig()); + DeviceManager.AddDevice(dmpsRoutingController); + + } else { diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index bdc25538..65eda177 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -121,6 +121,7 @@ + @@ -128,6 +129,7 @@ + diff --git a/devjson commands.json b/devjson commands.json index 9d8ed35d..e7a8a884 100644 --- a/devjson commands.json +++ b/devjson commands.json @@ -38,4 +38,6 @@ devjson:2 {"deviceKey":"codec-comms-ssh", "methodName":"Connect", "params": []} devjson:1 {"deviceKey":"commBridge", "methodName":"ExecuteJoinAction", "params":[ 301, "digital", true ]} -devjson:2 {"deviceKey":"display01Comm-com", "methodName":"SendText", "params": [ "I'M GETTING TIRED OF THIS" ]} \ No newline at end of file +devjson:2 {"deviceKey":"display01Comm-com", "methodName":"SendText", "params": [ "I'M GETTING TIRED OF THIS" ]} + +devjson:10 {"deviceKey":"dmLink-ssh", "methodName":"Connect", "params": []} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs new file mode 100644 index 00000000..8856be01 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; + +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Cards; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +using PepperDash.Essentials.DM.Config; + +namespace PepperDash.Essentials.DM +{ + /// + /// Exposes the volume levels for Program, Aux1 or Aux2 outputs on a DMPS3 chassis + /// + public class DmpsAudioOutputController : Device + { + Card.Dmps3OutputBase OutputCard; + + public DmpsAudioOutput MasterVolumeLevel { get; private set; } + public DmpsAudioOutput SourceVolumeLevel { get; private set; } + public DmpsAudioOutput Codec1VolumeLevel { get; private set; } + public DmpsAudioOutput Codec2VolumeLevel { get; private set; } + + + public DmpsAudioOutputController(string key, string name, Card.Dmps3OutputBase card) + : base(key, name) + { + OutputCard = card; + + OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange); + + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + + if (card is Card.Dmps3ProgramOutput) + { + //(card as Card.Dmps3ProgramOutput).OutputMixer.MicLevel + //TODO: Hook up mic levels and mutes + Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); + Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); + } + else if (card is Card.Dmps3Aux1Output) + { + Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); + } + else if (card is Card.Dmps3Aux2Output) + { + Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); + } + } + + void BaseDevice_DMOutputChange(Switch device, DMOutputEventArgs args) + { + switch (args.EventId) + { + case DMOutputEventIds.MasterVolumeFeedBackEventId: + { + MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.MasterMuteOnFeedBackEventId: + { + MasterVolumeLevel.MuteFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.SourceLevelFeedBackEventId: + { + SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.Codec1LevelFeedBackEventId: + { + if(Codec1VolumeLevel != null) + Codec1VolumeLevel.VolumeLevelFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.Codec1MuteOnFeedBackEventId: + { + if (Codec1VolumeLevel != null) + Codec1VolumeLevel.MuteFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.Codec2LevelFeedBackEventId: + { + if (Codec2VolumeLevel != null) + Codec2VolumeLevel.VolumeLevelFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.Codec2MuteOnFeedBackEventId: + { + if (Codec2VolumeLevel != null) + Codec2VolumeLevel.MuteFeedback.FireUpdate(); + break; + } + } + } + } + + public class DmpsAudioOutput : IBasicVolumeWithFeedback + { + Card.Dmps3OutputBase Output; + + UShortInputSig Level; + + eDmpsLevelType Type; + + public BoolFeedback MuteFeedback { get; private set; } + public IntFeedback VolumeLevelFeedback { get; private set; } + + Action MuteOnAction; + Action MuteOffAction; + Action VolumeUpAction; + Action VolumeDownAction; + + public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) + { + Output = output; + + Type = type; + + switch (type) + { + case eDmpsLevelType.Master: + { + Level = output.MasterVolume; + + MuteFeedback = new BoolFeedback( new Func (() => Output.MasterMuteOnFeedBack.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => Output.MasterVolumeFeedBack.UShortValue)); + MuteOnAction = new Action(Output.MasterMuteOn); + MuteOffAction = new Action(Output.MasterMuteOff); + VolumeUpAction = new Action((b) => Output.MasterVolumeUp.BoolValue = b); + VolumeDownAction = new Action((b) => Output.MasterVolumeDown.BoolValue = b); + + + break; + } + case eDmpsLevelType.MicsMaster: + { + Level = output.MicMasterLevel; + + MuteFeedback = new BoolFeedback(new Func(() => Output.MicMasterMuteOnFeedBack.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => Output.MicMasterLevelFeedBack.UShortValue)); + MuteOnAction = new Action(Output.MicMasterMuteOn); + MuteOffAction = new Action(Output.MicMasterMuteOff); + VolumeUpAction = new Action((b) => Output.MicMasterLevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => Output.MicMasterLevelDown.BoolValue = b); + + break; + } + case eDmpsLevelType.Source: + { + Level = output.SourceLevel; + + MuteFeedback = new BoolFeedback(new Func(() => Output.SourceMuteOnFeedBack.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => Output.SourceLevelFeedBack.UShortValue)); + MuteOnAction = new Action(Output.SourceMuteOn); + MuteOffAction = new Action(Output.SourceMuteOff); + VolumeUpAction = new Action((b) => Output.SourceLevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => Output.SourceLevelDown.BoolValue = b); + break; + } + case eDmpsLevelType.Codec1: + { + var programOutput = output as Card.Dmps3ProgramOutput; + + if (programOutput != null) + { + Level = programOutput.Codec1Level; + + MuteFeedback = new BoolFeedback(new Func(() => programOutput.CodecMute1OnFeedback.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => programOutput.Codec1LevelFeedback.UShortValue)); + MuteOnAction = new Action(programOutput.Codec1MuteOn); + MuteOffAction = new Action(programOutput.Codec1MuteOff); + VolumeUpAction = new Action((b) => programOutput.Codec1LevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => programOutput.Codec1LevelDown.BoolValue = b); + + } + else + { + var auxOutput = output as Card.Dmps3Aux2Output; + + Level = auxOutput.Codec1Level; + + MuteFeedback = new BoolFeedback(new Func(() => auxOutput.CodecMute1OnFeedback.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => auxOutput.Codec1LevelFeedback.UShortValue)); + MuteOnAction = new Action(auxOutput.Codec1MuteOn); + MuteOffAction = new Action(auxOutput.Codec1MuteOff); + VolumeUpAction = new Action((b) => auxOutput.Codec1LevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => auxOutput.Codec1LevelDown.BoolValue = b); + } + break; + } + case eDmpsLevelType.Codec2: + { + var programOutput = output as Card.Dmps3ProgramOutput; + + if (programOutput != null) + { + Level = programOutput.Codec2Level; + + MuteFeedback = new BoolFeedback(new Func(() => programOutput.CodecMute1OnFeedback.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => programOutput.Codec2LevelFeedback.UShortValue)); + MuteOnAction = new Action(programOutput.Codec2MuteOn); + MuteOffAction = new Action(programOutput.Codec2MuteOff); + VolumeUpAction = new Action((b) => programOutput.Codec2LevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => programOutput.Codec2LevelDown.BoolValue = b); + + } + else + { + var auxOutput = output as Card.Dmps3Aux1Output; + + Level = auxOutput.Codec2Level; + + MuteFeedback = new BoolFeedback(new Func(() => auxOutput.CodecMute2OnFeedback.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => auxOutput.Codec2LevelFeedback.UShortValue)); + MuteOnAction = new Action(auxOutput.Codec2MuteOn); + MuteOffAction = new Action(auxOutput.Codec2MuteOff); + VolumeUpAction = new Action((b) => auxOutput.Codec2LevelUp.BoolValue = b); + VolumeDownAction = new Action((b) => auxOutput.Codec2LevelDown.BoolValue = b); + } + break; + } + } + + } + + #region IBasicVolumeWithFeedback Members + + public void SetVolume(ushort level) + { + Level.UShortValue = level; + } + + public void MuteOn() + { + MuteOnAction(); + } + + public void MuteOff() + { + MuteOffAction(); + } + + #endregion + + #region IBasicVolumeControls Members + + public void VolumeUp(bool pressRelease) + { + VolumeUpAction(pressRelease); + } + + public void VolumeDown(bool pressRelease) + { + VolumeDownAction(pressRelease); + } + + public void MuteToggle() + { + if (MuteFeedback.BoolValue) + MuteOff(); + else + MuteOn(); + } + + #endregion + } + + public enum eDmpsLevelType + { + Master, + Source, + MicsMaster, + Codec1, + Codec2, + Mic + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 350c11b5..8d83e7c1 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -309,6 +309,8 @@ namespace PepperDash.Essentials.DM { var airMediaInputCard = inputCard as Card.Dmps3AirMediaInput; + + AddInputPortWithDebug(number, string.Format("AirMediaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); } } @@ -370,14 +372,31 @@ namespace PepperDash.Essentials.DM else if (outputCard is Card.Dmps3ProgramOutput) { AddAudioOnlyOutputPort(number, "Program"); + + var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + + DeviceManager.AddDevice(programOutput); + return; } else if (outputCard is Card.Dmps3AuxOutput) { - if(outputCard.CardInputOutputType == eCardInputOutputType.Dmps3Aux1Output) + if (outputCard.CardInputOutputType == eCardInputOutputType.Dmps3Aux1Output) + { AddAudioOnlyOutputPort(number, "Aux1"); - else if(outputCard.CardInputOutputType == eCardInputOutputType.Dmps3Aux2Output) + + var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + + DeviceManager.AddDevice(aux1Output); + } + else if (outputCard.CardInputOutputType == eCardInputOutputType.Dmps3Aux2Output) + { AddAudioOnlyOutputPort(number, "Aux2"); + + var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + + DeviceManager.AddDevice(aux2Output); + } return; } else if (outputCard is Card.Dmps3CodecOutput) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs index f425843f..0eadd2a5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.AirMedia; using Crestron.SimplSharpPro.UI; @@ -68,7 +69,24 @@ namespace PepperDash.Essentials.DM return PepperDash.Essentials.DM.Chassis.HdMdNxM4kEController.GetController(key, name, type, props); } - + else if (typeName.Equals("hdmd400ce") || typeName.Equals("hdmd300ce") || typeName.Equals("hdmd200ce") || typeName.Equals("hdmd200c1ge")) + { + var props = JsonConvert.DeserializeObject + (properties.ToString()); + + if (typeName.Equals("hdmd400ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd400CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd300ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd300CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd200ce")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd200CE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + else if (typeName.Equals("hdmd200c1ge")) + return new PepperDash.Essentials.DM.HdMdxxxCEController(key, name, + new HdMd200C1GE(props.Control.IpIdInt, props.Control.TcpSshProperties.Address, Global.ControlSystem)); + } return null; } diff --git a/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs b/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs new file mode 100644 index 00000000..7a4c4900 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/DmLite/HdMdxxxCEController.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Receivers; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.DM +{ + /// + /// Represent both a transmitter and receiver pair of the HD-MD-400-C-E / HD-MD-300-C-E / HD-MD-200-C-E kits + /// + public class HdMdxxxCEController : CrestronGenericBaseDevice, IRouting//, IComPorts + { + /// + ///// DmLite Ports + ///// + //public RoutingOutputPort ToRx { get; private set; } + //public RoutingInputPort FromTx { get; private set; } + + public RoutingOutputPort HdmiOut { get; private set; } + + public HdMdxxxCE TxRxPair { get; private set; } + + public RoutingPortCollection InputPorts { get; private set; } + + /// + /// The value of the current video source for the HDMI output on the receiver + /// + public IntFeedback VideoSourceFeedback { get; private set; } + + /// + /// Indicates if Auto Route is on on the transmitter + /// + public BoolFeedback AutoRouteOnFeedback { get; private set; } + + /// + /// Indicates if Priority Routing is on on the transmitter + /// + public BoolFeedback PriorityRoutingOnFeedback { get; private set; } + + /// + /// INdicates if the On Screen Display is enabled + /// + public BoolFeedback InputOnScreenDisplayEnabledFeedback { get; private set; } + + /// + /// Indicates if video sync is detected on each of the inputs + /// + public Dictionary SyncDetectedFeedbacks { get; private set; } + + /// + /// Indicates if the remote end device is detected + /// + public BoolFeedback RemoteEndDetectedFeedback { get; private set; } + + public RoutingPortCollection OutputPorts + { + get { return new RoutingPortCollection { HdmiOut }; } + } + + public HdMdxxxCEController(string key, string name, HdMdxxxCE txRxPair) + :base(key, name, txRxPair) + { + + TxRxPair = txRxPair; + + RemoteEndDetectedFeedback = new BoolFeedback(() => TxRxPair.RemoteEndDetectedOnFeedback.BoolValue); + + AutoRouteOnFeedback = new BoolFeedback(() => TxRxPair.ReceiverAutoModeOnFeedback.BoolValue); + + PriorityRoutingOnFeedback = new BoolFeedback(() => TxRxPair.PriorityRoutingOnFeedback.BoolValue); + + InputOnScreenDisplayEnabledFeedback = new BoolFeedback(() => TxRxPair.OnScreenDisplayEnabledFeedback.BoolValue); + + InputPorts = new RoutingPortCollection(); + + SyncDetectedFeedbacks = new Dictionary(); + + // Add the HDMI input port on the receiver + InputPorts.Add(new RoutingInputPort(DmPortName.Hdmi, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 1, this)); + + SyncDetectedFeedbacks.Add(1, new BoolFeedback( () => TxRxPair.HdmiInputs[1].VideoDetectedFeedback.BoolValue)); + + if(txRxPair is HdMd400CE) + { + InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2, this)); + SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); + + InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 3, this)); + SyncDetectedFeedbacks.Add(3, new BoolFeedback(() => TxRxPair.HdmiInputs[3].VideoDetectedFeedback.BoolValue)); + + InputPorts.Add(new RoutingInputPort(DmPortName.VgaIn, eRoutingSignalType.Video | eRoutingSignalType.Audio, + eRoutingPortConnectionType.Vga, 4, this)); + SyncDetectedFeedbacks.Add(4, new BoolFeedback(() => TxRxPair.VgaInputs[1].VideoDetectedFeedback.BoolValue)); + + // Set Ports for CEC + InputPorts[DmPortName.HdmiIn1].Port = TxRxPair.HdmiInputs[1]; + InputPorts[DmPortName.HdmiIn2].Port = TxRxPair.HdmiInputs[2]; + } + else if (txRxPair is HdMd300CE) + { + InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2, this)); + SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); + + InputPorts.Add(new RoutingInputPort(DmPortName.VgaIn, eRoutingSignalType.Video | eRoutingSignalType.Audio, + eRoutingPortConnectionType.Vga, 3, this)); + SyncDetectedFeedbacks.Add(3, new BoolFeedback(() => TxRxPair.VgaInputs[1].VideoDetectedFeedback.BoolValue)); + + // Set Ports for CEC + InputPorts[DmPortName.HdmiIn].Port = TxRxPair.HdmiInputs[1]; + } + else if (txRxPair is HdMd200CE || txRxPair is HdMd200C1GE) + { + InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2, this)); + SyncDetectedFeedbacks.Add(2, new BoolFeedback(() => TxRxPair.HdmiInputs[2].VideoDetectedFeedback.BoolValue)); + + // Set Ports for CEC + InputPorts[DmPortName.HdmiIn].Port = TxRxPair.HdmiInputs[1]; + } + + //ToRx = new RoutingOutputPort(DmPortName.ToTx, eRoutingSignalType.Audio | eRoutingSignalType.Video, + // eRoutingPortConnectionType.DmCat, null, this); + + //FromTx = new RoutingInputPort(DmPortName.FromTx, eRoutingSignalType.Audio | eRoutingSignalType.Video, + // eRoutingPortConnectionType.DmCat, null, this); + + HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + OutputPorts[DmPortName.HdmiOut].Port = TxRxPair.HdmiOutputs[1]; + + TxRxPair.DMInputChange += new DMInputEventHandler(TxRxPair_DMInputChange); + TxRxPair.DMOutputChange += new DMOutputEventHandler(TxRxPair_DMOutputChange); + TxRxPair.DMSystemChange += new DMSystemEventHandler(TxRxPair_DMSystemChange); + + VideoSourceFeedback = new IntFeedback(() => (int)TxRxPair.HdmiOutputs[1].VideoOutFeedback.Number); + } + + void TxRxPair_DMSystemChange(Switch device, DMSystemEventArgs args) + { + if (args.EventId == DMSystemEventIds.RemoteEndDetectedEventId) + RemoteEndDetectedFeedback.FireUpdate(); + else if (args.EventId == DMSystemEventIds.ReceiverAutoModeOnEventId) + AutoRouteOnFeedback.FireUpdate(); + else if (args.EventId == DMSystemEventIds.PriorityRoutingOnEventId) + PriorityRoutingOnFeedback.FireUpdate(); + else if (args.EventId == DMSystemEventIds.OnScreenDisplayEnabledEventId) + InputOnScreenDisplayEnabledFeedback.FireUpdate(); + } + + void TxRxPair_DMOutputChange(Switch device, DMOutputEventArgs args) + { + if (args.EventId == DMOutputEventIds.VideoOutEventId) + VideoSourceFeedback.FireUpdate(); + } + + void TxRxPair_DMInputChange(Switch device, DMInputEventArgs args) + { + if (args.EventId == DMInputEventIds.VideoDetectedEventId) + SyncDetectedFeedbacks[args.Number].FireUpdate(); + } + + public void AutoRouteOn() + { + TxRxPair.TransmitterAutoModeOn(); + } + + public void AutoRouteOff() + { + TxRxPair.TransmitterAutoModeOff(); + } + + public void PriorityRouteOn() + { + TxRxPair.PriorityRoutingOn(); + } + + public void PriorityRouteOff() + { + TxRxPair.PriorityRoutingOff(); + } + + public void OnScreenDisplayEnable() + { + TxRxPair.OnScreenDisplayEnabled(); + } + + public void OnScreenDisplayDisable() + { + TxRxPair.OnScreenDisplayDisabled(); + } + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + var number = Convert.ToUInt32(inputSelector); // Cast can sometimes fail + + var input = number == 0 ? null : TxRxPair.Inputs[number]; + + TxRxPair.HdmiOutputs[1].VideoOut = input; + } + + // This device has a different class for com ports which will make it hard to implement IComPorts.... + + //#region IComPorts Members + //public CrestronCollection ComPorts { get { return TxRxPair.ComPorts as CrestronCollection; } } + //public int NumberOfComPorts { get { return 1; } } + //#endregion + } + + public class HdMdxxxCEPropertiesConfig + { + public ControlPropertiesConfig Control { get; set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/DmPortName.cs b/essentials-framework/Essentials DM/Essentials_DM/DmPortName.cs index 2c65b3f8..4ce4d34d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/DmPortName.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/DmPortName.cs @@ -26,6 +26,8 @@ namespace PepperDash.Essentials.DM public const string DmOut = "DmOut"; public const string DmOut1 = "DmOut1"; public const string DmOut2 = "DmOut2"; + public const string FromTx = "FromTx"; + public const string Hdmi = "Hdmi"; public const string HdmiIn = "HdmiIn"; public const string HdmiIn1 = "HdmiIn1"; public const string HdmiIn2 = "HdmiIn2"; @@ -35,6 +37,7 @@ namespace PepperDash.Essentials.DM public const string HdmiOut = "HdmiOut"; public const string Osd = "Osd"; public const string SpdifIn = "SpdifIn"; + public const string ToTx = "ToTx"; public const string VgaIn = "VgaIn"; } } \ 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 16be9593..8df92ef1 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs @@ -112,6 +112,8 @@ namespace PepperDash.Essentials.DM { if (typeName.StartsWith("dmrmc100c")) return new DmRmcX100CController(key, name, new DmRmc100C(ipid, Global.ControlSystem)); + if (typeName.StartsWith("dmrmc100s")) + return new DmRmc100SController(key, name, new DmRmc100S(ipid, Global.ControlSystem)); if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(ipid, Global.ControlSystem)); if (typeName.StartsWith("dmrmc4kz100c")) @@ -182,6 +184,8 @@ namespace PepperDash.Essentials.DM return new DmRmc4k100C1GController(key, name, new DmRmc4K100C1G(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc100c")) return new DmRmcX100CController(key, name, new DmRmc100C(chassis.Outputs[num])); + if (typeName.StartsWith("dmrmc100s")) + return new DmRmc100SController(key, name, new DmRmc100S(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4kz100c")) @@ -213,6 +217,8 @@ namespace PepperDash.Essentials.DM return new DmRmc4k100C1GController(key, name, new DmRmc4K100C1G(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc100c")) return new DmRmcX100CController(key, name, new DmRmc100C(ipid, chassis.Outputs[num])); + if (typeName.StartsWith("dmrmc100s")) + return new DmRmc100SController(key, name, new DmRmc100S(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4k100c")) return new DmRmcX100CController(key, name, new DmRmc4k100C(ipid, chassis.Outputs[num])); if (typeName.StartsWith("dmrmc4kz100c")) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj index f266c842..68aa1e17 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj @@ -97,6 +97,7 @@ + @@ -112,6 +113,7 @@ +