From e22c71853f7ebc6f1ddc4e405b47058f6fdcba31 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 2 Dec 2020 13:10:47 -0500 Subject: [PATCH 001/480] Starts adding support for starting and stopping dm stream cards via API bridge --- .../JoinMaps/DmChassisControllerJoinMap.cs | 12 + .../JoinMaps/DmChassisControllerJoinMap.cs | 8 + .../Chassis/DmChassisController.cs | 220 +++++++++++++++++- 3 files changed, 231 insertions(+), 9 deletions(-) diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index 2e1b8394..ba00306d 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -70,6 +70,14 @@ namespace PepperDash.Essentials.Bridges /// Range reports the highest supported HDCP state level for the corresponding input card /// public uint HdcpSupportCapability { get; set; } + /// + /// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback + /// + public uint InputStreamCardStatus { get; set; } + /// + /// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback + /// + public uint OutputStreamCardStatus { get; set; } #endregion #region Serials @@ -115,6 +123,8 @@ namespace PepperDash.Essentials.Bridges InputUsb = 700; //701-899 HdcpSupportState = 1000; //1001-1199 HdcpSupportCapability = 1200; //1201-1399 + InputStreamCardStatus = 1500; //1501-1532 + OutputStreamCardStatus = 1600; //1601-1632 //Serial @@ -145,6 +155,8 @@ namespace PepperDash.Essentials.Bridges OutputEndpointOnline = OutputEndpointOnline + joinOffset; HdcpSupportState = HdcpSupportState + joinOffset; HdcpSupportCapability = HdcpSupportCapability + joinOffset; + InputStreamCardStatus = InputStreamCardStatus + joinOffset; + OutputStreamCardStatus = OutputStreamCardStatus + joinOffset; OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset; TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index 54909d02..ee04bd45 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -76,6 +76,14 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 1201, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Input HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("InputStreamCardState")] + public JoinDataComplete InputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1501, JoinSpan = 32 }, + new JoinMetadata { Description = "DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("OutputStreamCardState")] + public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 }, + new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("InputNames")] public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 09c7988a..db4e517f 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -49,7 +49,9 @@ namespace PepperDash.Essentials.DM public BoolFeedback EnableAudioBreakawayFeedback { get; private set; } public BoolFeedback EnableUsbBreakawayFeedback { get; private set; } - public Dictionary InputCardHdcpStateFeedbacks { get; private set; } + public Dictionary InputCardHdcpStateFeedbacks { get; private set; } + public Dictionary InputStreamCardStateFeedbacks { get; private set; } + public Dictionary OutputStreamCardStateFeedbacks { get; private set; } public Dictionary InputCardHdcpCapabilityTypes { get; private set; } @@ -223,7 +225,9 @@ namespace PepperDash.Essentials.DM EnableUsbBreakawayFeedback = new BoolFeedback(() => (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); - InputCardHdcpStateFeedbacks = new Dictionary(); + InputCardHdcpStateFeedbacks = new Dictionary(); + InputStreamCardStateFeedbacks = new Dictionary(); + OutputStreamCardStateFeedbacks = new Dictionary(); InputCardHdcpCapabilityTypes = new Dictionary(); for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) @@ -307,6 +311,33 @@ namespace PepperDash.Essentials.DM // return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; return false; + }); + OutputStreamCardStateFeedbacks[tempX] = new IntFeedback(() => + { + try + { + var outputCard = Chassis.Outputs[tempX]; + + if (outputCard.Card is DmcStroAV) + { + Debug.Console(0, "Found output stream card in slot: {0}.", tempX); + var streamCard = outputCard.Card as DmcStroAV; + if (streamCard.Control.StartFeedback.BoolValue == true) + return 1; + else if (streamCard.Control.StopFeedback.BoolValue == true) + return 2; + else if (streamCard.Control.PauseFeedback.BoolValue == true) + return 3; + else + return 0; + } + return 0; + } + catch (InvalidOperationException iopex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding output stream card in slot: {0}. Error: {1}", tempX, iopex); + return 0; + } }); } @@ -406,6 +437,33 @@ namespace PepperDash.Essentials.DM Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "The Input Card in slot: {0} supports HDCP 2. Please update the configuration value in the inputCardSupportsHdcp2 object to true. Error: {1}", tempX, iopex); return 0; } + }); + InputStreamCardStateFeedbacks[tempX] = new IntFeedback(() => + { + try + { + var inputCard = Chassis.Inputs[tempX]; + + if (inputCard.Card is DmcStr) + { + Debug.Console(0, "Found input stream card in slot: {0}.", tempX); + var streamCard = inputCard.Card as DmcStr; + if (streamCard.Control.StartFeedback.BoolValue == true) + return 1; + else if (streamCard.Control.StopFeedback.BoolValue == true) + return 2; + else if (streamCard.Control.PauseFeedback.BoolValue == true) + return 3; + else + return 0; + } + return 0; + } + catch (InvalidOperationException iopex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding input stream card in slot: {0}. Error: {1}", tempX, iopex); + return 0; + } }); } } @@ -915,6 +973,42 @@ namespace PepperDash.Essentials.DM else Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); break; + } + case DMInputEventIds.StartEventId: + case DMInputEventIds.StopEventId: + case DMInputEventIds.PauseEventId: + { + Debug.Console(2, this, "DM Input {0} Stream Status EventId", args.Number); + if (InputStreamCardStateFeedbacks[args.Number] != null) + { + var streamCard = Chassis.Inputs[args.Number].Card as DmcStr; + InputStreamCardStateFeedbacks[args.Number] = new IntFeedback(() => { + if (streamCard.Control.StartFeedback.BoolValue == true) + { + Debug.Console(1, this, "Found start feedback"); + return 1; + } + else if (streamCard.Control.StopFeedback.BoolValue == true) + { + Debug.Console(1, this, "Found stop feedback"); + return 2; + } + else if (streamCard.Control.PauseFeedback.BoolValue == true) + { + Debug.Console(1, this, "Found pause feedback"); + return 3; + } + else + { + Debug.Console(1, this, "Found no feedback"); + return 0; + } + }); + InputStreamCardStateFeedbacks[args.Number].FireUpdate(); + } + else + Debug.Console(1, this, "No index of {0} found in InputStreamCardStateFeedbacks"); + break; } default: { @@ -1043,6 +1137,31 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); break; + } + case DMOutputEventIds.StartEventId: + case DMOutputEventIds.StopEventId: + case DMOutputEventIds.PauseEventId: + { + Debug.Console(2, this, "DM Output {0} Stream Status EventId", args.Number); + if (OutputStreamCardStateFeedbacks[args.Number] != null) + { + var streamCard = Chassis.Outputs[args.Number].Card as DmcStroAV; + OutputStreamCardStateFeedbacks[args.Number] = new IntFeedback(() => + { + if (streamCard.Control.StartFeedback.BoolValue == true) + return 1; + else if (streamCard.Control.StopFeedback.BoolValue == true) + return 2; + else if (streamCard.Control.PauseFeedback.BoolValue == true) + return 3; + else + return 0; + }); + OutputStreamCardStateFeedbacks[args.Number].FireUpdate(); + } + else + Debug.Console(1, this, "No index of {0} found in OutputStreamCardStateFeedbacks"); + break; } default: { @@ -1242,13 +1361,16 @@ namespace PepperDash.Essentials.DM } else { - LinkHdmiInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); - } - - if (RxDictionary.ContainsKey(ioSlot)) - { - LinkRxToApi(trilist, ioSlot, joinMap, ioSlotJoin); - } + LinkHdmiInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); + LinkStreamInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); + } + + if (RxDictionary.ContainsKey(ioSlot)) + { + LinkRxToApi(trilist, ioSlot, joinMap, ioSlotJoin); + } + else + LinkStreamOutputToApi(trilist, ioSlot, joinMap, ioSlotJoin); } } @@ -1295,6 +1417,86 @@ namespace PepperDash.Essentials.DM { trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; } + } + + private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) + { + var inputPort = InputPorts[string.Format("inputCard{0}--streamIn", ioSlot)]; + if (inputPort == null) + { + return; + } + var streamCard = Chassis.Inputs[ioSlot].Card as DmcStr; + var join = joinMap.InputStreamCardState.JoinNumber + ioSlotJoin; + + Debug.Console(1, "Port value for input card {0} is set as a stream card", ioSlot); + + trilist.SetUShortSigAction(join, s => + { + if (s == 1) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to start", join, s); + streamCard.Control.Start(); + } + else if (s == 2) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to stop", join, s); + streamCard.Control.Stop(); + } + else if (s == 3) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to pause", join, s); + streamCard.Control.Pause(); + } + else + { + Debug.Console(2, this, "Join {0} value {1}: Ignore stream state", join, s); + } + }); + + InputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]); + + trilist.UShortInput[join].UShortValue = InputStreamCardStateFeedbacks[ioSlot].UShortValue; + } + + private void LinkStreamOutputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) + { + var outputPort = OutputPorts[string.Format("outputCard{0}--streamOut", ioSlot)]; + if (outputPort == null) + { + return; + } + var streamCard = Chassis.Outputs[ioSlot].Card as DmcStroAV; + var join = joinMap.OutputStreamCardState.JoinNumber + ioSlotJoin; + + Debug.Console(1, "Port value for output card {0} is set as a stream card", ioSlot); + + trilist.SetUShortSigAction(join, s => + { + if (s == 1) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to start", join, s); + streamCard.Control.Start(); + } + else if (s == 2) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to stop", join, s); + streamCard.Control.Stop(); + } + else if (s == 3) + { + Debug.Console(2, this, "Join {0} value {1}: Setting stream state to pause", join, s); + streamCard.Control.Pause(); + } + else + { + Debug.Console(2, this, "Join {0} value {1}: Ignore stream state", join, s); + } + }); + + OutputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]); + + trilist.UShortInput[join].UShortValue = OutputStreamCardStateFeedbacks[ioSlot].UShortValue; } private void LinkRxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) From ab5dd5f7569eb6a4464df1ce587bd89577ae79ba Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 2 Dec 2020 13:51:44 -0500 Subject: [PATCH 002/480] Fixes streaming card feedback and removes excess debug --- .../Chassis/DmChassisController.cs | 43 ++----------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index db4e517f..3c5567c4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -320,7 +320,7 @@ namespace PepperDash.Essentials.DM if (outputCard.Card is DmcStroAV) { - Debug.Console(0, "Found output stream card in slot: {0}.", tempX); + Debug.Console(2, "Found output stream card in slot: {0}.", tempX); var streamCard = outputCard.Card as DmcStroAV; if (streamCard.Control.StartFeedback.BoolValue == true) return 1; @@ -446,7 +446,7 @@ namespace PepperDash.Essentials.DM if (inputCard.Card is DmcStr) { - Debug.Console(0, "Found input stream card in slot: {0}.", tempX); + Debug.Console(2, "Found input stream card in slot: {0}.", tempX); var streamCard = inputCard.Card as DmcStr; if (streamCard.Control.StartFeedback.BoolValue == true) return 1; @@ -981,33 +981,10 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "DM Input {0} Stream Status EventId", args.Number); if (InputStreamCardStateFeedbacks[args.Number] != null) { - var streamCard = Chassis.Inputs[args.Number].Card as DmcStr; - InputStreamCardStateFeedbacks[args.Number] = new IntFeedback(() => { - if (streamCard.Control.StartFeedback.BoolValue == true) - { - Debug.Console(1, this, "Found start feedback"); - return 1; - } - else if (streamCard.Control.StopFeedback.BoolValue == true) - { - Debug.Console(1, this, "Found stop feedback"); - return 2; - } - else if (streamCard.Control.PauseFeedback.BoolValue == true) - { - Debug.Console(1, this, "Found pause feedback"); - return 3; - } - else - { - Debug.Console(1, this, "Found no feedback"); - return 0; - } - }); InputStreamCardStateFeedbacks[args.Number].FireUpdate(); } else - Debug.Console(1, this, "No index of {0} found in InputStreamCardStateFeedbacks"); + Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks"); break; } default: @@ -1145,22 +1122,10 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "DM Output {0} Stream Status EventId", args.Number); if (OutputStreamCardStateFeedbacks[args.Number] != null) { - var streamCard = Chassis.Outputs[args.Number].Card as DmcStroAV; - OutputStreamCardStateFeedbacks[args.Number] = new IntFeedback(() => - { - if (streamCard.Control.StartFeedback.BoolValue == true) - return 1; - else if (streamCard.Control.StopFeedback.BoolValue == true) - return 2; - else if (streamCard.Control.PauseFeedback.BoolValue == true) - return 3; - else - return 0; - }); OutputStreamCardStateFeedbacks[args.Number].FireUpdate(); } else - Debug.Console(1, this, "No index of {0} found in OutputStreamCardStateFeedbacks"); + Debug.Console(2, this, "No index of {0} found in OutputStreamCardStateFeedbacks"); break; } default: From f9925f9ec9d9c9de3666a59a55419ec8e0a67872 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 3 Dec 2020 16:46:10 -0700 Subject: [PATCH 003/480] Add PowerIsOnFeedback back to DisplayBase and marked it as Obsolete --- .../PepperDashEssentialsBase/Display/BasicIrDisplay.cs | 3 ++- .../PepperDashEssentialsBase/Display/DisplayBase.cs | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs index 8d70bd55..3c691c19 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/BasicIrDisplay.cs @@ -20,7 +20,8 @@ namespace PepperDash.Essentials.Core public IrOutputPortController IrPort { get; private set; } public ushort IrPulseTime { get; set; } - public BoolFeedback PowerIsOnFeedback { get; private set; } + [Obsolete("This property will be removed in version 2.0.0")] + public override BoolFeedback PowerIsOnFeedback { get; protected set; } protected Func PowerIsOnFeedbackFunc { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs index e4a2cb26..4e461c1c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs @@ -18,7 +18,7 @@ namespace PepperDash.Essentials.Core /// /// /// - public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking + public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower { public event SourceInfoChangeHandler CurrentSourceChange; @@ -49,6 +49,9 @@ namespace PepperDash.Essentials.Core public BoolFeedback IsCoolingDownFeedback { get; protected set; } public BoolFeedback IsWarmingUpFeedback { get; private set; } + [Obsolete("This property will be removed in version 2.0.0")] + public abstract BoolFeedback PowerIsOnFeedback { get; protected set; } + public UsageTracking UsageTracker { get; set; } public uint WarmupTime { get; set; } @@ -261,7 +264,8 @@ namespace PepperDash.Essentials.Core abstract protected Func CurrentInputFeedbackFunc { get; } - public BoolFeedback PowerIsOnFeedback { get; protected set; } + public override BoolFeedback PowerIsOnFeedback { get; protected set; } + abstract protected Func PowerIsOnFeedbackFunc { get; } From 0e4edca08a31c558428599ef51e93eda4f6407ee Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 11:05:46 -0700 Subject: [PATCH 004/480] update plugin dependency check message --- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index f7275a66..3e8cbc38 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -402,13 +402,16 @@ namespace PepperDash.Essentials /// Loads a /// /// + /// static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly) { var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion); if (!passed) { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion); + Debug.Console(0, Debug.ErrorLogLevel.Error, + "**********/r/nPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}/r/n**********", + plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name); return; } else From 93a5f2e3b2831f7ca1c65eaafc69e2e8a30a8271 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 12:18:08 -0700 Subject: [PATCH 005/480] fix slases --- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index 3e8cbc38..f0a7aeeb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -410,7 +410,7 @@ namespace PepperDash.Essentials if (!passed) { Debug.Console(0, Debug.ErrorLogLevel.Error, - "**********/r/nPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}/r/n**********", + "**********\r\nPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n**********", plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name); return; } From 008a052045003b2667063fba0a6e1973c763bb45 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 1 Dec 2020 16:20:59 -0700 Subject: [PATCH 006/480] getting started with EssentialsTechRoom --- .../Room/Config/EssentialsRoomConfig.cs | 35 +- .../Room/Config/EssentialsTechRoomConfig.cs | 20 ++ .../Room/Types/EssentialsTechRoom.cs | 94 ++++++ .../Presets/DevicePresets.cs | 305 ++++++++++-------- 4 files changed, 291 insertions(+), 163 deletions(-) create mode 100644 PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs create mode 100644 PepperDashEssentials/Room/Types/EssentialsTechRoom.cs diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index dfaa333d..3aee1e20 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config public static Device GetRoomObject(DeviceConfig roomConfig) { var typeName = roomConfig.Type.ToLower(); + if (typeName == "huddle") { - var huddle = new EssentialsHuddleSpaceRoom(roomConfig); - - return huddle; + return new EssentialsHuddleSpaceRoom(roomConfig); } - else if (typeName == "huddlevtc1") - { - var rm = new EssentialsHuddleVtc1Room(roomConfig); - - return rm; - } - else if (typeName == "ddvc01Bridge") - { - return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing. - } - else if (typeName == "dualdisplay") - { - var rm = new EssentialsDualDisplayRoom(roomConfig); + if (typeName == "huddlevtc1") + { + return new EssentialsHuddleVtc1Room(roomConfig); + } + if (typeName == "ddvc01Bridge") + { + return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing. + } + if (typeName == "dualdisplay") + { + return new EssentialsDualDisplayRoom(roomConfig); + } - return rm; - } - - return null; + return typeName != "techRoom" ? null : new EssentialsTechRoom(roomConfig); } /// diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs new file mode 100644 index 00000000..8f35461b --- /dev/null +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace PepperDash.Essentials.Room.Config +{ + public class EssentialsTechRoomConfig + { + public List Displays; + public List Tuners; + public string ScheduleProviderKey; + public string UserPin; + public string TechPin; + public string PresetsFileName; + + public EssentialsTechRoomConfig() + { + Displays = new List(); + Tuners = new List(); + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs new file mode 100644 index 00000000..ba87df5d --- /dev/null +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Presets; +using PepperDash.Essentials.Devices.Common; +using PepperDash.Essentials.Room.Config; + +namespace PepperDash.Essentials +{ + public class EssentialsTechRoom:EssentialsRoomBase + { + private Dictionary _tuners; + private Dictionary _displays; + + private DevicePresetsModel _tunerPresets; + + private readonly EssentialsTechRoomConfig _config; + + + public EssentialsTechRoom(DeviceConfig config) : base(config) + { + _config = config.Properties.ToObject(); + + _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName); + + _tuners = GetDevices(_config.Tuners); + _displays = GetDevices(_config.Displays); + } + + private Dictionary GetDevices(ICollection config) where T:IKeyed + { + try + { + var returnValue = DeviceManager.AllDevices.OfType() + .Where(d => config.Contains(d.Key)) + .ToDictionary(d => d.Key, d => d); + + return returnValue; + } + catch + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error getting devices. Check Essentials Configuration"); + return null; + } + } + + #region Overrides of EssentialsRoomBase + + protected override Func IsWarmingFeedbackFunc + { + get { throw new NotImplementedException(); } + } + + protected override Func IsCoolingFeedbackFunc + { + get { throw new NotImplementedException(); } + } + + protected override Func OnFeedbackFunc + { + get { throw new NotImplementedException(); } + } + + protected override void EndShutdown() + { + throw new NotImplementedException(); + } + + public override void SetDefaultLevels() + { + throw new NotImplementedException(); + } + + public override void PowerOnToDefaultOrLastSource() + { + throw new NotImplementedException(); + } + + public override bool RunDefaultPresentRoute() + { + throw new NotImplementedException(); + } + + public override void RoomVacatedForTimeoutPeriod(object o) + { + throw new NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 4f79626f..f0378691 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -1,178 +1,197 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; - using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - using PepperDash.Core; //using SSMono.IO; namespace PepperDash.Essentials.Core.Presets { - /// - /// Class that represents the model behind presets display - /// - public class DevicePresetsModel : Device - { - public event EventHandler PresetsLoaded; + /// + /// Class that represents the model behind presets display + /// + public class DevicePresetsModel : Device + { + private readonly bool _initSuccess; - public int PulseTime { get; set; } - public int DigitSpacingMS { get; set; } - public bool PresetsAreLoaded { get; private set; } + /// + /// The methods on the STB device to call when dialing + /// + private Dictionary> _dialFunctions; - public List PresetsList { get { return _PresetsList.ToList(); } } - List _PresetsList; - public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } } + private bool _dialIsRunning; + private Action _enterFunction; + private string _filePath; - public bool UseLocalImageStorage { get; set; } - public string ImagesLocalHostPrefix { get; set; } - public string ImagesPathPrefix { get; set; } - public string ListPathPrefix { get; set; } + public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName) + : this(key, fileName) + { + try + { + // Grab the digit functions from the device + // If any fail, the whole thing fails peacefully + _dialFunctions = new Dictionary>(10) + { + {'1', setTopBox.Digit1}, + {'2', setTopBox.Digit2}, + {'3', setTopBox.Digit3}, + {'4', setTopBox.Digit4}, + {'5', setTopBox.Digit5}, + {'6', setTopBox.Digit6}, + {'7', setTopBox.Digit7}, + {'8', setTopBox.Digit8}, + {'9', setTopBox.Digit9}, + {'0', setTopBox.Digit0}, + {'-', setTopBox.Dash} + }; + } + catch + { + Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key); + _dialFunctions = null; + return; + } - /// - /// The methods on the STB device to call when dialing - /// - Dictionary> DialFunctions; - Action EnterFunction; + _enterFunction = setTopBox.KeypadEnter; + } - bool DialIsRunning; - string FilePath; - bool InitSuccess; - //SSMono.IO.FileSystemWatcher ListWatcher; + public DevicePresetsModel(string key, string fileName) : base(key) + { + PulseTime = 150; + DigitSpacingMs = 150; - public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName) - : base(key) - { - PulseTime = 150; - DigitSpacingMS = 150; + UseLocalImageStorage = true; - try - { - // Grab the digit functions from the device - // If any fail, the whole thing fails peacefully - DialFunctions = new Dictionary>(10) - { - { '1', setTopBox.Digit1 }, - { '2', setTopBox.Digit2 }, - { '3', setTopBox.Digit3 }, - { '4', setTopBox.Digit4 }, - { '5', setTopBox.Digit5 }, - { '6', setTopBox.Digit6 }, - { '7', setTopBox.Digit7 }, - { '8', setTopBox.Digit8 }, - { '9', setTopBox.Digit9 }, - { '0', setTopBox.Digit0 }, - { '-', setTopBox.Dash } - }; - } - catch - { - Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key); - DialFunctions = null; - return; - } + ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0); + ImagesPathPrefix = @"/presets/images.zip/"; + ListPathPrefix = @"/html/presets/lists/"; - EnterFunction = setTopBox.KeypadEnter; + SetFileName(fileName); - UseLocalImageStorage = true; + _initSuccess = true; + } - ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0); - ImagesPathPrefix = @"/presets/images.zip/"; - ListPathPrefix = @"/html/presets/lists/"; + public int PulseTime { get; set; } + public int DigitSpacingMs { get; set; } + public bool PresetsAreLoaded { get; private set; } - SetFileName(fileName); + public List PresetsList { get; private set; } - //ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists"); - //ListWatcher.NotifyFilter = NotifyFilters.LastWrite; - //ListWatcher.EnableRaisingEvents = true; - //ListWatcher.Changed += ListWatcher_Changed; - InitSuccess = true; - } + public int Count + { + get { return PresetsList != null ? PresetsList.Count : 0; } + } + + public bool UseLocalImageStorage { get; set; } + public string ImagesLocalHostPrefix { get; set; } + public string ImagesPathPrefix { get; set; } + public string ListPathPrefix { get; set; } + public event EventHandler PresetsLoaded; - public void SetFileName(string path) - { - FilePath = ListPathPrefix + path; - LoadChannels(); - } + public void SetFileName(string path) + { + _filePath = ListPathPrefix + path; + LoadChannels(); + } - public void LoadChannels() - { - PresetsAreLoaded = false; - try - { - var pl = JsonConvert.DeserializeObject(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII)); - Name = pl.Name; - _PresetsList = pl.Channels; - } - catch (Exception e) - { - Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message); - // Just save a default empty list - _PresetsList = new List(); - } - PresetsAreLoaded = true; + public void LoadChannels() + { + PresetsAreLoaded = false; + try + { + var pl = JsonConvert.DeserializeObject(File.ReadToEnd(_filePath, Encoding.ASCII)); + Name = pl.Name; + PresetsList = pl.Channels; + } + catch (Exception e) + { + Debug.Console(2, this, + "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", + _filePath, e.Message); + // Just save a default empty list + PresetsList = new List(); + } + PresetsAreLoaded = true; - var handler = PresetsLoaded; - if (handler != null) - handler(this, EventArgs.Empty); - } + var handler = PresetsLoaded; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + } - public void Dial(int presetNum) - { - if (presetNum <= _PresetsList.Count) - Dial(_PresetsList[presetNum - 1].Channel); - } + public void Dial(int presetNum) + { + if (presetNum <= PresetsList.Count) + { + Dial(PresetsList[presetNum - 1].Channel); + } + } - public void Dial(string chanNum) - { - if (DialIsRunning || !InitSuccess) return; - if (DialFunctions == null) - { - Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key); - return; - } + public void Dial(string chanNum) + { + if (_dialIsRunning || !_initSuccess) + { + return; + } + if (_dialFunctions == null) + { + Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key); + return; + } - DialIsRunning = true; - CrestronInvoke.BeginInvoke(o => - { - foreach (var c in chanNum.ToCharArray()) - { - if (DialFunctions.ContainsKey(c)) - Pulse(DialFunctions[c]); - CrestronEnvironment.Sleep(DigitSpacingMS); - } + _dialIsRunning = true; + CrestronInvoke.BeginInvoke(o => + { + foreach (var c in chanNum.ToCharArray()) + { + if (_dialFunctions.ContainsKey(c)) + { + Pulse(_dialFunctions[c]); + } + CrestronEnvironment.Sleep(DigitSpacingMs); + } - if (EnterFunction != null) - Pulse(EnterFunction); - DialIsRunning = false; - }); - } + if (_enterFunction != null) + { + Pulse(_enterFunction); + } + _dialIsRunning = false; + }); + } - void Pulse(Action act) - { - act(true); - CrestronEnvironment.Sleep(PulseTime); - act(false); - } + public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox) + { + _dialFunctions = new Dictionary>(10) + { + {'1', setTopBox.Digit1}, + {'2', setTopBox.Digit2}, + {'3', setTopBox.Digit3}, + {'4', setTopBox.Digit4}, + {'5', setTopBox.Digit5}, + {'6', setTopBox.Digit6}, + {'7', setTopBox.Digit7}, + {'8', setTopBox.Digit8}, + {'9', setTopBox.Digit9}, + {'0', setTopBox.Digit0}, + {'-', setTopBox.Dash} + }; - /// - /// Event handler for filesystem watcher. When directory changes, this is called - /// - //void ListWatcher_Changed(object sender, FileSystemEventArgs e) - //{ - // Debug.Console(1, this, "folder modified: {0}", e.FullPath); - // if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase)) - // { - // Debug.Console(1, this, "File changed: {0}", e.ChangeType); - // LoadChannels(); - // } - //} - } + _enterFunction = setTopBox.KeypadEnter; + + Dial(chanNum); + } + + private void Pulse(Action act) + { + act(true); + CrestronEnvironment.Sleep(PulseTime); + act(false); + } + } } \ No newline at end of file From 7a8c1f31656e035d75c3449bef88d3530e82a98d Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 2 Dec 2020 13:37:53 -0700 Subject: [PATCH 007/480] adding some overloads --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 ++ .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index ba87df5d..079a2ff6 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -26,6 +26,8 @@ namespace PepperDash.Essentials _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName); + _tunerPresets.LoadChannels(); + _tuners = GetDevices(_config.Tuners); _displays = GetDevices(_config.Displays); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index f0378691..43fdf59a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -165,6 +165,14 @@ namespace PepperDash.Essentials.Core.Presets }); } + public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox) + { + if (presetNum <= PresetsList.Count) + { + Dial(PresetsList[presetNum - 1].Channel, setTopBox); + } + } + public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox) { _dialFunctions = new Dictionary>(10) From 9171610e343ab072bc553d00b5049081f78e2e50 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 3 Dec 2020 13:26:55 -0700 Subject: [PATCH 008/480] getting files back in the project --- PepperDashEssentials/PepperDashEssentials.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 42d0e288..969c1f40 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -141,11 +141,13 @@ + + From 9888fbf047b6a2672895de256d2c13b892754553 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 13:24:00 -0700 Subject: [PATCH 009/480] added save presets method & expose some properties --- .../Room/Types/EssentialsTechRoom.cs | 60 +++++++++++++++++-- .../Presets/DevicePresets.cs | 22 +++++++ 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 079a2ff6..0680f46b 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -12,13 +12,37 @@ namespace PepperDash.Essentials { public class EssentialsTechRoom:EssentialsRoomBase { - private Dictionary _tuners; - private Dictionary _displays; + private readonly Dictionary _tuners; + private readonly Dictionary _displays; - private DevicePresetsModel _tunerPresets; + private readonly DevicePresetsModel _tunerPresets; private readonly EssentialsTechRoomConfig _config; + public DevicePresetsModel TunerPresets + { + get + { + return _tunerPresets; + } + } + + public Dictionary Tuners + { + get { return _tuners; } + } + + public Dictionary Displays + { + get { return _displays; } + } + + public BoolFeedback RoomPowerIsOnFeedback { get; private set; } + + public bool RoomPowerIsOn + { + get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); } + } public EssentialsTechRoom(DeviceConfig config) : base(config) { @@ -30,6 +54,32 @@ namespace PepperDash.Essentials _tuners = GetDevices(_config.Tuners); _displays = GetDevices(_config.Displays); + + RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn); + } + + private void SubscribeToDisplayFeedbacks() + { + foreach (var display in _displays) + { + display.Value.PowerIsOnFeedback.OutputChange += (sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate(); + } + } + + public void RoomPowerOn() + { + foreach (var display in _displays) + { + display.Value.PowerOn(); + } + } + + public void RoomPowerOff() + { + foreach (var display in _displays) + { + display.Value.PowerOff(); + } } private Dictionary GetDevices(ICollection config) where T:IKeyed @@ -47,7 +97,9 @@ namespace PepperDash.Essentials Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error getting devices. Check Essentials Configuration"); return null; } - } + } + + #region Overrides of EssentialsRoomBase diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 43fdf59a..ccce6ea7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -195,6 +195,28 @@ namespace PepperDash.Essentials.Core.Presets Dial(chanNum); } + public void UpdatePreset(int index, PresetChannel preset) + { + if (index >= PresetsList.Count) + { + return; + } + + PresetsList[index] = preset; + + SavePresets(); + } + + private void SavePresets() + { + var json = JsonConvert.SerializeObject(PresetsList); + + using (var file = File.Open(_filePath, FileMode.Truncate)) + { + file.Write(json, Encoding.UTF8); + } + } + private void Pulse(Action act) { act(true); From f11bdcfd539f9300fc6ebdd3c20f6e8170014689 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 16:21:48 -0700 Subject: [PATCH 010/480] add schedule config and schedule stuff --- .../Room/Config/EssentialsTechRoomConfig.cs | 2 + .../Room/Types/EssentialsTechRoom.cs | 68 +++++++++++++++++++ .../Global/Scheduler.cs | 36 ++++++++++ .../EssentialsRoomScheduledEventsConfig.cs | 37 ++++++++++ 4 files changed, 143 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 8f35461b..3e4e0dc7 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -10,11 +10,13 @@ namespace PepperDash.Essentials.Room.Config public string UserPin; public string TechPin; public string PresetsFileName; + public EssentialsRoomScheduledEventsConfig RoomScheduledEvents; public EssentialsTechRoomConfig() { Displays = new List(); Tuners = new List(); + RoomScheduledEvents = new EssentialsRoomScheduledEventsConfig(); } } } \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 0680f46b..7a6d9c7e 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Scheduler; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; @@ -19,6 +21,8 @@ namespace PepperDash.Essentials private readonly EssentialsTechRoomConfig _config; + private ScheduledEventGroup _roomScheduledEventGroup; + public DevicePresetsModel TunerPresets { get @@ -56,6 +60,10 @@ namespace PepperDash.Essentials _displays = GetDevices(_config.Displays); RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn); + + SubscribeToDisplayFeedbacks(); + + CreateScheduledEvents(); } private void SubscribeToDisplayFeedbacks() @@ -66,6 +74,66 @@ namespace PepperDash.Essentials } } + private void CreateScheduledEvents() + { + var eventsConfig = _config.RoomScheduledEvents; + + _roomScheduledEventGroup = new ScheduledEventGroup(Key); + + _roomScheduledEventGroup.RetrieveAllEvents(); + + Scheduler.AddEventGroup(_roomScheduledEventGroup); + + foreach (var eventConfig in eventsConfig.ScheduledEvents) + { + if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(eventConfig.Name)) + { + SchedulerUtilities.CreateEventFromConfig(eventConfig, _roomScheduledEventGroup); + continue; + } + + var roomEvent = _roomScheduledEventGroup.ScheduledEvents[eventConfig.Key]; + + if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(eventConfig.Time)) && + !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, eventConfig.Days)) + { + continue; + } + Debug.Console(1, this, "Existing event does not match new config properties. Deleting exisiting event: '{0}'", roomEvent.Name); + + _roomScheduledEventGroup.DeleteEvent(roomEvent); + + SchedulerUtilities.CreateEventFromConfig(eventConfig, _roomScheduledEventGroup); + } + + _roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent; + } + + private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type) + { + var eventConfig = _config.RoomScheduledEvents.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name); + + if (eventConfig == null) + { + Debug.Console(1, this, "Event with name {0} not found", schevent.Name); + return; + } + + if (eventConfig.Acknowledgeable) + { + schevent.Acknowledge(); + } + + CrestronInvoke.BeginInvoke((o) => + { + foreach (var a in eventConfig.Actions) + { + DeviceJsonApi.DoDeviceAction(a.Value); + } + }); + } + + public void RoomPowerOn() { foreach (var display in _displays) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index a7b721ef..85832cba 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -6,6 +6,8 @@ using Crestron.SimplSharp; using Crestron.SimplSharp.Scheduler; using PepperDash.Core; +using PepperDash.Essentials.Core.Fusion; +using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials.Core { @@ -135,5 +137,39 @@ namespace PepperDash.Essentials.Core return isMatch; } + + public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time) + { + return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute; + } + + public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days) + { + return evnt.Recurrence.RecurrenceDays == days; + } + + public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group) + { + if (group == null) + { + Debug.Console(0, "Unable to create event. Group is null"); + return; + } + var scheduledEvent = new ScheduledEvent(config.Key, group) + { + Acknowledgeable = config.Acknowledgeable, + Persistent = config.Persistent + }; + + scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); + + scheduledEvent.Recurrence.Weekly(config.Days); + + var eventTime = DateTime.Parse(config.Time); + + if (DateTime.Now < eventTime) eventTime.AddDays(1); + + scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs new file mode 100644 index 00000000..50c77f1f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Crestron.SimplSharp.Scheduler; +using Newtonsoft.Json; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Room.Config +{ + public class EssentialsRoomScheduledEventsConfig + { + [JsonProperty("scheduledEvents")] + public List ScheduledEvents; + } + + public class ScheduledEventConfig + { + [JsonProperty("key")] + public string Key; + + [JsonProperty("name")] + public string Name; + + [JsonProperty("days")] + public ScheduledEventCommon.eWeekDays Days; + + [JsonProperty("time")] + public string Time; + + [JsonProperty("actions")] + public Dictionary Actions; + + [JsonProperty("persistent")] + public bool Persistent; + + [JsonProperty("acknowledgeable")] + public bool Acknowledgeable; + } +} \ No newline at end of file From 45c1e25e4fb50166e9cfc0ec95985f1dffe82b26 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 21:35:31 -0700 Subject: [PATCH 011/480] Change to list of actions instead of dictionary --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 +- .../Room/Config/EssentialsRoomScheduledEventsConfig.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 7a6d9c7e..f0521d64 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -128,7 +128,7 @@ namespace PepperDash.Essentials { foreach (var a in eventConfig.Actions) { - DeviceJsonApi.DoDeviceAction(a.Value); + DeviceJsonApi.DoDeviceAction(a); } }); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs index 50c77f1f..e16524ce 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs @@ -26,7 +26,7 @@ namespace PepperDash.Essentials.Room.Config public string Time; [JsonProperty("actions")] - public Dictionary Actions; + public List Actions; [JsonProperty("persistent")] public bool Persistent; From fc5d4f946d0c7438d56dd411178fee5eddfdbfd8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 4 Dec 2020 21:36:07 -0700 Subject: [PATCH 012/480] added scheduled events config --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 6d4def73..1a2fc594 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -278,6 +278,7 @@ + From 05e2422cb405be3a0df6c2c4ae04ea379d27f560 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:48:07 -0700 Subject: [PATCH 013/480] refactoring some methods add handling for Scheduled Events --- .../Room/Types/EssentialsTechRoom.cs | 167 ++++++++++++------ 1 file changed, 110 insertions(+), 57 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index f0521d64..cb8ebfa1 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.Scheduler; +using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; @@ -12,23 +13,37 @@ using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials { - public class EssentialsTechRoom:EssentialsRoomBase + public class EssentialsTechRoom : EssentialsRoomBase { - private readonly Dictionary _tuners; + private readonly EssentialsTechRoomConfig _config; private readonly Dictionary _displays; private readonly DevicePresetsModel _tunerPresets; - - private readonly EssentialsTechRoomConfig _config; + private readonly Dictionary _tuners; private ScheduledEventGroup _roomScheduledEventGroup; + public EssentialsTechRoom(DeviceConfig config) : base(config) + { + _config = config.Properties.ToObject(); + + _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName); + + _tunerPresets.LoadChannels(); + + _tuners = GetDevices(_config.Tuners); + _displays = GetDevices(_config.Displays); + + RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn); + + SubscribeToDisplayFeedbacks(); + + CreateOrUpdateScheduledEvents(); + } + public DevicePresetsModel TunerPresets { - get - { - return _tunerPresets; - } + get { return _tunerPresets; } } public Dictionary Tuners @@ -48,70 +63,104 @@ namespace PepperDash.Essentials get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); } } - public EssentialsTechRoom(DeviceConfig config) : base(config) - { - _config = config.Properties.ToObject(); - - _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName); - - _tunerPresets.LoadChannels(); - - _tuners = GetDevices(_config.Tuners); - _displays = GetDevices(_config.Displays); - - RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn); - - SubscribeToDisplayFeedbacks(); - - CreateScheduledEvents(); - } - private void SubscribeToDisplayFeedbacks() { foreach (var display in _displays) { - display.Value.PowerIsOnFeedback.OutputChange += (sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate(); + display.Value.PowerIsOnFeedback.OutputChange += + (sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate(); } } - private void CreateScheduledEvents() + private void CreateOrUpdateScheduledEvents() { var eventsConfig = _config.RoomScheduledEvents; - _roomScheduledEventGroup = new ScheduledEventGroup(Key); + GetOrCreateScheduleGroup(); - _roomScheduledEventGroup.RetrieveAllEvents(); - - Scheduler.AddEventGroup(_roomScheduledEventGroup); - - foreach (var eventConfig in eventsConfig.ScheduledEvents) + foreach (var eventConfig in eventsConfig) { - if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(eventConfig.Name)) - { - SchedulerUtilities.CreateEventFromConfig(eventConfig, _roomScheduledEventGroup); - continue; - } - - var roomEvent = _roomScheduledEventGroup.ScheduledEvents[eventConfig.Key]; - - if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(eventConfig.Time)) && - !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, eventConfig.Days)) - { - continue; - } - Debug.Console(1, this, "Existing event does not match new config properties. Deleting exisiting event: '{0}'", roomEvent.Name); - - _roomScheduledEventGroup.DeleteEvent(roomEvent); - - SchedulerUtilities.CreateEventFromConfig(eventConfig, _roomScheduledEventGroup); + CreateOrUpdateSingleEvent(eventConfig); } _roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent; } + private void GetOrCreateScheduleGroup() + { + if (_roomScheduledEventGroup == null) + { + _roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key); + + Scheduler.AddEventGroup(_roomScheduledEventGroup); + } + + _roomScheduledEventGroup.RetrieveAllEvents(); + } + + private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent) + { + if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Name)) + { + SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); + return; + } + + var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key]; + + if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) && + !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days)) + { + return; + } + + Debug.Console(1, this, + "Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration", + roomEvent.Name); + + _roomScheduledEventGroup.DeleteEvent(roomEvent); + + SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); + } + + public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent) + { + //update config based on key of scheduleEvent + GetOrCreateScheduleGroup(); + var existingEvent = _config.RoomScheduledEvents.FirstOrDefault(e => e.Key == scheduledEvent.Key); + + if (existingEvent == null) + { + _config.RoomScheduledEvents.Add(scheduledEvent); + } + + //create or update event based on config + CreateOrUpdateSingleEvent(scheduledEvent); + //save config + Config.Properties = JToken.FromObject(_config); + + CustomSetConfig(Config); + //Fire Event + OnScheduledEventUpdate(); + } + + public void OnScheduledEventUpdate() + { + var handler = ScheduledEventsChanged; + + if (handler == null) + { + return; + } + + handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.RoomScheduledEvents}); + } + + public event EventHandler ScheduledEventsChanged; + private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type) { - var eventConfig = _config.RoomScheduledEvents.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name); + var eventConfig = _config.RoomScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name); if (eventConfig == null) { @@ -150,7 +199,7 @@ namespace PepperDash.Essentials } } - private Dictionary GetDevices(ICollection config) where T:IKeyed + private Dictionary GetDevices(ICollection config) where T : IKeyed { try { @@ -162,13 +211,12 @@ namespace PepperDash.Essentials } catch { - Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error getting devices. Check Essentials Configuration"); + Debug.Console(0, this, Debug.ErrorLogLevel.Error, + "Error getting devices. Check Essentials Configuration"); return null; } } - - #region Overrides of EssentialsRoomBase protected override Func IsWarmingFeedbackFunc @@ -213,4 +261,9 @@ namespace PepperDash.Essentials #endregion } + + public class ScheduledEventEventArgs : EventArgs + { + public List ScheduledEvents; + } } \ No newline at end of file From 3a024b8d4c0cb08cd94c5060a0cb07da795026b9 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:48:21 -0700 Subject: [PATCH 014/480] moved ScheduledEvents list to main object --- PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 3e4e0dc7..e4b88e96 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -10,13 +10,13 @@ namespace PepperDash.Essentials.Room.Config public string UserPin; public string TechPin; public string PresetsFileName; - public EssentialsRoomScheduledEventsConfig RoomScheduledEvents; + public List RoomScheduledEvents; public EssentialsTechRoomConfig() { Displays = new List(); Tuners = new List(); - RoomScheduledEvents = new EssentialsRoomScheduledEventsConfig(); + RoomScheduledEvents = new List(); } } } \ No newline at end of file From 0dc2e9d134e185d68a28e4fea0e13c19a3bb96f7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:48:34 -0700 Subject: [PATCH 015/480] Added logic to create EssentialsTechRoom --- PepperDashEssentials/ControlSystem.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 460086e0..4e24de9f 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -12,6 +12,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Fusion; using PepperDash.Essentials.Devices.Common; using PepperDash.Essentials.DM; using PepperDash.Essentials.Fusion; @@ -436,7 +437,7 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1)); + DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, 0xf1)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -454,6 +455,18 @@ namespace PepperDash.Essentials CreateMobileControlBridge(room); } + else if (room is EssentialsTechRoom) + { + DeviceManager.AddDevice(room); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, + "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase(room, 0xF1)); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); + + CreateMobileControlBridge(room); + } else { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion"); From ab6d44e60461497e9ec29c1b178aa986fb220feb Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:48:48 -0700 Subject: [PATCH 016/480] added enable property to ScheduledEventConfig --- .../Room/Config/EssentialsRoomScheduledEventsConfig.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs index e16524ce..366f453c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs @@ -33,5 +33,8 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("acknowledgeable")] public bool Acknowledgeable; + + [JsonProperty("enable")] + public bool Enable; } } \ No newline at end of file From d2b7e71c4adb254b8ff406d03c9e52b3e874a1d8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:49:30 -0700 Subject: [PATCH 017/480] Added GetScheduledEventGroup Method added logic to enable/disable events --- .../Global/Scheduler.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 85832cba..64ba57df 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -1,12 +1,9 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharp.Scheduler; using PepperDash.Core; -using PepperDash.Essentials.Core.Fusion; using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials.Core @@ -16,7 +13,7 @@ namespace PepperDash.Essentials.Core /// public static class Scheduler { - private static Dictionary EventGroups = new Dictionary(); + private static readonly Dictionary EventGroups = new Dictionary(); static Scheduler() { @@ -51,7 +48,6 @@ namespace PepperDash.Essentials.Core /// /// Adds the event group to the global list /// - /// /// public static void AddEventGroup(ScheduledEventGroup eventGroup) { @@ -69,6 +65,13 @@ namespace PepperDash.Essentials.Core if(!EventGroups.ContainsKey(eventGroup.Name)) EventGroups.Remove(eventGroup.Name); } + + public static ScheduledEventGroup GetEventGroup(string key) + { + ScheduledEventGroup returnValue; + + return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null; + } } public static class SchedulerUtilities @@ -161,6 +164,15 @@ namespace PepperDash.Essentials.Core Persistent = config.Persistent }; + if (config.Enable) + { + scheduledEvent.Resume(); + } + else + { + scheduledEvent.Pause(); + } + scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); scheduledEvent.Recurrence.Weekly(config.Days); From 43d7fab04d25a27456f30a603505634c353aecf7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 11:50:48 -0700 Subject: [PATCH 018/480] refactored Fusion Base Class --- ...lsHuddleSpaceFusionSystemControllerBase.cs | 1769 +++++++++-------- 1 file changed, 952 insertions(+), 817 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 39cd7d78..9270ed37 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -2,164 +2,118 @@ using System.Collections.Generic; using System.Linq; using System.Text; - using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronXml; using Crestron.SimplSharp.CrestronXml.Serialization; -using Crestron.SimplSharp.CrestronXmlLinq; using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.Fusion; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - using PepperDash.Core; -using PepperDash.Essentials; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; - - namespace PepperDash.Essentials.Core.Fusion { - public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider - { - public event EventHandler ScheduleChange; - //public event EventHandler MeetingEndWarning; - //public event EventHandler NextMeetingBeginWarning; + public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider + { + private const string RemoteOccupancyXml = "Local{0}"; + private readonly bool _guidFileExists; - public event EventHandler RoomInfoChange; + private readonly Dictionary _sourceToFeedbackSigs = + new Dictionary(); + + protected StringSigData CurrentRoomSourceNameSig; public FusionCustomPropertiesBridge CustomPropertiesBridge = new FusionCustomPropertiesBridge(); + protected FusionOccupancySensorAsset FusionOccSensor; + protected FusionRemoteOccupancySensor FusionRemoteOccSensor; - protected FusionRoom FusionRoom; - protected EssentialsRoomBase Room; - Dictionary SourceToFeedbackSigs = - new Dictionary(); + protected FusionRoom FusionRoom; + protected Dictionary FusionStaticAssets; + public long PushNotificationTimeout = 5000; + protected EssentialsRoomBase Room; + public long SchedulePollInterval = 300000; - StatusMonitorCollection ErrorMessageRollUp; + private Event _currentMeeting; + private RoomSchedule _currentSchedule; + private CTimer _dailyTimeRequestTimer; + private StatusMonitorCollection _errorMessageRollUp; - protected StringSigData CurrentRoomSourceNameSig; + private FusionRoomGuids _guiDs; + private uint _ipId; + + private bool _isRegisteredForSchedulePushNotifications; + private Event _nextMeeting; + + private CTimer _pollTimer; + + private CTimer _pushNotificationTimer; + + private string _roomOccupancyRemoteString; #region System Info Sigs + //StringSigData SystemName; //StringSigData Model; //StringSigData SerialNumber; //StringSigData Uptime; + #endregion - #region Processor Info Sigs - StringSigData Ip1; - StringSigData Ip2; - StringSigData Gateway; - StringSigData Hostname; - StringSigData Domain; - StringSigData Dns1; - StringSigData Dns2; - StringSigData Mac1; - StringSigData Mac2; - StringSigData NetMask1; - StringSigData NetMask2; - StringSigData Firmware; - StringSigData[] Program = new StringSigData[10]; + private readonly StringSigData[] _program = new StringSigData[10]; + private StringSigData _dns1; + private StringSigData _dns2; + private StringSigData _domain; + private StringSigData _firmware; + private StringSigData _gateway; + private StringSigData _hostname; + private StringSigData _ip1; + private StringSigData _ip2; + private StringSigData _mac1; + private StringSigData _mac2; + private StringSigData _netMask1; + private StringSigData _netMask2; + #endregion #region Default Display Source Sigs - BooleanSigData[] Source = new BooleanSigData[10]; + private BooleanSigData[] _source = new BooleanSigData[10]; #endregion - RoomSchedule CurrentSchedule; - - Event NextMeeting; - - Event CurrentMeeting; - - protected string RoomGuid - { - get - { - return GUIDs.RoomGuid; - } - - } - - uint IpId; - - FusionRoomGuids GUIDs; - - bool GuidFileExists; - - bool IsRegisteredForSchedulePushNotifications = false; - - CTimer PollTimer = null; - - CTimer PushNotificationTimer = null; - - CTimer DailyTimeRequestTimer = null; - - // Default poll time is 5 min unless overridden by config value - public long SchedulePollInterval = 300000; - - public long PushNotificationTimeout = 5000; - - private const string RemoteOccupancyXml = "Local{0}"; - - protected Dictionary FusionStaticAssets; - - // For use with local occ sensor devices which will relay to Fusion the current occupancy status - protected FusionRemoteOccupancySensor FusionRemoteOccSensor; - - // For use with occ sensor attached to a scheduling panel in Fusion - protected FusionOccupancySensorAsset FusionOccSensor; - - public BoolFeedback RoomIsOccupiedFeedback { get; private set; } - - private string _roomOccupancyRemoteString; - public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; } - - protected Func RoomIsOccupiedFeedbackFunc - { - get - { - return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; - } - } - - //ScheduleResponseEvent NextMeeting; - public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId) - : base(room.Key + "-fusion") - { - + : base(room.Key + "-fusion") + { try { - Room = room; - IpId = ipId; + _ipId = ipId; FusionStaticAssets = new Dictionary(); - GUIDs = new FusionRoomGuids(); + _guiDs = new FusionRoomGuids(); - var mac = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0); + var mac = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0); var slot = Global.ControlSystem.ProgramNumber; - string guidFilePath = Global.FilePathPrefix + string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag); + var guidFilePath = Global.FilePathPrefix + + string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag); - GuidFileExists = File.Exists(guidFilePath); + _guidFileExists = File.Exists(guidFilePath); // Check if file exists - if (!GuidFileExists) + if (!_guidFileExists) { // Does not exist. Create GUIDs - GUIDs = new FusionRoomGuids(Room.Name, ipId, GUIDs.GenerateNewRoomGuid(slot, mac), FusionStaticAssets); + _guiDs = new FusionRoomGuids(Room.Name, ipId, _guiDs.GenerateNewRoomGuid(slot, mac), + FusionStaticAssets); } else { @@ -170,18 +124,19 @@ namespace PepperDash.Essentials.Core.Fusion if (Room.RoomOccupancy != null) { if (Room.OccupancyStatusProviderIsRemote) + { SetUpRemoteOccupancy(); + } else { SetUpLocalOccupancy(); } } - AddPostActivationAction(() => { - CreateSymbolAndBasicSigs(IpId); + CreateSymbolAndBasicSigs(_ipId); SetUpSources(); SetUpCommunitcationMonitors(); SetUpDisplay(); @@ -192,27 +147,51 @@ namespace PepperDash.Essentials.Core.Fusion GenerateGuidFile(guidFilePath); }); - } catch (Exception e) { Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error Building Fusion System Controller: {0}", e); } - } + } + + protected string RoomGuid + { + get { return _guiDs.RoomGuid; } + } + + public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; } + + protected Func RoomIsOccupiedFeedbackFunc + { + get { return () => FusionRemoteOccSensor.RoomOccupied.OutputSig.BoolValue; } + } + + #region IOccupancyStatusProvider Members + + public BoolFeedback RoomIsOccupiedFeedback { get; private set; } + + #endregion + + public event EventHandler ScheduleChange; + //public event EventHandler MeetingEndWarning; + //public event EventHandler NextMeetingBeginWarning; + + public event EventHandler RoomInfoChange; + + //ScheduleResponseEvent NextMeeting; /// /// Used for extension classes to execute whatever steps are necessary before generating the RVI and GUID files /// protected virtual void ExecuteCustomSteps() { - } /// /// Generates the guid file in NVRAM. If the file already exists it will be overwritten. /// /// path for the file - void GenerateGuidFile(string filePath) + private void GenerateGuidFile(string filePath) { if (string.IsNullOrEmpty(filePath)) { @@ -220,32 +199,32 @@ namespace PepperDash.Essentials.Core.Fusion return; } - CCriticalSection _fileLock = new CCriticalSection(); + var fileLock = new CCriticalSection(); try { - if (_fileLock == null || _fileLock.Disposed) + if (fileLock.Disposed) + { return; + } - _fileLock.Enter(); + fileLock.Enter(); Debug.Console(1, this, "Writing GUIDs to file"); - if (FusionOccSensor == null) - GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, FusionStaticAssets); - else - GUIDs = new FusionRoomGuids(Room.Name, IpId, RoomGuid, FusionStaticAssets, FusionOccSensor); + _guiDs = FusionOccSensor == null + ? new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets) + : new FusionRoomGuids(Room.Name, _ipId, RoomGuid, FusionStaticAssets, FusionOccSensor); - var JSON = JsonConvert.SerializeObject(GUIDs, Newtonsoft.Json.Formatting.Indented); + var json = JsonConvert.SerializeObject(_guiDs, Newtonsoft.Json.Formatting.Indented); - using (StreamWriter sw = new StreamWriter(filePath)) + using (var sw = new StreamWriter(filePath)) { - sw.Write(JSON); + sw.Write(json); sw.Flush(); } Debug.Console(1, this, "Guids successfully written to file '{0}'", filePath); - } catch (Exception e) { @@ -253,8 +232,10 @@ namespace PepperDash.Essentials.Core.Fusion } finally { - if (_fileLock != null && !_fileLock.Disposed) - _fileLock.Leave(); + if (!fileLock.Disposed) + { + fileLock.Leave(); + } } } @@ -262,42 +243,45 @@ namespace PepperDash.Essentials.Core.Fusion /// Reads the guid file from NVRAM /// /// path for te file - void ReadGuidFile(string filePath) + private void ReadGuidFile(string filePath) { - if(string.IsNullOrEmpty(filePath)) + if (string.IsNullOrEmpty(filePath)) { Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Error reading guid file. No path specified."); return; } - CCriticalSection _fileLock = new CCriticalSection(); + var fileLock = new CCriticalSection(); try { - if(_fileLock == null || _fileLock.Disposed) - return; - - _fileLock.Enter(); - - if(File.Exists(filePath)) + if (fileLock.Disposed) { - var JSON = File.ReadToEnd(filePath, Encoding.ASCII); - - GUIDs = JsonConvert.DeserializeObject(JSON); - - IpId = GUIDs.IpId; - - FusionStaticAssets = GUIDs.StaticAssets; - + return; } - Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}", filePath); + fileLock.Enter(); - Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, IpId, RoomGuid); + if (File.Exists(filePath)) + { + var json = File.ReadToEnd(filePath, Encoding.ASCII); + + _guiDs = JsonConvert.DeserializeObject(json); + + _ipId = _guiDs.IpId; + + FusionStaticAssets = _guiDs.StaticAssets; + } + + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}", + filePath); + + Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, _ipId, RoomGuid); foreach (var item in FusionStaticAssets) { - Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", item.Value.Name, item.Value.SlotNumber, item.Value.InstanceId); + Debug.Console(1, this, "\nAsset Name: {0}\nAsset No: {1}\n Guid: {2}", item.Value.Name, + item.Value.SlotNumber, item.Value.InstanceId); } } catch (Exception e) @@ -306,46 +290,65 @@ namespace PepperDash.Essentials.Core.Fusion } finally { - if(_fileLock != null && !_fileLock.Disposed) - _fileLock.Leave(); + if (!fileLock.Disposed) + { + fileLock.Leave(); + } } - } - protected virtual void CreateSymbolAndBasicSigs(uint ipId) - { + protected virtual void CreateSymbolAndBasicSigs(uint ipId) + { Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); FusionRoom.ExtenderFusionRoomDataReservedSigs.Use(); - FusionRoom.Register(); + FusionRoom.Register(); - FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange); + FusionRoom.FusionStateChange += FusionRoom_FusionStateChange; - FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += new DeviceExtenderJoinChangeEventHandler(FusionRoomSchedule_DeviceExtenderSigChange); - FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += new DeviceExtenderJoinChangeEventHandler(ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange); - FusionRoom.OnlineStatusChange += new OnlineStatusChangeEventHandler(FusionRoom_OnlineStatusChange); + FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += + FusionRoomSchedule_DeviceExtenderSigChange; + FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += + ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange; + FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange; - CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", + "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", + "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", + "Creates and Ad Hoc meeting for on hour or until the next meeting", + ConsoleAccessLevelEnum.AccessOperator); - // Room to fusion room - Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); + // Room to fusion room + Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly); - // Don't think we need to get current status of this as nothing should be alive yet. - (Room as IHasCurrentSourceInfoChange).CurrentSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange); + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", + eSigIoMask.InputSigOnly); + // Don't think we need to get current status of this as nothing should be alive yet. + var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange; + if (hasCurrentSourceInfoChange != null) + { + hasCurrentSourceInfoChange.CurrentSourceChange += Room_CurrentSourceInfoChange; + } - FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsRoomBase).PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey)); - // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); - FusionRoom.ErrorMessage.InputSig.StringValue = - "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => + { + var runRouteAction = Room as IRunRouteAction; + if (runRouteAction != null) + { + runRouteAction.RunRouteAction("roomOff", Room.SourceListKey); + } + }); + // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); + FusionRoom.ErrorMessage.InputSig.StringValue = + "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; SetUpEthernetValues(); @@ -355,7 +358,7 @@ namespace PepperDash.Essentials.Core.Fusion GetProcessorInfo(); - CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler); + CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; } protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) @@ -372,82 +375,107 @@ namespace PepperDash.Essentials.Core.Fusion //Model.InputSig.StringValue = InitialParametersClass.ControllerPromptName; //SerialNumber.InputSig.StringValue = InitialParametersClass. - string response = string.Empty; + var response = string.Empty; var systemReboot = FusionRoom.CreateOffsetBoolSig(74, "Processor - Reboot", eSigIoMask.OutputSigOnly); - systemReboot.OutputSig.SetSigFalseAction(() => CrestronConsole.SendControlSystemCommand("reboot", ref response)); + systemReboot.OutputSig.SetSigFalseAction( + () => CrestronConsole.SendControlSystemCommand("reboot", ref response)); } protected void SetUpEthernetValues() { - Ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); - Ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); - Gateway = FusionRoom.CreateOffsetStringSig(52, "Info - Processor - Gateway", eSigIoMask.InputSigOnly); - Hostname = FusionRoom.CreateOffsetStringSig(53, "Info - Processor - Hostname", eSigIoMask.InputSigOnly); - Domain = FusionRoom.CreateOffsetStringSig(54, "Info - Processor - Domain", eSigIoMask.InputSigOnly); - Dns1 = FusionRoom.CreateOffsetStringSig(55, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly); - Dns2 = FusionRoom.CreateOffsetStringSig(56, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly); - Mac1 = FusionRoom.CreateOffsetStringSig(57, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly); - Mac2 = FusionRoom.CreateOffsetStringSig(58, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly); - NetMask1 = FusionRoom.CreateOffsetStringSig(59, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly); - NetMask2 = FusionRoom.CreateOffsetStringSig(60, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly); + _ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); + _ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); + _gateway = FusionRoom.CreateOffsetStringSig(52, "Info - Processor - Gateway", eSigIoMask.InputSigOnly); + _hostname = FusionRoom.CreateOffsetStringSig(53, "Info - Processor - Hostname", eSigIoMask.InputSigOnly); + _domain = FusionRoom.CreateOffsetStringSig(54, "Info - Processor - Domain", eSigIoMask.InputSigOnly); + _dns1 = FusionRoom.CreateOffsetStringSig(55, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly); + _dns2 = FusionRoom.CreateOffsetStringSig(56, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly); + _mac1 = FusionRoom.CreateOffsetStringSig(57, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly); + _mac2 = FusionRoom.CreateOffsetStringSig(58, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly); + _netMask1 = FusionRoom.CreateOffsetStringSig(59, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly); + _netMask2 = FusionRoom.CreateOffsetStringSig(60, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly); } protected void GetProcessorEthernetValues() { - Ip1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0); - Gateway.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0); - Hostname.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0); - Domain.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0); + _ip1.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0); + _gateway.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0); + _hostname.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0); + _domain.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0); - var dnsServers = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, 0).Split(','); - Dns1.InputSig.StringValue = dnsServers[0]; + var dnsServers = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, 0).Split(','); + _dns1.InputSig.StringValue = dnsServers[0]; if (dnsServers.Length > 1) - Dns2.InputSig.StringValue = dnsServers[1]; + { + _dns2.InputSig.StringValue = dnsServers[1]; + } - Mac1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0); - NetMask1.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0); + _mac1.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 0); + _netMask1.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0); // Interface 1 - if (InitialParametersClass.NumberOfEthernetInterfaces > 1) // Only get these values if the processor has more than 1 NIC + if (InitialParametersClass.NumberOfEthernetInterfaces > 1) + // Only get these values if the processor has more than 1 NIC { - Ip2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 1); - Mac2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 1); - NetMask2.InputSig.StringValue = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 1); + _ip2.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 1); + _mac2.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, 1); + _netMask2.InputSig.StringValue = + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 1); } } protected void GetProcessorInfo() { - - Firmware = FusionRoom.CreateOffsetStringSig(61, "Info - Processor - Firmware", eSigIoMask.InputSigOnly); + _firmware = FusionRoom.CreateOffsetStringSig(61, "Info - Processor - Firmware", eSigIoMask.InputSigOnly); if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) { - for (int i = 0; i < Global.ControlSystem.NumProgramsSupported; i++) + for (var i = 0; i < Global.ControlSystem.NumProgramsSupported; i++) { var join = 62 + i; var progNum = i + 1; - Program[i] = FusionRoom.CreateOffsetStringSig((uint)join, string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly); + _program[i] = FusionRoom.CreateOffsetStringSig((uint) join, + string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly); } } - Firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion; - + _firmware.InputSig.StringValue = InitialParametersClass.FirmwareVersion; } protected void GetCustomProperties() { if (FusionRoom.IsOnline) { - string fusionRoomCustomPropertiesRequest = @"RoomConfigurationRequest"; + const string fusionRoomCustomPropertiesRequest = + @"RoomConfigurationRequest"; - FusionRoom.ExtenderFusionRoomDataReservedSigs.RoomConfigQuery.StringValue = fusionRoomCustomPropertiesRequest; + FusionRoom.ExtenderFusionRoomDataReservedSigs.RoomConfigQuery.StringValue = + fusionRoomCustomPropertiesRequest; } } - void GetTouchpanelInfo() + private void GetTouchpanelInfo() { // TODO: Get IP and Project Name from TP } @@ -460,33 +488,33 @@ namespace PepperDash.Essentials.Core.Fusion // Send Push Notification Action request: - string requestID = "InitialPushRequest"; + const string requestId = "InitialPushRequest"; - string actionRequest = - string.Format("\n{0}\n", requestID) + + var actionRequest = + string.Format("\n{0}\n", requestId) + "RegisterPushModel\n" + "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + "\n" + - "\n"; + "\n"; Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest); @@ -498,17 +526,16 @@ namespace PepperDash.Essentials.Core.Fusion RequestLocalDateTime(null); // Setup timer to request time daily - if (DailyTimeRequestTimer != null && !DailyTimeRequestTimer.Disposed) + if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed) { - DailyTimeRequestTimer.Stop(); - DailyTimeRequestTimer.Dispose(); + _dailyTimeRequestTimer.Stop(); + _dailyTimeRequestTimer.Dispose(); } - DailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000); + _dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000); - DailyTimeRequestTimer.Reset(86400000, 86400000); + _dailyTimeRequestTimer.Reset(86400000, 86400000); } - } /// @@ -517,9 +544,10 @@ namespace PepperDash.Essentials.Core.Fusion /// public void RequestLocalDateTime(object callbackObject) { - string timeRequestID = "TimeRequest"; + const string timeRequestId = "TimeRequest"; - string timeRequest = string.Format("{0}", timeRequestID); + var timeRequest = string.Format("{0}", + timeRequestId); FusionRoom.ExtenderFusionRoomDataReservedSigs.LocalDateTimeQuery.StringValue = timeRequest; } @@ -527,79 +555,78 @@ namespace PepperDash.Essentials.Core.Fusion /// /// Generates a room schedule request for this room for the next 24 hours. /// - /// string identifying this request. Used with a corresponding ScheduleResponse value public void RequestFullRoomSchedule(object callbackObject) { - DateTime now = DateTime.Today; + var now = DateTime.Today; - string currentTime = now.ToString("s"); + var currentTime = now.ToString("s"); - string requestTest = - string.Format("FullSchedleRequest{0}{1}24", RoomGuid, currentTime); + var requestTest = + string.Format( + "FullSchedleRequest{0}{1}24", + RoomGuid, currentTime); Debug.Console(2, this, "Sending Fusion ScheduleQuery: \n{0}", requestTest); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleQuery.StringValue = requestTest; - if (IsRegisteredForSchedulePushNotifications) - PushNotificationTimer.Stop(); + if (_isRegisteredForSchedulePushNotifications) + { + _pushNotificationTimer.Stop(); + } } - + /// /// Wrapper method to allow console commands to modify the current meeting end time /// /// meetingID extendTime public void ModifyMeetingEndTimeConsoleHelper(string command) { - string requestID; - string meetingID = null; - int extendMinutes = -1; + var extendMinutes = -1; - requestID = "ModifyMeetingTest12345"; + const string requestId = "ModifyMeetingTest12345"; try { var tokens = command.Split(' '); - meetingID = tokens[0]; extendMinutes = Int32.Parse(tokens[1]); - } catch (Exception e) { Debug.Console(1, this, "Error parsing console command: {0}", e); } - ModifyMeetingEndTime(requestID, extendMinutes); - + ModifyMeetingEndTime(requestId, extendMinutes); } /// /// Ends or Extends the current meeting by the specified number of minutes. /// + /// /// Number of minutes to extend the meeting. A value of 0 will end the meeting. - public void ModifyMeetingEndTime(string requestID, int extendMinutes) + public void ModifyMeetingEndTime(string requestId, int extendMinutes) { - if(CurrentMeeting == null) + if (_currentMeeting == null) { Debug.Console(1, this, "No meeting in progress. Unable to modify end time."); return; - } + } if (extendMinutes > -1) { - if(extendMinutes > 0) + if (extendMinutes > 0) { - var extendTime = CurrentMeeting.dtEnd - DateTime.Now; - double extendMinutesRaw = extendTime.TotalMinutes; + var extendTime = _currentMeeting.dtEnd - DateTime.Now; + var extendMinutesRaw = extendTime.TotalMinutes; - extendMinutes = extendMinutes + (int)Math.Round(extendMinutesRaw); + extendMinutes = extendMinutes + (int) Math.Round(extendMinutesRaw); } - string requestTest = string.Format( + var requestTest = string.Format( "{0}{1}MeetingChange" - , requestID, RoomGuid, CurrentMeeting.MeetingID, extendMinutes); + , requestId, RoomGuid, _currentMeeting.MeetingID, extendMinutes); Debug.Console(1, this, "Sending MeetingChange Request: \n{0}", requestTest); @@ -609,8 +636,6 @@ namespace PepperDash.Essentials.Core.Fusion { Debug.Console(1, this, "Invalid time specified"); } - - } /// @@ -618,38 +643,38 @@ namespace PepperDash.Essentials.Core.Fusion /// public void CreateAsHocMeeting(string command) { - string requestID = "CreateAdHocMeeting"; + const string requestId = "CreateAdHocMeeting"; - DateTime now = DateTime.Now.AddMinutes(1); + var now = DateTime.Now.AddMinutes(1); now.AddSeconds(-now.Second); // Assume 1 hour meeting if possible - DateTime dtEnd = now.AddHours(1); + var dtEnd = now.AddHours(1); // Check if room is available for 1 hour before next meeting - if (NextMeeting != null) + if (_nextMeeting != null) { - var roomAvailable = NextMeeting.dtEnd.Subtract(dtEnd); + var roomAvailable = _nextMeeting.dtEnd.Subtract(dtEnd); if (roomAvailable.TotalMinutes < 60) { - /// Room not available for full hour, book until next meeting starts - dtEnd = NextMeeting.dtEnd; + // Room not available for full hour, book until next meeting starts + dtEnd = _nextMeeting.dtEnd; } } - string createMeetingRequest = + var createMeetingRequest = "" + - string.Format("{0}", requestID) + - string.Format("{0}", RoomGuid) + - "" + - string.Format("{0}", now.ToString("s")) + - string.Format("{0}", dtEnd.ToString("s")) + - "AdHoc Meeting" + - "Room User" + - "Example Message" + - "" + + string.Format("{0}", requestId) + + string.Format("{0}", RoomGuid) + + "" + + string.Format("{0}", now.ToString("s")) + + string.Format("{0}", dtEnd.ToString("s")) + + "AdHoc Meeting" + + "Room User" + + "Example Message" + + "" + ""; Debug.Console(2, this, "Sending CreateMeeting Request: \n{0}", createMeetingRequest); @@ -659,7 +684,6 @@ namespace PepperDash.Essentials.Core.Fusion //Debug.Console(1, this, "Sending CreateMeeting Request: \n{0}", command); //FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateMeeting.StringValue = command; - } /// @@ -667,73 +691,73 @@ namespace PepperDash.Essentials.Core.Fusion /// /// /// - protected void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) + protected void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, + SigEventArgs args) { - Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); + Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, + args.Sig.StringValue); if (args.Sig == FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQueryResponse) { try { - XmlDocument message = new XmlDocument(); + var message = new XmlDocument(); message.LoadXml(args.Sig.StringValue); var actionResponse = message["ActionResponse"]; - if (actionResponse != null) + if (actionResponse == null) { - var requestID = actionResponse["RequestID"]; + return; + } - if (requestID.InnerText == "InitialPushRequest") + var requestId = actionResponse["RequestID"]; + + if (requestId.InnerText != "InitialPushRequest") + { + return; + } + + if (actionResponse["ActionID"].InnerText != "RegisterPushModel") + { + return; + } + + var parameters = actionResponse["Parameters"]; + + foreach (var isRegistered in from XmlElement parameter in parameters + where parameter.HasAttributes + select parameter.Attributes + into attributes + where attributes["ID"].Value == "Registered" + select Int32.Parse(attributes["Value"].Value)) + { + switch (isRegistered) { - if (actionResponse["ActionID"].InnerText == "RegisterPushModel") - { - var parameters = actionResponse["Parameters"]; - - foreach (XmlElement parameter in parameters) + case 1: + _isRegisteredForSchedulePushNotifications = true; + if (_pollTimer != null && !_pollTimer.Disposed) { - if (parameter.HasAttributes) - { - var attributes = parameter.Attributes; - - if (attributes["ID"].Value == "Registered") - { - var isRegistered = Int32.Parse(attributes["Value"].Value); - - if (isRegistered == 1) - { - IsRegisteredForSchedulePushNotifications = true; - - if (PollTimer != null && !PollTimer.Disposed) - { - PollTimer.Stop(); - PollTimer.Dispose(); - } - - PushNotificationTimer = new CTimer(RequestFullRoomSchedule, null, PushNotificationTimeout, PushNotificationTimeout); - - PushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout); - } - else if (isRegistered == 0) - { - IsRegisteredForSchedulePushNotifications = false; - - if (PushNotificationTimer != null && !PushNotificationTimer.Disposed) - { - PushNotificationTimer.Stop(); - PushNotificationTimer.Dispose(); - } - - PollTimer = new CTimer(RequestFullRoomSchedule, null, SchedulePollInterval, SchedulePollInterval); - - PollTimer.Reset(SchedulePollInterval, SchedulePollInterval); - } - } - } + _pollTimer.Stop(); + _pollTimer.Dispose(); } - } + _pushNotificationTimer = new CTimer(RequestFullRoomSchedule, null, + PushNotificationTimeout, PushNotificationTimeout); + _pushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout); + break; + case 0: + _isRegisteredForSchedulePushNotifications = false; + if (_pushNotificationTimer != null && !_pushNotificationTimer.Disposed) + { + _pushNotificationTimer.Stop(); + _pushNotificationTimer.Dispose(); + } + _pollTimer = new CTimer(RequestFullRoomSchedule, null, SchedulePollInterval, + SchedulePollInterval); + _pollTimer.Reset(SchedulePollInterval, SchedulePollInterval); + break; } } } @@ -746,7 +770,7 @@ namespace PepperDash.Essentials.Core.Fusion { try { - XmlDocument message = new XmlDocument(); + var message = new XmlDocument(); message.LoadXml(args.Sig.StringValue); @@ -759,13 +783,15 @@ namespace PepperDash.Essentials.Core.Fusion if (localDateTime != null) { var tempLocalDateTime = localDateTime.InnerText; - - DateTime currentTime = DateTime.Parse(tempLocalDateTime); + + var currentTime = DateTime.Parse(tempLocalDateTime); Debug.Console(1, this, "DateTime from Fusion Server: {0}", currentTime); // Parse time and date from response and insert values - CrestronEnvironment.SetTimeAndDate((ushort)currentTime.Hour, (ushort)currentTime.Minute, (ushort)currentTime.Second, (ushort)currentTime.Month, (ushort)currentTime.Day, (ushort)currentTime.Year); + CrestronEnvironment.SetTimeAndDate((ushort) currentTime.Hour, (ushort) currentTime.Minute, + (ushort) currentTime.Second, (ushort) currentTime.Month, (ushort) currentTime.Day, + (ushort) currentTime.Year); Debug.Console(1, this, "Processor time set to {0}", CrestronEnvironment.GetLocalTime()); } @@ -780,13 +806,13 @@ namespace PepperDash.Essentials.Core.Fusion { // Room info response with custom properties - string roomConfigResponseArgs = args.Sig.StringValue.Replace("&", "and"); + var roomConfigResponseArgs = args.Sig.StringValue.Replace("&", "and"); Debug.Console(2, this, "Fusion Response: \n {0}", roomConfigResponseArgs); try { - XmlDocument roomConfigResponse = new XmlDocument(); + var roomConfigResponse = new XmlDocument(); roomConfigResponse.LoadXml(roomConfigResponseArgs); @@ -794,13 +820,13 @@ namespace PepperDash.Essentials.Core.Fusion if (requestRoomConfiguration != null) { - RoomInformation roomInformation = new RoomInformation(); + var roomInformation = new RoomInformation(); foreach (XmlElement e in roomConfigResponse.FirstChild.ChildNodes) { if (e.Name == "RoomInformation") { - XmlReader roomInfo = new XmlReader(e.OuterXml); + var roomInfo = new XmlReader(e.OuterXml); roomInformation = CrestronXMLSerialization.DeSerializeObject(roomInfo); } @@ -808,7 +834,7 @@ namespace PepperDash.Essentials.Core.Fusion { foreach (XmlElement el in e) { - FusionCustomProperty customProperty = new FusionCustomProperty(); + var customProperty = new FusionCustomProperty(); if (el.Name == "CustomField") { @@ -838,7 +864,9 @@ namespace PepperDash.Essentials.Core.Fusion var handler = RoomInfoChange; if (handler != null) + { handler(this, new EventArgs()); + } CustomPropertiesBridge.EvaluateRoomInfo(Room.Key, roomInformation); } @@ -851,7 +879,6 @@ namespace PepperDash.Essentials.Core.Fusion //getRoomInfoBusy = false; //_DynFusion.API.EISC.BooleanInput[Constants.GetRoomInfo].BoolValue = getRoomInfoBusy; } - } /// @@ -859,130 +886,127 @@ namespace PepperDash.Essentials.Core.Fusion /// /// /// - protected void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) + protected void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, + SigEventArgs args) { - Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); + Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, + args.Sig.Name, args.Sig.StringValue); - if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleResponse) - { - try - { - ScheduleResponse scheduleResponse = new ScheduleResponse(); + if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.ScheduleResponse) + { + try + { + var scheduleResponse = new ScheduleResponse(); - XmlDocument message = new XmlDocument(); + var message = new XmlDocument(); - message.LoadXml(args.Sig.StringValue); + message.LoadXml(args.Sig.StringValue); - var response = message["ScheduleResponse"]; + var response = message["ScheduleResponse"]; - if (response != null) - { - // Check for push notification - if (response["RequestID"].InnerText == "RVRequest") - { - var action = response["Action"]; + if (response != null) + { + // Check for push notification + if (response["RequestID"].InnerText == "RVRequest") + { + var action = response["Action"]; - if (action.OuterXml.IndexOf("RequestSchedule") > -1) - { - PushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout); - } - } - else // Not a push notification - { - CurrentSchedule = new RoomSchedule(); // Clear Current Schedule - CurrentMeeting = null; // Clear Current Meeting - NextMeeting = null; // Clear Next Meeting + if (action.OuterXml.IndexOf("RequestSchedule", StringComparison.Ordinal) > -1) + { + _pushNotificationTimer.Reset(PushNotificationTimeout, PushNotificationTimeout); + } + } + else // Not a push notification + { + _currentSchedule = new RoomSchedule(); // Clear Current Schedule + _currentMeeting = null; // Clear Current Meeting + _nextMeeting = null; // Clear Next Meeting - bool isNextMeeting = false; + var isNextMeeting = false; - foreach (XmlElement element in message.FirstChild.ChildNodes) - { - if (element.Name == "RequestID") - { - scheduleResponse.RequestID = element.InnerText; - } - else if (element.Name == "RoomID") - { - scheduleResponse.RoomID = element.InnerText; - } - else if (element.Name == "RoomName") - { - scheduleResponse.RoomName = element.InnerText; - } - else if (element.Name == "Event") - { - Debug.Console(2, this, "Event Found:\n{0}", element.OuterXml); + foreach (XmlElement element in message.FirstChild.ChildNodes) + { + if (element.Name == "RequestID") + { + scheduleResponse.RequestID = element.InnerText; + } + else if (element.Name == "RoomID") + { + scheduleResponse.RoomID = element.InnerText; + } + else if (element.Name == "RoomName") + { + scheduleResponse.RoomName = element.InnerText; + } + else if (element.Name == "Event") + { + Debug.Console(2, this, "Event Found:\n{0}", element.OuterXml); - XmlReader reader = new XmlReader(element.OuterXml); + var reader = new XmlReader(element.OuterXml); - Event tempEvent = new Event(); + var tempEvent = CrestronXMLSerialization.DeSerializeObject(reader); - tempEvent = CrestronXMLSerialization.DeSerializeObject(reader); + scheduleResponse.Events.Add(tempEvent); - scheduleResponse.Events.Add(tempEvent); + // Check is this is the current event + if (tempEvent.dtStart <= DateTime.Now && tempEvent.dtEnd >= DateTime.Now) + { + _currentMeeting = tempEvent; // Set Current Meeting + isNextMeeting = true; // Flag that next element is next meeting + } - // Check is this is the current event - if (tempEvent.dtStart <= DateTime.Now && tempEvent.dtEnd >= DateTime.Now) - { - CurrentMeeting = tempEvent; // Set Current Meeting - isNextMeeting = true; // Flag that next element is next meeting - } + if (isNextMeeting) + { + _nextMeeting = tempEvent; // Set Next Meeting + isNextMeeting = false; + } - if (isNextMeeting) - { - NextMeeting = tempEvent; // Set Next Meeting - isNextMeeting = false; - } + _currentSchedule.Meetings.Add(tempEvent); + } + } - CurrentSchedule.Meetings.Add(tempEvent); - } + PrintTodaysSchedule(); - } + if (!_isRegisteredForSchedulePushNotifications) + { + _pollTimer.Reset(SchedulePollInterval, SchedulePollInterval); + } - PrintTodaysSchedule(); - - if (!IsRegisteredForSchedulePushNotifications) - PollTimer.Reset(SchedulePollInterval, SchedulePollInterval); - - // Fire Schedule Change Event - var handler = ScheduleChange; - - if (handler != null) - { - handler(this, new ScheduleChangeEventArgs() { Schedule = CurrentSchedule }); - } - - } - } - - - - } - catch (Exception e) - { - Debug.Console(1, this, "Error parsing ScheduleResponse: {0}", e); - } - } - else if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateResponse) - { - Debug.Console(2, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); - } + // Fire Schedule Change Event + var handler = ScheduleChange; + if (handler != null) + { + handler(this, new ScheduleChangeEventArgs {Schedule = _currentSchedule}); + } + } + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error parsing ScheduleResponse: {0}", e); + } + } + else if (args.Sig == FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.CreateResponse) + { + Debug.Console(2, this, "Create Meeting Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, + args.Sig.Name, args.Sig.StringValue); + } } /// /// Prints today's schedule to console for debugging /// - void PrintTodaysSchedule() + private void PrintTodaysSchedule() { if (Debug.Level > 1) { - if (CurrentSchedule.Meetings.Count > 0) + if (_currentSchedule.Meetings.Count > 0) { Debug.Console(1, this, "Today's Schedule for '{0}'\n", Room.Name); - foreach (Event e in CurrentSchedule.Meetings) + foreach (var e in _currentSchedule.Meetings) { Debug.Console(1, this, "Subject: {0}", e.Subject); Debug.Console(1, this, "Organizer: {0}", e.Organizer); @@ -995,63 +1019,62 @@ namespace PepperDash.Essentials.Core.Fusion } } - protected virtual void SetUpSources() - { - // Sources - var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsRoomBase).SourceListKey); - if (dict != null) - { - // NEW PROCESS: - // Make these lists and insert the fusion attributes by iterating these - var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); - uint i = 1; - foreach (var kvp in setTopBoxes) - { - TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); - i = 1; - foreach (var kvp in discPlayers) - { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 5) // We only have five spots - break; - } - - var laptops = dict.Where(d => d.Value.SourceDevice is Devices.Laptop); - i = 1; - foreach (var kvp in laptops) - { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); - i++; - if (i > 10) // We only have ten spots??? - break; - } - - foreach (var kvp in dict) + protected virtual void SetUpSources() + { + // Sources + var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.SourceListKey); + if (dict != null) + { + // NEW PROCESS: + // Make these lists and insert the fusion attributes by iterating these + var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); + uint i = 1; + foreach (var kvp in setTopBoxes) { - var usageDevice = kvp.Value.SourceDevice as IUsageTracking; - - if (usageDevice != null) + TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots { - usageDevice.UsageTracker = new UsageTracking(usageDevice as Device); - usageDevice.UsageTracker.UsageIsTracked = true; - usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + break; } } - - } - else - { - Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", - (Room as EssentialsRoomBase).SourceListKey, Room.Key); - } - } + + var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); + i = 1; + foreach (var kvp in discPlayers) + { + TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + { + break; + } + } + + var laptops = dict.Where(d => d.Value.SourceDevice is Devices.Laptop); + i = 1; + foreach (var kvp in laptops) + { + TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 10) // We only have ten spots??? + { + break; + } + } + + foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType()) + { + usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true}; + usageDevice.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; + } + } + else + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", + Room.SourceListKey, Room.Key); + } + } /// /// Collects usage data from source and sends to Fusion @@ -1059,24 +1082,31 @@ namespace PepperDash.Essentials.Core.Fusion /// /// protected void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e) - { + { var deviceTracker = sender as UsageTracking; - var configDevice = ConfigReader.ConfigObject.Devices.Where(d => d.Key.Equals(deviceTracker.Parent)); + if (deviceTracker == null) + { + return; + } - string group = ConfigReader.GetGroupForDeviceKey(deviceTracker.Parent.Key); + var group = ConfigReader.GetGroupForDeviceKey(deviceTracker.Parent.Key); - string currentMeetingId = "-"; + var currentMeetingId = "-"; - if (CurrentMeeting != null) - currentMeetingId = CurrentMeeting.MeetingID; + if (_currentMeeting != null) + { + currentMeetingId = _currentMeeting.MeetingID; + } //String Format: "USAGE||[Date YYYY-MM-DD]||[Time HH-mm-ss]||TIME||[Asset_Type]||[Asset_Name]||[Minutes_used]||[Asset_ID]||[Meeting_ID]" // [Asset_ID] property does not appear to be used in Crestron SSI examples. They are sending "-" instead so that's what is replicated here - string deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||-||{4}||-||{5}||{6}||\r\n", e.UsageEndTime.ToString("yyyy-MM-dd"), e.UsageEndTime.ToString("HH:mm:ss"), - group, deviceTracker.Parent.Name, e.MinutesUsed, "-", currentMeetingId); + var deviceUsage = string.Format("USAGE||{0}||{1}||TIME||{2}||{3}||-||{4}||-||{5}||{6}||\r\n", + e.UsageEndTime.ToString("yyyy-MM-dd"), e.UsageEndTime.ToString("HH:mm:ss"), + @group, deviceTracker.Parent.Name, e.MinutesUsed, "-", currentMeetingId); - Debug.Console(1, this, "Device usage for: {0} ended at {1}. In use for {2} minutes", deviceTracker.Parent.Name, e.UsageEndTime, e.MinutesUsed); + Debug.Console(1, this, "Device usage for: {0} ended at {1}. In use for {2} minutes", + deviceTracker.Parent.Name, e.UsageEndTime, e.MinutesUsed); FusionRoom.DeviceUsage.InputSig.StringValue = deviceUsage; @@ -1084,41 +1114,51 @@ namespace PepperDash.Essentials.Core.Fusion } - protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) - { - Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", - attrName, attrNum, pSrc.Key); - try - { - var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); - // Need feedback when this source is selected - // Event handler, added below, will compare source changes with this sig dict - SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); + protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) + { + Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", + attrName, attrNum, pSrc.Key); + try + { + var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig); + // Need feedback when this source is selected + // Event handler, added below, will compare source changes with this sig dict + _sourceToFeedbackSigs.Add(pSrc, sigD.InputSig); - // And respond to selection in Fusion - sigD.OutputSig.SetSigFalseAction(() => (Room as IRunRouteAction).RunRouteAction(routeKey, Room.SourceListKey)); - } - catch (Exception) - { - Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", attrNum, attrName, pSrc.Key); - } - } + // And respond to selection in Fusion + sigD.OutputSig.SetSigFalseAction(() => + { + var runRouteAction = Room as IRunRouteAction; + if (runRouteAction != null) + { + runRouteAction.RunRouteAction(routeKey, Room.SourceListKey); + } + }); + } + catch (Exception) + { + Debug.Console(2, this, "Error creating Fusion signal {0} {1} for device '{2}'. THIS NEEDS REWORKING", + attrNum, attrName, pSrc.Key); + } + } - /// - /// - /// - void SetUpCommunitcationMonitors() - { + /// + /// + /// + private void SetUpCommunitcationMonitors() + { uint displayNum = 0; uint touchpanelNum = 0; uint xpanelNum = 0; - // Attach to all room's devices with monitors. - //foreach (var dev in DeviceManager.Devices) - foreach (var dev in DeviceManager.GetDevices()) - { - if (!(dev is ICommunicationMonitor)) - continue; + // Attach to all room's devices with monitors. + //foreach (var dev in DeviceManager.Devices) + foreach (var dev in DeviceManager.GetDevices()) + { + if (!(dev is ICommunicationMonitor)) + { + continue; + } string attrName = null; uint attrNum = 1; @@ -1141,7 +1181,9 @@ namespace PepperDash.Essentials.Core.Fusion attrNum = attrNum + touchpanelNum; if (attrNum > 10) + { continue; + } attrName = "Online - XPanel " + attrNum; attrNum += 160; @@ -1152,7 +1194,9 @@ namespace PepperDash.Essentials.Core.Fusion attrNum = attrNum + xpanelNum; if (attrNum > 10) + { continue; + } attrName = "Online - Touch Panel " + attrNum; attrNum += 150; @@ -1160,45 +1204,47 @@ namespace PepperDash.Essentials.Core.Fusion } } - //else - if (dev is DisplayBase) - { - attrNum = attrNum + displayNum; - if (attrNum > 10) - continue; - attrName = "Online - Display " + attrNum; - attrNum += 170; + //else + if (dev is DisplayBase) + { + attrNum = attrNum + displayNum; + if (attrNum > 10) + { + continue; + } + attrName = "Online - Display " + attrNum; + attrNum += 170; displayNum++; - } - //else if (dev is DvdDeviceBase) - //{ - // if (attrNum > 5) - // continue; - // attrName = "Device Ok - DVD " + attrNum; - // attrNum += 260; - //} - // add set top box + } + //else if (dev is DvdDeviceBase) + //{ + // if (attrNum > 5) + // continue; + // attrName = "Device Ok - DVD " + attrNum; + // attrNum += 260; + //} + // add set top box - // add Cresnet roll-up + // add Cresnet roll-up - // add DM-devices roll-up + // add DM-devices roll-up - if (attrName != null) - { - // Link comm status to sig and update - var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly); - var smd = dev as ICommunicationMonitor; - sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk; - smd.CommunicationMonitor.StatusChange += (o, a) => - { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; - Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName); - } - } - } + if (attrName != null) + { + // Link comm status to sig and update + var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly); + var smd = dev as ICommunicationMonitor; + sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk; + smd.CommunicationMonitor.StatusChange += + (o, a) => { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; + Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName); + } + } + } - protected virtual void SetUpDisplay() - { + protected virtual void SetUpDisplay() + { try { //Setup Display Usage Monitoring @@ -1207,35 +1253,52 @@ namespace PepperDash.Essentials.Core.Fusion // Consider updating this in multiple display systems - foreach (DisplayBase display in displays) + foreach (var display in displays.Cast()) { - display.UsageTracker = new UsageTracking(display); - display.UsageTracker.UsageIsTracked = true; - display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true}; + display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; } - var defaultDisplay = (Room as IHasDefaultDisplay).DefaultDisplay as DisplayBase; + var hasDefaultDisplay = Room as IHasDefaultDisplay; + if (hasDefaultDisplay == null) + { + return; + } + var defaultDisplay = hasDefaultDisplay.DefaultDisplay as DisplayBase; if (defaultDisplay == null) { Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); return; } - var dispPowerOnAction = new Action(b => { if (!b) defaultDisplay.PowerOn(); }); - var dispPowerOffAction = new Action(b => { if (!b) defaultDisplay.PowerOff(); }); + var dispPowerOnAction = new Action(b => + { + if (!b) + { + defaultDisplay.PowerOn(); + } + }); + var dispPowerOffAction = new Action(b => + { + if (!b) + { + defaultDisplay.PowerOff(); + } + }); // Display to fusion room sigs FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; - FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; + FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; MapDisplayToRoomJoins(1, 158, defaultDisplay); - var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); + var deviceConfig = + ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); //Check for existing asset in GUIDs collection - var tempAsset = new FusionAsset(); + FusionAsset tempAsset; if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) { @@ -1244,11 +1307,13 @@ namespace PepperDash.Essentials.Core.Fusion else { // Create a new asset - tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", ""); + tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), + defaultDisplay.Name, "Display", ""); FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); } - var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); + var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", + tempAsset.InstanceId); dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; @@ -1257,13 +1322,14 @@ namespace PepperDash.Essentials.Core.Fusion { defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); if (defaultDisplay is IDisplayUsage) + { (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + } defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); - } - // Use extension methods + // Use extension methods dispAsset.TrySetMakeModel(defaultDisplay); dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay); } @@ -1271,323 +1337,397 @@ namespace PepperDash.Essentials.Core.Fusion { Debug.Console(1, this, "Error setting up display in Fusion: {0}", e); } - - } + } /// /// Maps room attributes to a display at a specified index /// - /// - /// a + /// + /// + /// + /// a protected virtual void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) { - string displayName = string.Format("Display {0} - ", displayIndex); + var displayName = string.Format("Display {0} - ", displayIndex); - if (display == (Room as IHasDefaultDisplay).DefaultDisplay) + var hasDefaultDisplay = Room as IHasDefaultDisplay; + if (hasDefaultDisplay == null || display != hasDefaultDisplay.DefaultDisplay) { - // Display volume - var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); - defaultDisplayVolume.OutputSig.UserObject = new Action(b => (display as IBasicVolumeWithFeedback).SetVolume(b)); - (display as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig); - - // Power on - var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); - defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOn(); }); - - // Power Off - var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); - defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOff(); }); ; - - - var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback; - if (defaultTwoWayDisplay != null) + return; + } + // Display volume + var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", + eSigIoMask.InputOutputSig); + defaultDisplayVolume.OutputSig.UserObject = new Action(b => + { + var basicVolumeWithFeedback = display as IBasicVolumeWithFeedback; + if (basicVolumeWithFeedback == null) { - defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); - defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig); + return; } - // Current Source - var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); - defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as IRunRouteAction).RunRouteAction("roomOff", Room.SourceListKey); }); ; + basicVolumeWithFeedback.SetVolume(b); + basicVolumeWithFeedback.VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig); + }); + + + // Power on + var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On", + eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => + { + if (!b) + { + display.PowerOn(); + } + }); + + // Power Off + var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1, displayName + "Power Off", + eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => + { + if (!b) + { + display.PowerOff(); + } + }); + + + var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback; + if (defaultTwoWayDisplay != null) + { + defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); + defaultTwoWayDisplay.PowerIsOnFeedback.LinkComplementInputSig(defaultDisplayPowerOff.InputSig); } + + // Current Source + var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8, + displayName + "Source None", eSigIoMask.InputOutputSig); + defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => + { + if (!b) + { + var runRouteAction = Room as IRunRouteAction; + if (runRouteAction != null) + { + runRouteAction.RunRouteAction("roomOff", Room.SourceListKey); + } + } + }); } - void SetUpError() - { - // Roll up ALL device errors - ErrorMessageRollUp = new StatusMonitorCollection(this); - foreach (var dev in DeviceManager.GetDevices()) - { - var md = dev as ICommunicationMonitor; - if (md != null) - { - ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor); - Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key); - } - } - ErrorMessageRollUp.Start(); - FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; - ErrorMessageRollUp.StatusChange += (o, a) => - { - FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; - }; - - } + private void SetUpError() + { + // Roll up ALL device errors + _errorMessageRollUp = new StatusMonitorCollection(this); + foreach (var dev in DeviceManager.GetDevices()) + { + var md = dev as ICommunicationMonitor; + if (md != null) + { + _errorMessageRollUp.AddMonitor(md.CommunicationMonitor); + Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", + md.CommunicationMonitor.Parent.Key); + } + } + _errorMessageRollUp.Start(); + FusionRoom.ErrorMessage.InputSig.StringValue = _errorMessageRollUp.Message; + _errorMessageRollUp.StatusChange += + (o, a) => { FusionRoom.ErrorMessage.InputSig.StringValue = _errorMessageRollUp.Message; }; + } /// /// Sets up a local occupancy sensor, such as one attached to a Fusion Scheduling panel. The occupancy status of the room will be read from Fusion /// - void SetUpLocalOccupancy() + private void SetUpLocalOccupancy() { RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); - FusionRoom.FusionAssetStateChange += new FusionAssetStateEventHandler(FusionRoom_FusionAssetStateChange); + FusionRoom.FusionAssetStateChange += FusionRoom_FusionAssetStateChange; // Build Occupancy Asset? // Link sigs? //Room.SetRoomOccupancy(this as IOccupancyStatusProvider, 0); - - } - void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args) + private void FusionRoom_FusionAssetStateChange(FusionBase device, FusionAssetStateEventArgs args) { - if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId || args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId) + if (args.EventId == FusionAssetEventId.RoomOccupiedReceivedEventId || + args.EventId == FusionAssetEventId.RoomUnoccupiedReceivedEventId) + { RoomIsOccupiedFeedback.FireUpdate(); - + } } /// /// Sets up remote occupancy that will relay the occupancy status determined by local system devices to Fusion /// - void SetUpRemoteOccupancy() - { - + private void SetUpRemoteOccupancy() + { // Need to have the room occupancy object first and somehow determine the slot number of the Occupancy asset but will not be able to use the UID from config likely. // Consider defining an object just for Room Occupancy (either eAssetType.Occupancy Sensor (local) or eAssetType.RemoteOccupancySensor (from Fusion sched. panel)) and reserving slot 4 for that asset (statics would start at 5) //if (Room.OccupancyObj != null) //{ - var tempOccAsset = GUIDs.OccupancyAsset; - - if(tempOccAsset == null) - { - FusionOccSensor = new FusionOccupancySensorAsset(eAssetType.OccupancySensor); - tempOccAsset = FusionOccSensor; - } + var tempOccAsset = _guiDs.OccupancyAsset; - var occSensorAsset = FusionRoom.CreateOccupancySensorAsset(tempOccAsset.SlotNumber, tempOccAsset.Name, "Occupancy Sensor", tempOccAsset.InstanceId); + if (tempOccAsset == null) + { + FusionOccSensor = new FusionOccupancySensorAsset(eAssetType.OccupancySensor); + tempOccAsset = FusionOccSensor; + } - occSensorAsset.RoomOccupied.AddSigToRVIFile = true; + var occSensorAsset = FusionRoom.CreateOccupancySensorAsset(tempOccAsset.SlotNumber, tempOccAsset.Name, + "Occupancy Sensor", tempOccAsset.InstanceId); - var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig); - - // Tie to method on occupancy object - //occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b)); + occSensorAsset.RoomOccupied.AddSigToRVIFile = true; + + //var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig); + + // Tie to method on occupancy object + //occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b)); - RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString); - Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig); - Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange; - RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig); - + RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString); + Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig); + Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange; + RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig); + //} } - void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e) + private void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e) { _roomOccupancyRemoteString = String.Format(RemoteOccupancyXml, e.BoolValue ? "Occupied" : "Unoccupied"); RoomOccupancyRemoteStringFeedback.FireUpdate(); } - /// - /// Helper to get the number from the end of a device's key string - /// - /// -1 if no number matched - int ExtractNumberFromKey(string key) - { + /// + /// Helper to get the number from the end of a device's key string + /// + /// -1 if no number matched + private int ExtractNumberFromKey(string key) + { var capture = System.Text.RegularExpressions.Regex.Match(key, @"\b(\d+)"); - if (!capture.Success) - return -1; - else return Convert.ToInt32(capture.Groups[1].Value); - } + if (!capture.Success) + { + return -1; + } + return Convert.ToInt32(capture.Groups[1].Value); + } - /// - /// Event handler for when room source changes - /// - protected void Room_CurrentSourceInfoChange(SourceListItem info, ChangeType type) - { - // Handle null. Nothing to do when switching from or to null - if (info == null || info.SourceDevice == null) - return; + /// + /// Event handler for when room source changes + /// + protected void Room_CurrentSourceInfoChange(SourceListItem info, ChangeType type) + { + // Handle null. Nothing to do when switching from or to null + if (info == null || info.SourceDevice == null) + { + return; + } - var dev = info.SourceDevice; - if (type == ChangeType.WillChange) - { - if (SourceToFeedbackSigs.ContainsKey(dev)) - SourceToFeedbackSigs[dev].BoolValue = false; - } - else - { - if (SourceToFeedbackSigs.ContainsKey(dev)) - SourceToFeedbackSigs[dev].BoolValue = true; + var dev = info.SourceDevice; + if (type == ChangeType.WillChange) + { + if (_sourceToFeedbackSigs.ContainsKey(dev)) + { + _sourceToFeedbackSigs[dev].BoolValue = false; + } + } + else + { + if (_sourceToFeedbackSigs.ContainsKey(dev)) + { + _sourceToFeedbackSigs[dev].BoolValue = true; + } //var name = (room == null ? "" : room.Name); - CurrentRoomSourceNameSig.InputSig.StringValue = info.SourceDevice.Name; - } - } + CurrentRoomSourceNameSig.InputSig.StringValue = info.SourceDevice.Name; + } + } - protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) - { + protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) + { + // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors, + // even though they all contain sigs. - // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors, - // even though they all contain sigs. + var sigData = args.UserConfiguredSigDetail as BooleanSigDataFixedName; - var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName); - if (sigData != null) - { - var outSig = sigData.OutputSig; - if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.BoolValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.UShortValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.StringValue); - return; - } + BoolOutputSig outSig; + if (sigData != null) + { + outSig = sigData.OutputSig; + if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.BoolValue); + } + else if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.UShortValue); + } + else if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.StringValue); + } + return; + } - var attrData = (args.UserConfiguredSigDetail as BooleanSigData); - if (attrData != null) - { - var outSig = attrData.OutputSig; - if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.BoolValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.UShortValue); - else if (outSig.UserObject is Action) - (outSig.UserObject as Action).Invoke(outSig.StringValue); - return; - } - - } - } + var attrData = (args.UserConfiguredSigDetail as BooleanSigData); + if (attrData == null) + { + return; + } + outSig = attrData.OutputSig; + if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.BoolValue); + } + else if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.UShortValue); + } + else if (outSig.UserObject is Action) + { + (outSig.UserObject as Action).Invoke(outSig.StringValue); + } + } + } - public static class FusionRoomExtensions - { - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.Bool, number, name, mask); - return fr.UserDefinedBooleanSigDetails[number]; - } + public static class FusionRoomExtensions + { + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) + { + throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + } + number -= 49; + fr.AddSig(eSigType.Bool, number, name, mask); + return fr.UserDefinedBooleanSigDetails[number]; + } - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.UShort, number, name, mask); - return fr.UserDefinedUShortSigDetails[number]; - } + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) + { + throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + } + number -= 49; + fr.AddSig(eSigType.UShort, number, name, mask); + return fr.UserDefinedUShortSigDetails[number]; + } - /// - /// Creates and returns a fusion attribute. The join number will match the established Simpl - /// standard of 50+, and will generate a 50+ join in the RVI. It calls - /// FusionRoom.AddSig with join number - 49 - /// - /// The new attribute - public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) - { - if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); - number -= 49; - fr.AddSig(eSigType.String, number, name, mask); - return fr.UserDefinedStringSigDetails[number]; - } + /// + /// Creates and returns a fusion attribute. The join number will match the established Simpl + /// standard of 50+, and will generate a 50+ join in the RVI. It calls + /// FusionRoom.AddSig with join number - 49 + /// + /// The new attribute + public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask) + { + if (number < 50) + { + throw new ArgumentOutOfRangeException("number", "Cannot be less than 50"); + } + number -= 49; + fr.AddSig(eSigType.String, number, name, mask); + return fr.UserDefinedStringSigDetails[number]; + } - /// - /// Creates and returns a static asset - /// - /// the new asset - public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) - { + /// + /// Creates and returns a static asset + /// + /// the new asset + public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, + string instanceId) + { Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId); - fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); - return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; - } + fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); + return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; + } - public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) + public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name, + string type, string instanceId) { - Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId); + Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number, + instanceId); fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId); return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor; } - } + } - //************************************************************************************************ - /// - /// Extensions to enhance Fusion room, asset and signal creation. - /// - public static class FusionStaticAssetExtensions - { - /// - /// Tries to set a Fusion asset with the make and model of a device. - /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset. - /// Otherwise, does nothing. - /// - public static void TrySetMakeModel(this FusionStaticAsset asset, Device device) - { - var mm = device as IMakeModel; - if (mm != null) - { - asset.ParamMake.Value = mm.DeviceMake; - asset.ParamModel.Value = mm.DeviceModel; - } - } + //************************************************************************************************ + /// + /// Extensions to enhance Fusion room, asset and signal creation. + /// + public static class FusionStaticAssetExtensions + { + /// + /// Tries to set a Fusion asset with the make and model of a device. + /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset. + /// Otherwise, does nothing. + /// + public static void TrySetMakeModel(this FusionStaticAsset asset, Device device) + { + var mm = device as IMakeModel; + if (mm != null) + { + asset.ParamMake.Value = mm.DeviceMake; + asset.ParamModel.Value = mm.DeviceModel; + } + } - /// - /// Tries to attach the AssetError input on a Fusion asset to a Device's - /// CommunicationMonitor.StatusChange event. Does nothing if the device is not - /// IStatusMonitor - /// - /// - /// - public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device) - { - if (device is ICommunicationMonitor) - { - var monitor = (device as ICommunicationMonitor).CommunicationMonitor; - monitor.StatusChange += (o, a) => - { - // Link connected and error inputs on asset - asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; - asset.AssetError.InputSig.StringValue = a.Status.ToString(); - }; - // set current value - asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk; - asset.AssetError.InputSig.StringValue = monitor.Status.ToString(); - } - } - } + /// + /// Tries to attach the AssetError input on a Fusion asset to a Device's + /// CommunicationMonitor.StatusChange event. Does nothing if the device is not + /// IStatusMonitor + /// + /// + /// + public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device) + { + if (device is ICommunicationMonitor) + { + var monitor = (device as ICommunicationMonitor).CommunicationMonitor; + monitor.StatusChange += (o, a) => + { + // Link connected and error inputs on asset + asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; + asset.AssetError.InputSig.StringValue = a.Status.ToString(); + }; + // set current value + asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk; + asset.AssetError.InputSig.StringValue = monitor.Status.ToString(); + } + } + } public class RoomInformation { + public RoomInformation() + { + FusionCustomProperties = new List(); + } + public string ID { get; set; } public string Name { get; set; } public string Location { get; set; } @@ -1598,27 +1738,22 @@ namespace PepperDash.Essentials.Core.Fusion public string SubErrorMsg { get; set; } public string EmailInfo { get; set; } public List FusionCustomProperties { get; set; } - - public RoomInformation() - { - FusionCustomProperties = new List(); - } } + public class FusionCustomProperty { - public string ID { get; set; } - public string CustomFieldName { get; set; } - public string CustomFieldType { get; set; } - public string CustomFieldValue { get; set; } - public FusionCustomProperty() { - } public FusionCustomProperty(string id) { ID = id; } + + public string ID { get; set; } + public string CustomFieldName { get; set; } + public string CustomFieldType { get; set; } + public string CustomFieldValue { get; set; } } } \ No newline at end of file From 9c4650b4afd573ae05ae4fa85bf9f59b8b4c1f6d Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 16:32:06 -0700 Subject: [PATCH 019/480] fixes to get it to load --- .../Room/Config/EssentialsRoomConfig.cs | 4 +-- .../Room/Config/EssentialsTechRoomConfig.cs | 17 +++++++++-- .../Room/Types/EssentialsTechRoom.cs | 28 +++++++++---------- .../Global/Scheduler.cs | 8 ++++-- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 3aee1e20..79844ce4 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Room.Config { return new EssentialsHuddleVtc1Room(roomConfig); } - if (typeName == "ddvc01Bridge") + if (typeName == "ddvc01bridge") { return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing. } @@ -40,7 +40,7 @@ namespace PepperDash.Essentials.Room.Config return new EssentialsDualDisplayRoom(roomConfig); } - return typeName != "techRoom" ? null : new EssentialsTechRoom(roomConfig); + return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig); } /// diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index e4b88e96..ccf9ec6d 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -1,22 +1,33 @@ using System.Collections.Generic; +using Newtonsoft.Json; namespace PepperDash.Essentials.Room.Config { public class EssentialsTechRoomConfig { + [JsonProperty("displays")] public List Displays; + + [JsonProperty("tuners")] public List Tuners; - public string ScheduleProviderKey; + + [JsonProperty("userPin")] public string UserPin; + + [JsonProperty("techPin")] public string TechPin; + + [JsonProperty("presetFileName")] public string PresetsFileName; - public List RoomScheduledEvents; + + [JsonProperty("scheduledEvents")] + public List ScheduledEvents; public EssentialsTechRoomConfig() { Displays = new List(); Tuners = new List(); - RoomScheduledEvents = new List(); + ScheduledEvents = new List(); } } } \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index cb8ebfa1..c7f474eb 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -74,7 +74,7 @@ namespace PepperDash.Essentials private void CreateOrUpdateScheduledEvents() { - var eventsConfig = _config.RoomScheduledEvents; + var eventsConfig = _config.ScheduledEvents; GetOrCreateScheduleGroup(); @@ -127,11 +127,11 @@ namespace PepperDash.Essentials { //update config based on key of scheduleEvent GetOrCreateScheduleGroup(); - var existingEvent = _config.RoomScheduledEvents.FirstOrDefault(e => e.Key == scheduledEvent.Key); + var existingEvent = _config.ScheduledEvents.FirstOrDefault(e => e.Key == scheduledEvent.Key); if (existingEvent == null) { - _config.RoomScheduledEvents.Add(scheduledEvent); + _config.ScheduledEvents.Add(scheduledEvent); } //create or update event based on config @@ -144,7 +144,7 @@ namespace PepperDash.Essentials OnScheduledEventUpdate(); } - public void OnScheduledEventUpdate() + private void OnScheduledEventUpdate() { var handler = ScheduledEventsChanged; @@ -153,14 +153,14 @@ namespace PepperDash.Essentials return; } - handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.RoomScheduledEvents}); + handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents}); } public event EventHandler ScheduledEventsChanged; private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type) { - var eventConfig = _config.RoomScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name); + var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name); if (eventConfig == null) { @@ -221,42 +221,42 @@ namespace PepperDash.Essentials protected override Func IsWarmingFeedbackFunc { - get { throw new NotImplementedException(); } + get { return () => false; } } protected override Func IsCoolingFeedbackFunc { - get { throw new NotImplementedException(); } + get { return () => false; } } protected override Func OnFeedbackFunc { - get { throw new NotImplementedException(); } + get { return () => RoomPowerIsOn; } } protected override void EndShutdown() { - throw new NotImplementedException(); + } public override void SetDefaultLevels() { - throw new NotImplementedException(); + } public override void PowerOnToDefaultOrLastSource() { - throw new NotImplementedException(); + } public override bool RunDefaultPresentRoute() { - throw new NotImplementedException(); + return false; } public override void RoomVacatedForTimeoutPeriod(object o) { - throw new NotImplementedException(); + } #endregion diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 64ba57df..6544f1f4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -175,13 +175,15 @@ namespace PepperDash.Essentials.Core scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); - scheduledEvent.Recurrence.Weekly(config.Days); - var eventTime = DateTime.Parse(config.Time); - if (DateTime.Now < eventTime) eventTime.AddDays(1); + if (DateTime.Now > eventTime) eventTime = eventTime.AddDays(1); scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); + + scheduledEvent.Recurrence.Weekly(config.Days); + + } } } \ No newline at end of file From c4755f23cd7a80e70e749e184ca07e1d640a5860 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 16:58:33 -0700 Subject: [PATCH 020/480] added logic to subscribe to scheduled event --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 6 +++++- .../PepperDashEssentialsBase/Global/Scheduler.cs | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index c7f474eb..f6fe1b39 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -120,7 +120,9 @@ namespace PepperDash.Essentials _roomScheduledEventGroup.DeleteEvent(roomEvent); - SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); + var tempEvent = SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); + + tempEvent.UserCallBack += HandleScheduledEvent; } public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent) @@ -168,6 +170,8 @@ namespace PepperDash.Essentials return; } + Debug.Console(1, this, "Running actions for event {0}", schevent.Name); + if (eventConfig.Acknowledgeable) { schevent.Acknowledge(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 6544f1f4..9f27a15c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -151,12 +151,12 @@ namespace PepperDash.Essentials.Core return evnt.Recurrence.RecurrenceDays == days; } - public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group) + public static ScheduledEvent CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group) { if (group == null) { Debug.Console(0, "Unable to create event. Group is null"); - return; + return null; } var scheduledEvent = new ScheduledEvent(config.Key, group) { @@ -183,7 +183,7 @@ namespace PepperDash.Essentials.Core scheduledEvent.Recurrence.Weekly(config.Days); - + return scheduledEvent; } } } \ No newline at end of file From 099e387570ff9be4efef9029c1736728c0927c3f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 7 Dec 2020 17:21:05 -0700 Subject: [PATCH 021/480] getting things in the right order for scheduling --- .../Room/Types/EssentialsTechRoom.cs | 6 ++--- .../Global/Scheduler.cs | 22 +++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index f6fe1b39..b9edbb70 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -102,7 +102,7 @@ namespace PepperDash.Essentials { if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Name)) { - SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); + SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent); return; } @@ -120,9 +120,7 @@ namespace PepperDash.Essentials _roomScheduledEventGroup.DeleteEvent(roomEvent); - var tempEvent = SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup); - - tempEvent.UserCallBack += HandleScheduledEvent; + SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent); } public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 9f27a15c..11232896 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -151,12 +151,12 @@ namespace PepperDash.Essentials.Core return evnt.Recurrence.RecurrenceDays == days; } - public static ScheduledEvent CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group) + public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler) { if (group == null) { Debug.Console(0, "Unable to create event. Group is null"); - return null; + return; } var scheduledEvent = new ScheduledEvent(config.Key, group) { @@ -164,14 +164,7 @@ namespace PepperDash.Essentials.Core Persistent = config.Persistent }; - if (config.Enable) - { - scheduledEvent.Resume(); - } - else - { - scheduledEvent.Pause(); - } + scheduledEvent.UserCallBack += handler; scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday); @@ -183,7 +176,14 @@ namespace PepperDash.Essentials.Core scheduledEvent.Recurrence.Weekly(config.Days); - return scheduledEvent; + if (config.Enable) + { + scheduledEvent.Enable(); + } + else + { + scheduledEvent.Disable(); + } } } } \ No newline at end of file From 2eaf21b1e0790178fb425de114a57fd198e79770 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 08:01:01 -0700 Subject: [PATCH 022/480] Fix event retrieval --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index b9edbb70..da362173 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -100,7 +100,7 @@ namespace PepperDash.Essentials private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent) { - if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Name)) + if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key)) { SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent); return; From 2c36c0f2cbe87c893045268520f6c54a5a1491d8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 08:01:25 -0700 Subject: [PATCH 023/480] Run `GoWithLoad` command in separate thread when using donotloadonnextboot --- PepperDashEssentials/ControlSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 4e24de9f..58a545f2 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -53,7 +53,7 @@ namespace PepperDash.Essentials if (Debug.DoNotLoadOnNextBoot) { - CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file", + CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file", ConsoleAccessLevelEnum.AccessOperator); } From a78b29b0a12087bb0c311db5abe09a35e0349654 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 08:01:58 -0700 Subject: [PATCH 024/480] #523 Add NullCheck and Debug message for com Port --- .../PepperDashEssentialsBase/Comm and IR/ComPortController.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs index ddb578d7..8d2f2db1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs @@ -56,6 +56,10 @@ namespace PepperDash.Essentials.Core private void RegisterAndConfigureComPort() { + if (Port == null) + { + Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist."); + } if (Port.Parent is CrestronControlSystem) { var result = Port.Register(); From 4d67279827f0d436d177a8a850af4650aaf893b8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 08:02:35 -0700 Subject: [PATCH 025/480] Log message to error log when configured com port doesn't exist --- .../PepperDashEssentialsBase/Comm and IR/CommFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a8fa67e4..8a5efe47 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs @@ -104,7 +104,7 @@ namespace PepperDash.Essentials.Core var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey); if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts) return dev.ComPorts[config.ControlPortNumber]; - Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber); + Debug.Console(0,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber); return null; } From d990930b19565eac741169b2f6b60f6ba4a95879 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 11:05:52 -0700 Subject: [PATCH 026/480] #523 Add return statement --- .../PepperDashEssentialsBase/Comm and IR/ComPortController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs index 8d2f2db1..75e9ae72 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs @@ -59,6 +59,7 @@ namespace PepperDash.Essentials.Core if (Port == null) { Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist."); + return; } if (Port.Parent is CrestronControlSystem) { From 8feb7a142c2863424e9cd8f61cba05aff42ae0e7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 11:06:06 -0700 Subject: [PATCH 027/480] #524 Fix Fusion Printing --- .../Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 9270ed37..dcc86635 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -276,7 +276,7 @@ namespace PepperDash.Essentials.Core.Fusion Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Fusion Guids successfully read from file: {0}", filePath); - Debug.Console(1, this, "\nRoom Name: {0}\nIPID: {1:x}\n RoomGuid: {2}", Room.Name, _ipId, RoomGuid); + Debug.Console(1, this, "\r\n********************\r\n\tRoom Name: {0}\r\n\tIPID: {1:X}\r\n\tRoomGuid: {2}\r\n*******************", Room.Name, _ipId, RoomGuid); foreach (var item in FusionStaticAssets) { From 9204ad2701268fb3f5d40a7331fe69be9170c833 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 12:48:26 -0700 Subject: [PATCH 028/480] #525 Add Rooms Array & LinkToRooms method --- .../Bridges/BridgeBase.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 151b5461..443a720e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -131,6 +131,16 @@ namespace PepperDash.Essentials.Core.Bridges } } + RegisterEisc(); + } + + private void RegisterEisc() + { + if (Eisc.Registered) + { + return; + } + var registerResult = Eisc.Register(); if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success) @@ -142,6 +152,27 @@ namespace PepperDash.Essentials.Core.Bridges Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful"); } + public void LinkToRooms() + { + Debug.Console(1, this, "Linking Rooms..."); + + foreach (var room in PropertiesConfig.Rooms) + { + var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced; + + if (rm == null) + { + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, + "Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey); + continue; + } + + rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this); + } + + RegisterEisc(); + } + /// /// Adds a join map /// @@ -290,6 +321,9 @@ namespace PepperDash.Essentials.Core.Bridges [JsonProperty("devices")] public List Devices { get; set; } + [JsonProperty("rooms")] + public List Rooms { get; set; } + public class ApiDevicePropertiesConfig { @@ -303,6 +337,18 @@ namespace PepperDash.Essentials.Core.Bridges public string JoinMapKey { get; set; } } + public class ApiRoomPropertiesConfig + { + [JsonProperty("roomKey")] + public string RoomKey { get; set; } + + [JsonProperty("joinStart")] + public uint JoinStart { get; set; } + + [JsonProperty("joinMapKey")] + public string JoinMapKey { get; set; } + } + } public class EiscApiAdvancedFactory : EssentialsDeviceFactory From 2e636082bb016bebb165ec55d8f58f464e17170c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 12:50:55 -0700 Subject: [PATCH 029/480] #526 Add ITvPresetsProvider interface --- .../DeviceTypeInterfaces/ITvPresetsProvider.cs | 9 +++++++++ .../PepperDash_Essentials_Core.csproj | 1 + 2 files changed, 10 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs new file mode 100644 index 00000000..61b8ec09 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ITvPresetsProvider.cs @@ -0,0 +1,9 @@ +using PepperDash.Essentials.Core.Presets; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + public interface ITvPresetsProvider + { + DevicePresetsModel TvPresets { get; } + } +} \ 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 1a2fc594..49f4b25a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -199,6 +199,7 @@ + From 748b1ca14767f92677c9c92d40fd61592f882c0b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 12:51:20 -0700 Subject: [PATCH 030/480] Add config properties Implement ITvPresetsProvider --- PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs | 4 ++++ PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index ccf9ec6d..7b470574 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -23,6 +23,10 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("scheduledEvents")] public List ScheduledEvents; + [JsonProperty("isPrimary")] public bool IsPrimary; + + [JsonProperty("isTvPresetsProvider")] public bool IsTvPresetsProvider; + public EssentialsTechRoomConfig() { Displays = new List(); diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index da362173..e639a4a0 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -7,13 +7,14 @@ using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Devices.Common; using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials { - public class EssentialsTechRoom : EssentialsRoomBase + public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider { private readonly EssentialsTechRoomConfig _config; private readonly Dictionary _displays; @@ -41,7 +42,7 @@ namespace PepperDash.Essentials CreateOrUpdateScheduledEvents(); } - public DevicePresetsModel TunerPresets + public DevicePresetsModel TvPresets { get { return _tunerPresets; } } From 169e89774853612a367d7b58749a8baf0d45e5dd Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 12:54:35 -0700 Subject: [PATCH 031/480] Add CriticalSection for file ops --- .../Presets/DevicePresets.cs | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index ccce6ea7..84b3cbd3 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -15,6 +15,7 @@ namespace PepperDash.Essentials.Core.Presets /// public class DevicePresetsModel : Device { + private CCriticalSection _fileOps = new CCriticalSection(); private readonly bool _initSuccess; /// @@ -101,27 +102,35 @@ namespace PepperDash.Essentials.Core.Presets public void LoadChannels() { - PresetsAreLoaded = false; try { - var pl = JsonConvert.DeserializeObject(File.ReadToEnd(_filePath, Encoding.ASCII)); - Name = pl.Name; - PresetsList = pl.Channels; - } - catch (Exception e) - { - Debug.Console(2, this, - "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", - _filePath, e.Message); - // Just save a default empty list - PresetsList = new List(); - } - PresetsAreLoaded = true; + _fileOps.Enter(); + PresetsAreLoaded = false; + try + { + var pl = JsonConvert.DeserializeObject(File.ReadToEnd(_filePath, Encoding.ASCII)); + Name = pl.Name; + PresetsList = pl.Channels; + } + catch (Exception e) + { + Debug.Console(2, this, + "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", + _filePath, e.Message); + // Just save a default empty list + PresetsList = new List(); + } + PresetsAreLoaded = true; - var handler = PresetsLoaded; - if (handler != null) + var handler = PresetsLoaded; + if (handler != null) + { + handler(this, EventArgs.Empty); + } + } + finally { - handler(this, EventArgs.Empty); + _fileOps.Leave(); } } @@ -209,12 +218,21 @@ namespace PepperDash.Essentials.Core.Presets private void SavePresets() { - var json = JsonConvert.SerializeObject(PresetsList); - - using (var file = File.Open(_filePath, FileMode.Truncate)) + try { - file.Write(json, Encoding.UTF8); + _fileOps.Enter(); + var json = JsonConvert.SerializeObject(PresetsList); + + using (var file = File.Open(_filePath, FileMode.Truncate)) + { + file.Write(json, Encoding.UTF8); + } } + finally + { + _fileOps.Leave(); + } + } private void Pulse(Action act) From 56cf54a6443b521c3e3b6be7b26db51eb289a9e1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 16:24:03 -0700 Subject: [PATCH 032/480] Added LinkRooms as a PostActivationAction --- .../Bridges/BridgeBase.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 443a720e..86db81ba 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -99,12 +99,19 @@ namespace PepperDash.Essentials.Core.Bridges Eisc.SigChange += Eisc_SigChange; AddPostActivationAction(LinkDevices); + AddPostActivationAction(LinkRooms); } private void LinkDevices() { Debug.Console(1, this, "Linking Devices..."); + if (PropertiesConfig.Devices == null) + { + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No devices linked to this bridge"); + return; + } + foreach (var d in PropertiesConfig.Devices) { var device = DeviceManager.GetDeviceForKey(d.DeviceKey); @@ -152,10 +159,16 @@ namespace PepperDash.Essentials.Core.Bridges Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful"); } - public void LinkToRooms() + public void LinkRooms() { Debug.Console(1, this, "Linking Rooms..."); + if (PropertiesConfig.Rooms == null) + { + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No rooms linked to this bridge."); + return; + } + foreach (var room in PropertiesConfig.Rooms) { var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced; From b09c1517385cd270b07eca21658810f304debd90 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 16:24:22 -0700 Subject: [PATCH 033/480] Added logic to send presets to far end --- .../DeviceTypeInterfaces/INumeric.cs | 4 +-- .../Presets/DevicePresets.cs | 29 ++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs index 0294a0b5..62ea8b3f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/INumeric.cs @@ -1,5 +1,5 @@ using Crestron.SimplSharpPro.DeviceSupport; - +using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.SmartObjects; @@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core /// /// /// - public interface INumericKeypad + public interface INumericKeypad:IKeyed { void Digit0(bool pressRelease); void Digit1(bool pressRelease); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 84b3cbd3..55522cf0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using PepperDash.Core; //using SSMono.IO; +using PepperDash.Core.WebApi.Presets; namespace PepperDash.Essentials.Core.Presets { @@ -15,9 +16,13 @@ namespace PepperDash.Essentials.Core.Presets /// public class DevicePresetsModel : Device { - private CCriticalSection _fileOps = new CCriticalSection(); + public delegate void PresetChangedCallback(ISetTopBoxNumericKeypad device, string channel); + + private readonly CCriticalSection _fileOps = new CCriticalSection(); private readonly bool _initSuccess; + private ISetTopBoxNumericKeypad _setTopBox; + /// /// The methods on the STB device to call when dialing /// @@ -32,6 +37,8 @@ namespace PepperDash.Essentials.Core.Presets { try { + _setTopBox = setTopBox; + // Grab the digit functions from the device // If any fail, the whole thing fails peacefully _dialFunctions = new Dictionary>(10) @@ -76,6 +83,8 @@ namespace PepperDash.Essentials.Core.Presets _initSuccess = true; } + public event PresetChangedCallback PresetChanged; + public int PulseTime { get; set; } public int DigitSpacingMs { get; set; } public bool PresetsAreLoaded { get; private set; } @@ -172,6 +181,10 @@ namespace PepperDash.Essentials.Core.Presets } _dialIsRunning = false; }); + + if (_setTopBox == null) return; + + OnPresetChanged(_setTopBox, chanNum); } public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox) @@ -201,9 +214,23 @@ namespace PepperDash.Essentials.Core.Presets _enterFunction = setTopBox.KeypadEnter; + OnPresetChanged(setTopBox, chanNum); + Dial(chanNum); } + private void OnPresetChanged(ISetTopBoxNumericKeypad setTopBox, string channel) + { + var handler = PresetChanged; + + if (handler == null) + { + return; + } + + handler(setTopBox, channel); + } + public void UpdatePreset(int index, PresetChannel preset) { if (index >= PresetsList.Count) From 7e8f216afb77cbfa393901e47948723cf2884267 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 16:24:35 -0700 Subject: [PATCH 034/480] added logic to send presets to far end --- .../Room/Types/EssentialsTechRoom.cs | 119 ++++++++++++++++-- 1 file changed, 110 insertions(+), 9 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index e639a4a0..74eaac6a 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -3,9 +3,12 @@ using System.Collections.Generic; using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.Scheduler; +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Presets; @@ -14,7 +17,7 @@ using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials { - public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider + public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced { private readonly EssentialsTechRoomConfig _config; private readonly Dictionary _displays; @@ -22,6 +25,7 @@ namespace PepperDash.Essentials private readonly DevicePresetsModel _tunerPresets; private readonly Dictionary _tuners; + private Dictionary _currentPresets; private ScheduledEventGroup _roomScheduledEventGroup; public EssentialsTechRoom(DeviceConfig config) : base(config) @@ -32,20 +36,21 @@ namespace PepperDash.Essentials _tunerPresets.LoadChannels(); + _tunerPresets.PresetChanged += TunerPresetsOnPresetChanged; + _tuners = GetDevices(_config.Tuners); _displays = GetDevices(_config.Displays); RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn); + SetUpTunerPresetsFeedback(); + SubscribeToDisplayFeedbacks(); CreateOrUpdateScheduledEvents(); } - public DevicePresetsModel TvPresets - { - get { return _tunerPresets; } - } + public Dictionary CurrentPresetsFeedbacks { get; private set; } public Dictionary Tuners { @@ -64,6 +69,43 @@ namespace PepperDash.Essentials get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); } } + #region ITvPresetsProvider Members + + public DevicePresetsModel TvPresets + { + get { return _tunerPresets; } + } + + #endregion + + private void TunerPresetsOnPresetChanged(ISetTopBoxNumericKeypad device, string channel) + { + if (!_currentPresets.ContainsKey(device.Key)) + { + return; + } + + _currentPresets[device.Key] = channel; + + if (!CurrentPresetsFeedbacks.ContainsKey(device.Key)) + { + CurrentPresetsFeedbacks[device.Key].FireUpdate(); + } + } + + private void SetUpTunerPresetsFeedback() + { + _currentPresets = new Dictionary(); + CurrentPresetsFeedbacks = new Dictionary(); + + foreach (var setTopBox in _tuners) + { + var tuner = setTopBox.Value; + _currentPresets.Add(tuner.Key, String.Empty); + CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key])); + } + } + private void SubscribeToDisplayFeedbacks() { foreach (var display in _displays) @@ -239,17 +281,14 @@ namespace PepperDash.Essentials protected override void EndShutdown() { - } public override void SetDefaultLevels() { - } public override void PowerOnToDefaultOrLastSource() { - } public override bool RunDefaultPresentRoute() @@ -259,10 +298,72 @@ namespace PepperDash.Essentials public override void RoomVacatedForTimeoutPeriod(object o) { - } #endregion + + #region Implementation of IBridgeAdvanced + + public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + + var joinMap = new EssentialsTechRoomJoinMap(joinStart); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!String.IsNullOrEmpty(joinMapSerialized)) + { + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + uint i; + if (_config.IsPrimary) + { + i = 0; + foreach (var feedback in CurrentPresetsFeedbacks) + { + feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]); + i++; + } + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) + { + return; + } + + foreach (var feedback in CurrentPresetsFeedbacks) + { + feedback.Value.FireUpdate(); + } + }; + } + + i = 0; + foreach (var setTopBox in _tuners) + { + var tuner = setTopBox; + + trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + } + } + + #endregion + + private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced + { + [JoinName("currentPreset")] + public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16}, + new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial}); + + public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap)) + { + } + } } public class ScheduledEventEventArgs : EventArgs From 6e4fa48b9d1b16dd8e5bdb2698f9c5da80c9665e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Dec 2020 16:34:00 -0700 Subject: [PATCH 035/480] rearrange message formatting --- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index f0a7aeeb..01da1c54 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -410,7 +410,7 @@ namespace PepperDash.Essentials if (!passed) { Debug.Console(0, Debug.ErrorLogLevel.Error, - "**********\r\nPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n**********", + "\r\n********************\r\n\tPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n********************", plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name); return; } From 3e5685994341174ecd36d48e256e8594a9863316 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 9 Dec 2020 15:14:52 -0700 Subject: [PATCH 036/480] add UpdatePresets method --- .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 55522cf0..85e3038e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -243,6 +243,13 @@ namespace PepperDash.Essentials.Core.Presets SavePresets(); } + public void UpdatePresets(List presets) + { + PresetsList = presets; + + SavePresets(); + } + private void SavePresets() { try From f8ae6264f7e5bc1d62fa9a89242a93422c4d6c77 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 9 Dec 2020 16:18:21 -0700 Subject: [PATCH 037/480] add some debug statements and fix presets file loading --- PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs | 2 +- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 +- .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 7b470574..292a6b7c 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("techPin")] public string TechPin; - [JsonProperty("presetFileName")] + [JsonProperty("presetsFileName")] public string PresetsFileName; [JsonProperty("scheduledEvents")] diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 74eaac6a..c90e9414 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -34,7 +34,7 @@ namespace PepperDash.Essentials _tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName); - _tunerPresets.LoadChannels(); + _tunerPresets.SetFileName(_config.PresetsFileName); _tunerPresets.PresetChanged += TunerPresetsOnPresetChanged; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 85e3038e..6fb228a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -106,6 +106,8 @@ namespace PepperDash.Essentials.Core.Presets public void SetFileName(string path) { _filePath = ListPathPrefix + path; + + Debug.Console(2, this, "Setting presets file path to {0}", _filePath); LoadChannels(); } @@ -114,6 +116,8 @@ namespace PepperDash.Essentials.Core.Presets try { _fileOps.Enter(); + + Debug.Console(2, this, "Loading presets from {0}", _filePath); PresetsAreLoaded = false; try { From 1ee87c0499964a2f1bb9034afe4358e8328a0084 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 9 Dec 2020 16:37:14 -0700 Subject: [PATCH 038/480] add some debug statements and fix presets file loading --- .../Presets/PresetChannel.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs index b9650e60..259ccbb9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/PresetChannel.cs @@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core.Presets public class PresetChannel { - [JsonProperty(Required = Required.Always)] + [JsonProperty(Required = Required.Always,PropertyName = "name")] public string Name { get; set; } - [JsonProperty(Required = Required.Always)] + + [JsonProperty(Required = Required.Always, PropertyName = "iconUrl")] public string IconUrl { get; set; } - [JsonProperty(Required = Required.Always)] + + [JsonProperty(Required = Required.Always, PropertyName = "channel")] public string Channel { get; set; } } public class PresetsList { - [JsonProperty(Required=Required.Always)] + [JsonProperty(Required=Required.Always,PropertyName = "name")] public string Name { get; set; } - [JsonProperty(Required = Required.Always)] + + [JsonProperty(Required = Required.Always, PropertyName = "channels")] public List Channels { get; set; } } } \ No newline at end of file From 01ddf1721ca8a944a7106978197b1d1d17241caa Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 11 Dec 2020 15:42:38 -0700 Subject: [PATCH 039/480] add method to get scheduled events --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 5 +++++ .../PepperDashEssentialsBase/Global/Scheduler.cs | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index c90e9414..3dc45c3a 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -187,6 +187,11 @@ namespace PepperDash.Essentials OnScheduledEventUpdate(); } + public List GetScheduledEvents() + { + return _config.ScheduledEvents ?? new List(); + } + private void OnScheduledEventUpdate() { var handler = ScheduledEventsChanged; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 11232896..192f7dd0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -170,7 +170,15 @@ namespace PepperDash.Essentials.Core var eventTime = DateTime.Parse(config.Time); - if (DateTime.Now > eventTime) eventTime = eventTime.AddDays(1); + if (DateTime.Now > eventTime) + { + eventTime = eventTime.AddDays(1); + } + + while (!config.Days.ToString().ToLower().Contains(eventTime.DayOfWeek.ToString().ToLower())) + { + eventTime = eventTime.AddDays(1); + } scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); From eb114b4a951d25a16906c61efdbe6914c0c44844 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 15 Dec 2020 08:44:10 -0700 Subject: [PATCH 040/480] make Days enum serialize to string --- .../Room/Config/EssentialsRoomScheduledEventsConfig.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs index 366f453c..88ac7db9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Crestron.SimplSharp.Scheduler; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Room.Config @@ -20,6 +21,7 @@ namespace PepperDash.Essentials.Room.Config public string Name; [JsonProperty("days")] + [JsonConverter(typeof(StringEnumConverter))] public ScheduledEventCommon.eWeekDays Days; [JsonProperty("time")] From a4a99f4a9b045f5660a7931ec32be2d906f03828 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 15 Dec 2020 09:47:08 -0700 Subject: [PATCH 041/480] remove JsonConverter Attribute --- .../Room/Config/EssentialsRoomScheduledEventsConfig.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs index 88ac7db9..cd0c2586 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Config/EssentialsRoomScheduledEventsConfig.cs @@ -21,7 +21,6 @@ namespace PepperDash.Essentials.Room.Config public string Name; [JsonProperty("days")] - [JsonConverter(typeof(StringEnumConverter))] public ScheduledEventCommon.eWeekDays Days; [JsonProperty("time")] From d2c308c0092f1c9f735037a8ba2704de0f9c86e2 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 15 Dec 2020 09:47:35 -0700 Subject: [PATCH 042/480] Add methods & logic to make sure... ...day & time is in the list of recurrence days --- .../Global/Scheduler.cs | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 192f7dd0..fb305172 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -1,10 +1,14 @@ using System; using System.Collections.Generic; +using System.Linq; using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Scheduler; using PepperDash.Core; +using PepperDash.Essentials.Core.Fusion; using PepperDash.Essentials.Room.Config; +using Activator = System.Activator; namespace PepperDash.Essentials.Core { @@ -175,9 +179,18 @@ namespace PepperDash.Essentials.Core eventTime = eventTime.AddDays(1); } - while (!config.Days.ToString().ToLower().Contains(eventTime.DayOfWeek.ToString().ToLower())) + Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek, + config.Days); + + var dayOfWeekConverted = ConvertDayOfWeek(eventTime); + + Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted); + + while (!dayOfWeekConverted.IsFlagSet(config.Days)) { eventTime = eventTime.AddDays(1); + + dayOfWeekConverted = ConvertDayOfWeek(eventTime); } scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime); @@ -193,5 +206,28 @@ namespace PepperDash.Essentials.Core scheduledEvent.Disable(); } } + + private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime) + { + return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true); + } + + private static bool IsFlagSet(this T value, T flag) where T : struct + { + CheckIsEnum(true); + + var lValue = Convert.ToInt64(value); + var lFlag = Convert.ToInt64(flag); + + return (lValue & lFlag) != 0; + } + + private static void CheckIsEnum(bool withFlags) + { + if (!typeof(T).IsEnum) + throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName)); + if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute))) + throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName)); + } } } \ No newline at end of file From 91eec8c258cc7f1446676e8719e1594f375449e9 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 15 Dec 2020 16:43:09 -0700 Subject: [PATCH 043/480] fix scheduled event saving --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 3dc45c3a..acd44710 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -170,12 +170,16 @@ namespace PepperDash.Essentials { //update config based on key of scheduleEvent GetOrCreateScheduleGroup(); - var existingEvent = _config.ScheduledEvents.FirstOrDefault(e => e.Key == scheduledEvent.Key); + var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key); - if (existingEvent == null) + if (existingEventIndex < 0) { _config.ScheduledEvents.Add(scheduledEvent); } + else + { + _config.ScheduledEvents[existingEventIndex] = scheduledEvent; + } //create or update event based on config CreateOrUpdateSingleEvent(scheduledEvent); From 1cad1976eedb719fe926318f911f317eac0b686d Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Wed, 16 Dec 2020 14:39:53 -0500 Subject: [PATCH 044/480] #499 Adds interfaces ILogStrings and ILogStringsWithLevel to PepperDash_Essentials_Core.Interfaces --- .../Interfaces/ILogStrings.cs | 17 +++++++++++++++++ .../Interfaces/ILogStringsWithLevel.cs | 18 ++++++++++++++++++ .../PepperDash_Essentials_Core.csproj | 2 ++ 3 files changed, 37 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs new file mode 100644 index 00000000..441292e8 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Core.IKeyed; + +namespace PepperDash_Essentials_Core.Interfaces +{ + public interface ILogStrings : IKeyed + { + /// + /// Defines a class that is capable of logging a string + /// + void SendToLog(IKeyed device, string logMessage); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs new file mode 100644 index 00000000..636128c9 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Core; + +namespace PepperDash_Essentials_Core.Interfaces +{ + public interface ILogStringsWithLevel + { + /// + /// Defines a class that is capable of logging a string with an int level + /// + void SendToLog(IKeyed device, Debug.ErrorLogLevel level,string logMessage); + } + +} \ 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 6d4def73..39e68257 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -223,6 +223,8 @@ + + From fc91ba7c1e3a57cd9e01a9a9727f158632c1c4c8 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Wed, 16 Dec 2020 15:00:30 -0500 Subject: [PATCH 045/480] Fixes Namespace and Implements IKeyed in both interfaces. --- .../PepperDashEssentialsBase/Interfaces/ILogStrings.cs | 4 ++-- .../Interfaces/ILogStringsWithLevel.cs | 4 ++-- .../Essentials_DM/PepperDash_Essentials_DM.csproj | 6 +++--- .../Essentials Devices Common.csproj | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs index 441292e8..92557319 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStrings.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; -using PepperDash.Core.IKeyed; +using PepperDash.Core; -namespace PepperDash_Essentials_Core.Interfaces +namespace PepperDash.Essentials.Core.Interfaces { public interface ILogStrings : IKeyed { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs index 636128c9..c43c4e6c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Interfaces/ILogStringsWithLevel.cs @@ -5,9 +5,9 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; -namespace PepperDash_Essentials_Core.Interfaces +namespace PepperDash.Essentials.Core.Interfaces { - public interface ILogStringsWithLevel + public interface ILogStringsWithLevel : IKeyed { /// /// Defines a class that is capable of logging a string with an int level 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 69045ea5..b1ea1b42 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -65,12 +65,12 @@ False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False @@ -79,7 +79,7 @@ False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe False diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 54d37613..bfee822e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -69,12 +69,12 @@ False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False @@ -83,7 +83,7 @@ False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe False From 66cd39c0138b0d92b9030fd30b7b96c3b236a953 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 16 Dec 2020 16:21:10 -0700 Subject: [PATCH 046/480] changed event names and added saved event --- .../Room/Types/EssentialsTechRoom.cs | 4 +-- .../Presets/DevicePresets.cs | 28 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index acd44710..535cab22 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -36,7 +36,7 @@ namespace PepperDash.Essentials _tunerPresets.SetFileName(_config.PresetsFileName); - _tunerPresets.PresetChanged += TunerPresetsOnPresetChanged; + _tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled; _tuners = GetDevices(_config.Tuners); _displays = GetDevices(_config.Displays); @@ -78,7 +78,7 @@ namespace PepperDash.Essentials #endregion - private void TunerPresetsOnPresetChanged(ISetTopBoxNumericKeypad device, string channel) + private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel) { if (!_currentPresets.ContainsKey(device.Key)) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 6fb228a4..d2724d77 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -16,12 +16,14 @@ namespace PepperDash.Essentials.Core.Presets /// public class DevicePresetsModel : Device { - public delegate void PresetChangedCallback(ISetTopBoxNumericKeypad device, string channel); + public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel); + + public delegate void PresetsSavedCallback(List presets); private readonly CCriticalSection _fileOps = new CCriticalSection(); private readonly bool _initSuccess; - private ISetTopBoxNumericKeypad _setTopBox; + private readonly ISetTopBoxNumericKeypad _setTopBox; /// /// The methods on the STB device to call when dialing @@ -83,7 +85,8 @@ namespace PepperDash.Essentials.Core.Presets _initSuccess = true; } - public event PresetChangedCallback PresetChanged; + public event PresetRecalledCallback PresetRecalled; + public event PresetsSavedCallback PresetsSaved; public int PulseTime { get; set; } public int DigitSpacingMs { get; set; } @@ -188,7 +191,7 @@ namespace PepperDash.Essentials.Core.Presets if (_setTopBox == null) return; - OnPresetChanged(_setTopBox, chanNum); + OnPresetRecalled(_setTopBox, chanNum); } public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox) @@ -218,14 +221,14 @@ namespace PepperDash.Essentials.Core.Presets _enterFunction = setTopBox.KeypadEnter; - OnPresetChanged(setTopBox, chanNum); + OnPresetRecalled(setTopBox, chanNum); Dial(chanNum); } - private void OnPresetChanged(ISetTopBoxNumericKeypad setTopBox, string channel) + private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel) { - var handler = PresetChanged; + var handler = PresetRecalled; if (handler == null) { @@ -265,6 +268,8 @@ namespace PepperDash.Essentials.Core.Presets { file.Write(json, Encoding.UTF8); } + + } finally { @@ -273,6 +278,15 @@ namespace PepperDash.Essentials.Core.Presets } + private void OnPresetsSaved() + { + var handler = PresetsSaved; + + if (handler == null) return; + + handler(PresetsList); + } + private void Pulse(Action act) { act(true); From 695ff5487f4e5db7f45db1a01a295cfd56829a44 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 17 Dec 2020 10:38:31 -0700 Subject: [PATCH 047/480] actually fire the PresetsSaved event --- .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index d2724d77..85e5dfdb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -248,6 +248,8 @@ namespace PepperDash.Essentials.Core.Presets PresetsList[index] = preset; SavePresets(); + + OnPresetsSaved(); } public void UpdatePresets(List presets) @@ -255,6 +257,8 @@ namespace PepperDash.Essentials.Core.Presets PresetsList = presets; SavePresets(); + + OnPresetsSaved(); } private void SavePresets() From 57ebd2b6086732e089e0eecab82ab4a6698dec0b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 17 Dec 2020 14:07:48 -0700 Subject: [PATCH 048/480] Adds IRunDirectAction to EssentialsTechRoom --- .../Room/Types/EssentialsTechRoom.cs | 55 +- .../Room/Interfaces.cs | 8 + .../VideoCodec/ZoomRoom/ResponseObjects.cs | 2666 ++++++++--------- 3 files changed, 1394 insertions(+), 1335 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 535cab22..515a4355 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -17,7 +17,7 @@ using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials { - public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced + public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction { private readonly EssentialsTechRoomConfig _config; private readonly Dictionary _displays; @@ -28,6 +28,8 @@ namespace PepperDash.Essentials private Dictionary _currentPresets; private ScheduledEventGroup _roomScheduledEventGroup; + private GenericSource DummySource = new GenericSource("$off", "Dummy Source"); + public EssentialsTechRoom(DeviceConfig config) : base(config) { _config = config.Properties.ToObject(); @@ -48,6 +50,8 @@ namespace PepperDash.Essentials SubscribeToDisplayFeedbacks(); CreateOrUpdateScheduledEvents(); + + DeviceManager.AddDevice(DummySource); } public Dictionary CurrentPresetsFeedbacks { get; private set; } @@ -241,7 +245,7 @@ namespace PepperDash.Essentials { foreach (var display in _displays) { - display.Value.PowerOn(); + } } @@ -373,6 +377,53 @@ namespace PepperDash.Essentials { } } + + #region IRunDirectRouteAction Members + + private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest) + { + if (dest == null) + { + Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key); + return; + } + + if (source.Key.Equals("$off", StringComparison.OrdinalIgnoreCase)) + { + dest.ReleaseRoute(); + if (dest is IHasPowerControl) + (dest as IHasPowerControl).PowerOff(); + } + else + { + if (source == null) + { + Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", source.Key, dest.Key); + return; + } + dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video); + } + } + + /// + /// Attempts to route directly between a source and destination + /// + /// + /// + public void RunDirectRoute(string sourceKey, string destinationKey) + { + IRoutingSink dest = null; + + dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink; + + var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs; + + RunDirectRoute(source, dest); + } + + + + #endregion } public class ScheduledEventEventArgs : EventArgs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs index 1743bdaa..82871228 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs @@ -41,6 +41,14 @@ namespace PepperDash.Essentials.Core } + /// + /// Simplified routing direct from source to destination + /// + public interface IRunDirectRouteAction + { + void RunDirectRoute(string sourceKey, string destinationKey); + } + /// /// For rooms that default presentation only routing /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 3be18c1d..36cce89f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1,1335 +1,1335 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.ComponentModel; -using System.Runtime.CompilerServices; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Devices.Common.Codec; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom -{ - public enum eZoomRoomResponseType - { - zEvent, - zStatus, - zConfiguration, - zCommand - } - - public abstract class NotifiableObject : INotifyPropertyChanged - { - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected void NotifyPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - } - - /// - /// Used to track the current status of a ZoomRoom - /// - public class ZoomRoomStatus - { - public zStatus.Login Login { get; set; } - public zStatus.SystemUnit SystemUnit { get; set; } - public zStatus.Phonebook Phonebook { get; set; } - public zStatus.Call Call { get; set; } - public zStatus.Capabilities Capabilities { get; set; } - public zStatus.Sharing Sharing { get; set; } - public zStatus.NumberOfScreens NumberOfScreens { get; set; } - public zStatus.Layout Layout { get; set; } - public zStatus.Video Video { get; set; } - public zStatus.CameraShare CameraShare { get; set; } - public List AudioInputs { get; set; } - public List AudioOuputs { get; set; } - public List Cameras { get; set; } - public zEvent.PhoneCallStatus PhoneCall { get; set; } - - public ZoomRoomStatus() - { - Login = new zStatus.Login(); - SystemUnit = new zStatus.SystemUnit(); - Phonebook = new zStatus.Phonebook(); - Call = new zStatus.Call(); - Capabilities = new zStatus.Capabilities(); - Sharing = new zStatus.Sharing(); - NumberOfScreens = new zStatus.NumberOfScreens(); - Layout = new zStatus.Layout(); - Video = new zStatus.Video(); - CameraShare = new zStatus.CameraShare(); - AudioInputs = new List(); - AudioOuputs = new List(); - Cameras = new List(); - PhoneCall = new zEvent.PhoneCallStatus(); - } - } - - /// - /// Used to track the current configuration of a ZoomRoom - /// - public class ZoomRoomConfiguration - { - public zConfiguration.Call Call { get; set; } - public zConfiguration.Audio Audio { get; set; } - public zConfiguration.Video Video { get; set; } - public zConfiguration.Client Client { get; set; } - public zConfiguration.Camera Camera { get; set; } - - public ZoomRoomConfiguration() - { - Call = new zConfiguration.Call(); - Audio = new zConfiguration.Audio(); - Video = new zConfiguration.Video(); - Client = new zConfiguration.Client(); +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Devices.Common.Codec; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom +{ + public enum eZoomRoomResponseType + { + zEvent, + zStatus, + zConfiguration, + zCommand + } + + public abstract class NotifiableObject : INotifyPropertyChanged + { + #region INotifyPropertyChanged Members + + public event PropertyChangedEventHandler PropertyChanged; + + protected void NotifyPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + #endregion + } + + /// + /// Used to track the current status of a ZoomRoom + /// + public class ZoomRoomStatus + { + public zStatus.Login Login { get; set; } + public zStatus.SystemUnit SystemUnit { get; set; } + public zStatus.Phonebook Phonebook { get; set; } + public zStatus.Call Call { get; set; } + public zStatus.Capabilities Capabilities { get; set; } + public zStatus.Sharing Sharing { get; set; } + public zStatus.NumberOfScreens NumberOfScreens { get; set; } + public zStatus.Layout Layout { get; set; } + public zStatus.Video Video { get; set; } + public zStatus.CameraShare CameraShare { get; set; } + public List AudioInputs { get; set; } + public List AudioOuputs { get; set; } + public List Cameras { get; set; } + public zEvent.PhoneCallStatus PhoneCall { get; set; } + + public ZoomRoomStatus() + { + Login = new zStatus.Login(); + SystemUnit = new zStatus.SystemUnit(); + Phonebook = new zStatus.Phonebook(); + Call = new zStatus.Call(); + Capabilities = new zStatus.Capabilities(); + Sharing = new zStatus.Sharing(); + NumberOfScreens = new zStatus.NumberOfScreens(); + Layout = new zStatus.Layout(); + Video = new zStatus.Video(); + CameraShare = new zStatus.CameraShare(); + AudioInputs = new List(); + AudioOuputs = new List(); + Cameras = new List(); + PhoneCall = new zEvent.PhoneCallStatus(); + } + } + + /// + /// Used to track the current configuration of a ZoomRoom + /// + public class ZoomRoomConfiguration + { + public zConfiguration.Call Call { get; set; } + public zConfiguration.Audio Audio { get; set; } + public zConfiguration.Video Video { get; set; } + public zConfiguration.Client Client { get; set; } + public zConfiguration.Camera Camera { get; set; } + + public ZoomRoomConfiguration() + { + Call = new zConfiguration.Call(); + Audio = new zConfiguration.Audio(); + Video = new zConfiguration.Video(); + Client = new zConfiguration.Client(); Camera = new zConfiguration.Camera(); - } - } - - /// - /// Represents a response from a ZoomRoom system - /// - public class Response - { - public Status Status { get; set; } - public bool Sync { get; set; } - [JsonProperty("topKey")] - public string TopKey { get; set; } - [JsonProperty("type")] - public string Type { get; set; } - - public Response() - { - Status = new Status(); - } - } - - public class Status - { - [JsonProperty("message")] - public string Message { get; set; } - [JsonProperty("state")] - public string State { get; set; } - } - - - /// - /// zStatus class stucture - /// - public class zStatus - { - public class Login - { - [JsonProperty("ZAAPI Release")] - public string ZAAPIRelease { get; set; } - [JsonProperty("Zoom Room Release")] - public string ZoomRoomRelease { get; set; } - } - - public class SystemUnit - { - [JsonProperty("email")] - public string Email { get; set; } - [JsonProperty("login_type")] - public string LoginType { get; set; } - [JsonProperty("meeting_number")] - public string MeetingNumber { get; set; } - [JsonProperty("platform")] - public string Platform { get; set; } - [JsonProperty("room_info")] - public RoomInfo RoomInfo { get; set; } - [JsonProperty("room_version")] - public string RoomVersion { get; set; } - - public SystemUnit() - { - RoomInfo = new RoomInfo(); - } - } - - public class RoomInfo - { - [JsonProperty("account_email")] - public string AccountEmail { get; set; } - [JsonProperty("display_version")] - public string DisplayVersion { get; set; } - [JsonProperty("is_auto_answer_enabled")] - public bool AutoAnswerIsEnabled { get; set; } - [JsonProperty("is_auto_answer_selected")] - public bool AutoAnswerIsSelected { get; set; } - [JsonProperty("room_name")] - public string RoomName { get; set; } - } - - public class CloudPbxInfo - { - [JsonProperty("company_number")] - public string CompanyNumber { get; set; } - [JsonProperty("extension")] - public string Extension { get; set; } - [JsonProperty("isValid")] - public bool IsValid { get; set; } - } - - public enum ePresence - { - PRESENCE_OFFLINE, - PRESENCE_ONLINE, - PRESENCE_AWAY, - PRESENCE_BUSY, - PRESENCE_DND - } - - public class Contact - { - [JsonProperty("avatarURL")] - public string AvatarURL { get; set; } - [JsonProperty("cloud_pbx_info")] - public CloudPbxInfo CloudPbxInfo { get; set; } - [JsonProperty("email")] - public string Email { get; set; } - [JsonProperty("firstName")] - public string FirstName { get; set; } - [JsonProperty("index")] - public int Index { get; set; } - [JsonProperty("isLegacy")] - public bool IsLegacy { get; set; } - [JsonProperty("isZoomRoom")] - public bool IsZoomRoom { get; set; } - [JsonProperty("jid")] - public string Jid { get; set; } - [JsonProperty("lastName")] - public string LastName { get; set; } - [JsonProperty("onDesktop")] - public bool OnDesktop { get; set; } - [JsonProperty("onMobile")] - public bool OnMobile { get; set; } - [JsonProperty("phoneNumber")] - public string PhoneNumber { get; set; } - [JsonProperty("presence")] - public ePresence Presence { get; set; } - [JsonProperty("presence_status")] - public int PresenceStatus { get; set; } - [JsonProperty("screenName")] - public string ScreenName { get; set; } - [JsonProperty("sip_phone_number")] - public string SipPhoneNumber { get; set; } - - - public Contact() - { - CloudPbxInfo = new CloudPbxInfo(); - } - } - - /// - /// Used to be able to inplement IInvitableContact on DirectoryContact - /// - public class ZoomDirectoryContact : DirectoryContact, IInvitableContact - { - - } - - public class Phonebook - { - [JsonProperty("Contacts")] - public List Contacts { get; set; } - - public Phonebook() - { - Contacts = new List(); - } - - /// - /// Converts from zStatus.Contact types to generic directory items - /// - /// - public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts) - { - var directory = new CodecDirectory(); - - var folders = new List(); - - var roomFolder = new DirectoryFolder(); - - var contactFolder = new DirectoryFolder(); - - var contacts = new List(); - - // Check if there are any zoom rooms - var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom); - - if (zoomRooms.Count > 0) - { - // If so, setup a rooms and contacts folder and add them. - roomFolder.Name = "Rooms"; - roomFolder.ParentFolderId = "root"; - roomFolder.FolderId = "rooms"; - - contactFolder.Name = "Contacts"; - contactFolder.ParentFolderId = "root"; - contactFolder.FolderId = "contacts"; - - folders.Add(roomFolder); - folders.Add(contactFolder); - - directory.AddFoldersToDirectory(folders); - } - - try - { - if (zoomContacts.Count == 0) return directory; - { - foreach (Contact c in zoomContacts) - { - var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid}; - - if (folders.Count > 0) - { - contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; - } - - contacts.Add(contact); - } - - directory.AddContactsToDirectory(contacts); - } - } - catch (Exception e) - { - Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e); - } - - return directory; - } - } - - public enum eCallStatus - { - UNKNOWN, - NOT_IN_MEETING, - CONNECTING_MEETING, - IN_MEETING, - LOGGED_OUT - } - - public class ClosedCaption - { - public bool Available { get; set; } - } - - public class Call : NotifiableObject - { - private eCallStatus _status; - private List _participants; - - public bool IsInCall; - - public eCallStatus Status - { - get - { - return _status; - } - set - { - if (value != _status) - { - _status = value; - IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING; - NotifyPropertyChanged("Status"); - } - } - } - public ClosedCaption ClosedCaption { get; set; } - public List Participants - { - get - { - return _participants; - } - set - { - _participants = value; - NotifyPropertyChanged("Participants"); - } - } - public zEvent.SharingState Sharing { get; set; } - - public CallRecordInfo CallRecordInfo { get; set; } - - private zCommand.InfoResult _info; - - public zCommand.InfoResult Info - { - get - { - return _info; - } - set - { - _info = value; - NotifyPropertyChanged("Info"); - } - } - - public Call() - { - ClosedCaption = new ClosedCaption(); - Participants = new List(); - Sharing = new zEvent.SharingState(); - CallRecordInfo = new CallRecordInfo(); - Info = new zCommand.InfoResult(); - } - } - - public class Capabilities - { - public bool aec_Setting_Stored_In_ZR { get; set; } - public bool can_Dtmf_For_Invite_By_Phone { get; set; } - public bool can_Mute_On_Entry { get; set; } - public bool can_Ringing_In_Pstn_Call { get; set; } - public bool can_Switch_To_Specific_Camera { get; set; } - public bool is_Airhost_Disabled { get; set; } - public bool pstn_Call_In_Local_resentation { get; set; } - public bool support_Claim_Host { get; set; } - public bool support_Out_Room_Display { get; set; } - public bool support_Pin_And_Spotlight { get; set; } - public bool supports_Audio_Checkup { get; set; } - public bool supports_CheckIn { get; set; } - public bool supports_Cloud_PBX { get; set; } - public bool supports_Encrypted_Connection { get; set; } - public bool supports_Expel_User_Permanently { get; set; } - public bool supports_H323_DTMF { get; set; } - public bool supports_Hdmi_Cec_Control { get; set; } - public bool supports_Highly_Reverberant_Room { get; set; } - public bool supports_Loading_Contacts_Dynamically { get; set; } - public bool supports_Loading_Participants_Dynamically { get; set; } - public bool supports_Mic_Record_Test { get; set; } - public bool supports_Multi_Share { get; set; } - public bool supports_ShareCamera { get; set; } - public bool supports_Share_For_Floating_And_Content_Only { get; set; } - public bool supports_Sip_Call_out { get; set; } - public bool supports_Software_Audio_Processing { get; set; } - public bool supports_Web_Settings_Push { get; set; } - } - - public class Sharing : NotifiableObject - { - private string _dispState; - private string _password; - - public string directPresentationPairingCode { get; set; } - /// - /// Laptop client sharing key - /// - public string directPresentationSharingKey { get; set; } - public string dispState - { - get - { - return _dispState; - } - set - { - if (value != _dispState) - { - _dispState = value; - NotifyPropertyChanged("dispState"); - } - } - } - public bool isAirHostClientConnected { get; set; } - public bool isBlackMagicConnected { get; set; } - public bool isBlackMagicDataAvailable { get; set; } - public bool isDirectPresentationConnected { get; set; } - public bool isSharingBlackMagic { get; set; } - /// - /// IOS Airplay code - /// - public string password - { - get - { - return _password; - } - set - { - if (value != _password) - { - _password = value; - NotifyPropertyChanged("password"); - } - } - } - public string serverName { get; set; } - public string wifiName { get; set; } - } - - public class NumberOfScreens - { - [JsonProperty("NumberOfCECScreens")] - public int NumOfCECScreens { get; set; } - [JsonProperty("NumberOfScreens")] - public int NumOfScreens { get; set; } - } - - /// - /// AudioInputLine/AudioOutputLine/VideoCameraLine list item - /// - public class AudioVideoInputOutputLineItem - { - public string Alias { get; set; } - public string Name { get; set; } - public bool Selected { get; set; } - public bool combinedDevice { get; set; } - public string id { get; set; } - public bool manuallySelected { get; set; } - public int numberOfCombinedDevices { get; set; } - public int ptzComId { get; set; } - } - - public class Video - { - public bool Optimizable { get; set; } - } - - public class CameraShare : NotifiableObject - { - private bool _canControlCamera; - private bool _isSharing; - - [JsonProperty("can_Control_Camera")] - public bool CanControlCamera - { - get - { - return _canControlCamera; - } - set - { - if (value != _canControlCamera) - { - _canControlCamera = value; - NotifyPropertyChanged("CanControlCamera"); - } - } - } - public string id { get; set; } - public bool is_Mirrored { get; set; } - [JsonProperty("is_Sharing")] - public bool IsSharing - { - get - { - return _isSharing; - } - set - { - if (value != _isSharing) - { - _isSharing = value; - NotifyPropertyChanged("IsSharing"); - } - } - } - public int pan_Tilt_Speed { get; set; } - - } - - public class Layout - { - public bool can_Adjust_Floating_Video { get; set; } - public bool can_Switch_Floating_Share_Content { get; set; } - public bool can_Switch_Share_On_All_Screens { get; set; } - public bool can_Switch_Speaker_View { get; set; } - public bool can_Switch_Wall_View { get; set; } - public bool is_In_First_Page { get; set; } - public bool is_In_Last_Page { get; set; } - public bool is_supported { get; set; } - public int video_Count_In_Current_Page { get; set; } - public string video_type { get; set; } - } - - public class CallRecordInfo - { - public bool canRecord { get; set; } - public bool emailRequired { get; set; } - public bool amIRecording { get; set; } - public bool meetingIsBeingRecorded { get; set; } - } - } - - /// - /// zEvent Class Structure - /// - public class zEvent - { - public class NeedWaitForHost - { - public bool Wait { get; set; } - } - - public class IncomingCallIndication - { - public string callerJID { get; set; } - public string calleeJID { get; set; } - public string meetingID { get; set; } - public string password { get; set; } - public string meetingOption { get; set; } - public long MeetingNumber { get; set; } - public string callerName { get; set; } - public string avatarURL { get; set; } - public int lifeTime { get; set; } - public bool accepted { get; set; } - } - - public class CallConnectError - { - public int error_code { get; set; } - public string error_message { get; set; } - } - - public class CallDisconnect - { - public bool Successful - { - get - { - return success == "on"; - } - } - - public string success { get; set; } - } - - public class Layout - { - public bool Sharethumb { get; set; } - } - - public class Call - { - public Layout Layout { get; set; } - } - - public class Client - { - public Call Call { get; set; } - } - - public enum eSharingState - { - None, - Connecting, - Sending, - Receiving, - Send_Receiving - } - - public class SharingState : NotifiableObject - { - private bool _paused; - private eSharingState _state; - - public bool IsSharing; - - [JsonProperty("paused")] - public bool Paused - { - get - { - return _paused; - } - set - { - if (value != _paused) - { - _paused = value; - NotifyPropertyChanged("Paused"); - } - } - } - [JsonProperty("state")] - public eSharingState State - { - get - { - return _state; - } - set - { - if (value != _state) - { - _state = value; - IsSharing = _state == eSharingState.Sending; - NotifyPropertyChanged("State"); - } - } - } - } - - public class PinStatusOfScreenNotification - { - [JsonProperty("can_be_pinned")] - public bool CanBePinned { get; set; } - [JsonProperty("can_pin_share")] - public bool CanPinShare { get; set; } - [JsonProperty("pinned_share_source_id")] - public int PinnedShareSourceId { get; set; } - [JsonProperty("pinned_user_id")] - public int PinnedUserId { get; set; } - [JsonProperty("screen_index")] - public int ScreenIndex { get; set; } - [JsonProperty("screen_layout")] - public int ScreenLayout { get; set; } - [JsonProperty("share_source_type")] - public int ShareSourceType { get; set; } - [JsonProperty("why_cannot_pin_share")] - public string WhyCannotPinShare { get; set; } - } - - public class PhoneCallStatus:NotifiableObject - { - private bool _isIncomingCall; - private string _peerDisplayName; - private string _peerNumber; - - private bool _offHook; - - public string CallId { get; set; } - public bool IsIncomingCall { - get { return _isIncomingCall; } - set - { - if(value == _isIncomingCall) return; - - _isIncomingCall = value; - NotifyPropertyChanged("IsIncomingCall"); - } } - - public string PeerDisplayName - { - get { return _peerDisplayName; } - set - { - if (value == _peerDisplayName) return; - _peerDisplayName = value; - NotifyPropertyChanged("PeerDisplayName"); - } - } - - public string PeerNumber - { - get { return _peerNumber; } - set - { - if (value == _peerNumber) return; - - _peerNumber = value; - NotifyPropertyChanged("PeerNumber"); - } - } - - public string PeerUri { get; set; } - - private ePhoneCallStatus _status; - public ePhoneCallStatus Status - { - get { return _status; } - set - { - _status = value; - OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted || - _status == ePhoneCallStatus.PhoneCallStatus_InCall || - _status == ePhoneCallStatus.PhoneCallStatus_Init || - _status == ePhoneCallStatus.PhoneCallStatus_Ringing; - } - } - - public bool OffHook - { - get { return _offHook; } - set - { - if (value == _offHook) return; - - _offHook = value; - NotifyPropertyChanged("OffHook"); - } - } - } - - public enum ePhoneCallStatus - { - PhoneCallStatus_Ringing, - PhoneCallStatus_Terminated, - PhoneCallStatus_Accepted, - PhoneCallStatus_InCall, - PhoneCallStatus_Init, - } - } - - /// - /// zConfiguration class structure - /// - public class zConfiguration - { - public class Sharing - { - [JsonProperty("optimize_video_sharing")] - public bool OptimizeVideoSharing { get; set; } - } - - public class Camera : NotifiableObject - { - private bool _mute; - - public bool Mute - { - get { return _mute; } - set - { - Debug.Console(1, "Camera Mute response received: {0}", value); - - if (value == _mute) return; - - _mute = value; - NotifyPropertyChanged("Mute"); - } - } - } - - public class Microphone : NotifiableObject - { - private bool _mute; - - public bool Mute - { - get - { - return _mute; - } - set - { - if(value != _mute) - { - _mute = value; - NotifyPropertyChanged("Mute"); - } - } - } - } - - public enum eLayoutStyle - { - Gallery, - Speaker, - Strip, - ShareAll - } - - public enum eLayoutSize - { - Off, - Size1, - Size2, - Size3, - Strip - } - - public enum eLayoutPosition - { - Center, - Up, - Right, - UpRight, - Down, - DownRight, - Left, - UpLeft, - DownLeft - } - - public class Layout:NotifiableObject - { - public bool ShareThumb { get; set; } - public eLayoutStyle Style { get; set; } - public eLayoutSize Size { get; set; } - - private eLayoutPosition _position; - public eLayoutPosition Position { - get { return _position; } - set - { - _position = value; - NotifyPropertyChanged("Position"); - } } - } - - public class Lock - { - public bool Enable { get; set; } - } - - public class ClosedCaption - { - public bool Visible { get; set; } - public int FontSize { get; set; } - } - - public class MuteUserOnEntry - { - public bool Enable { get; set; } - } - - public class Call - { - public Sharing Sharing { get; set; } - public Camera Camera { get; set; } - public Microphone Microphone { get; set; } - public Layout Layout { get; set; } - public Lock Lock { get; set; } - public MuteUserOnEntry MuteUserOnEntry { get; set; } - public ClosedCaption ClosedCaption { get; set; } - - - public Call() - { - Sharing = new Sharing(); - Camera = new Camera(); - Microphone = new Microphone(); - Layout = new Layout(); - Lock = new Lock(); - MuteUserOnEntry = new MuteUserOnEntry(); - ClosedCaption = new ClosedCaption(); - } - } - - public class Audio - { - public Input Input { get; set; } - public Output Output { get; set; } - - public Audio() - { - Input = new Input(); - Output = new Output(); - } - } - - public class Input : Output - { - [JsonProperty("reduce_reverb")] - public bool ReduceReverb { get; set; } - } - - public class Output : NotifiableObject - { - private int _volume; - - [JsonProperty("volume")] - public int Volume - { - get - { - return _volume; - } - set - { - if (value != _volume) - { - _volume = value; - NotifyPropertyChanged("Volume"); - } - } - } - [JsonProperty("selectedId")] - public string SelectedId { get; set; } - [JsonProperty("is_sap_disabled")] - public bool IsSapDisabled { get; set; } - } - - public class Video : NotifiableObject - { - private bool _hideConfSelfVideo; - - [JsonProperty("hide_conf_self_video")] - public bool HideConfSelfVideo - { - get - { - return _hideConfSelfVideo; - } - set - { - if (value != _hideConfSelfVideo) - { - _hideConfSelfVideo = value; - NotifyPropertyChanged("HideConfSelfVideo"); - } - } - } - - public VideoCamera Camera { get; set; } - - public Video() - { - Camera = new VideoCamera(); - } - } - - public class VideoCamera : NotifiableObject - { - private string _selectedId; - - [JsonProperty("selectedId")] - public string SelectedId { - get - { - return _selectedId; - } - set - { - if (value != _selectedId) - { - _selectedId = value; - NotifyPropertyChanged("SelectedId"); - } - } - - } - public bool Mirror { get; set; } - } - - public class Client - { - public string appVersion { get; set; } - public string deviceSystem { get; set; } - } - - } - - /// - /// zCommand class structure - /// - public class zCommand - { - public class BookingsListResult - { - [JsonProperty("accessRole")] - public string AccessRole { get; set; } - [JsonProperty("calendarChangeKey")] - public string CalendarChangeKey { get; set; } - [JsonProperty("calendarID")] - public string CalendarId { get; set; } - [JsonProperty("checkIn")] - public bool CheckIn { get; set; } - [JsonProperty("creatorEmail")] - public string CreatorEmail { get; set; } - [JsonProperty("creatorName")] - public string CreatorName { get; set; } - [JsonProperty("endTime")] - public DateTime EndTime { get; set; } - [JsonProperty("hostName")] - public string HostName { get; set; } - [JsonProperty("isInstantMeeting")] - public bool IsInstantMeeting { get; set; } - [JsonProperty("isPrivate")] - public bool IsPrivate { get; set; } - [JsonProperty("location")] - public string Location { get; set; } - [JsonProperty("meetingName")] - public string MeetingName { get; set; } - [JsonProperty("meetingNumber")] - public string MeetingNumber { get; set; } - [JsonProperty("scheduledFrom")] - public string ScheduledFrom { get; set; } - [JsonProperty("startTime")] - public DateTime StartTime { get; set; } - [JsonProperty("third_party")] - public ThirdParty ThirdParty { get; set; } - } - - public static List GetGenericMeetingsFromBookingResult(List bookings, - int minutesBeforeMeetingStart) - { - var rv = GetGenericMeetingsFromBookingResult(bookings); - - foreach (var meeting in rv) - { - meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart; - } - - return rv; - } - /// - /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class - /// - /// - /// - public static List GetGenericMeetingsFromBookingResult(List bookings) - { - var meetings = new List(); - - if (Debug.Level > 0) - { - Debug.Console(1, "Meetings List:\n"); - } - - foreach (var b in bookings) - { - var meeting = new Meeting(); - - if (b.MeetingNumber != null) - meeting.Id = b.MeetingNumber; - if (b.CreatorName != null) - meeting.Organizer = b.CreatorName; - if (b.MeetingName != null) - meeting.Title = b.MeetingName; - //if (b.Agenda != null) - // meeting.Agenda = b.Agenda.Value; - if (b.StartTime != null) - meeting.StartTime = b.StartTime; - if (b.EndTime != null) - meeting.EndTime = b.EndTime; - - meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public; - - // No meeting.Calls data exists for Zoom Rooms. Leaving out for now. - var now = DateTime.Now; - if (meeting.StartTime < now && meeting.EndTime < now) - { - Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title); - continue; - } - - meetings.Add(meeting); - - if (Debug.Level > 0) - { - Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer); - Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration); - Debug.Console(1, " Joinable: {0}\n", meeting.Joinable); - } - } - - meetings.OrderBy(m => m.StartTime); - - return meetings; - } - - public class HandStatus - { - [JsonProperty("is_raise_hand")] - public bool IsRaiseHand { get; set; } - [JsonProperty("optimize_vis_validideo_sharing")] - public string IsValid { get; set; } - [JsonProperty("time_stamp")] - public string TimeStamp { get; set; } - } - - public class ListParticipant - { - [JsonProperty("audio_status state")] - public string AudioStatusState { get; set; } - [JsonProperty("audio_status type")] - public string AudioStatusType { get; set; } - [JsonProperty("avatar_url")] - public string AvatarUrl { get; set; } - [JsonProperty("camera_status am_i_controlling")] - public bool CameraStatusAmIControlling { get; set; } - [JsonProperty("camera_status can_i_request_control")] - public bool CameraStatusCanIRequestConrol { get; set; } - [JsonProperty("camera_status can_move_camera")] - public bool CameraStatusCanMoveCamera { get; set; } - [JsonProperty("camera_status can_switch_camera")] - public bool CameraStatusCanSwitchCamera { get; set; } - [JsonProperty("camera_status can_zoom_camera")] - public bool CameraStatusCanZoomCamera { get; set; } - [JsonProperty("can_edit_closed_caption")] - public bool CanEditClosedCaption { get; set; } - [JsonProperty("can_record")] - public bool CanRecord { get; set; } - [JsonProperty("event")] - public string Event { get; set; } - [JsonProperty("hand_status")] - public HandStatus HandStatus { get; set; } - [JsonProperty("isCohost")] - public bool IsCohost { get; set; } - [JsonProperty("is_client_support_closed_caption")] - public bool IsClientSupportClosedCaption { get; set; } - [JsonProperty("is_client_support_coHost")] - public bool IsClientSupportCoHost { get; set; } - [JsonProperty("is_host")] - public bool IsHost { get; set; } - [JsonProperty("is_myself")] - public bool IsMyself { get; set; } - [JsonProperty("is_recording")] - public bool IsRecording { get; set; } - [JsonProperty("is_video_can_mute_byHost")] - public bool IsVideoCanMuteByHost { get; set; } - [JsonProperty("is_video_can_unmute_byHost")] - public bool IsVideoCanUnmuteByHost { get; set; } - [JsonProperty("local_recording_disabled")] - public bool LocalRecordingDisabled { get; set; } - [JsonProperty("user_id")] - public int UserId { get; set; } - [JsonProperty("user_name")] - public string UserName { get; set; } - [JsonProperty("user_type")] - public string UserType { get; set; } - [JsonProperty("video_status has_source")] - public bool VideoStatusHasSource { get; set; } - [JsonProperty("video_status is_receiving")] - public bool VideoStatusIsReceiving { get; set; } - [JsonProperty("video_status is_sending")] - public bool VideoStatusIsSending { get; set; } - - public ListParticipant() - { - HandStatus = new HandStatus(); - } - - public static List GetGenericParticipantListFromParticipantsResult( - List participants) - { - return - participants.Select( - p => - new Participant - { - Name = p.UserName, - IsHost = p.IsHost, - CanMuteVideo = p.IsVideoCanMuteByHost, - CanUnmuteVideo = p.IsVideoCanUnmuteByHost, - AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", - VideoMuteFb = p.VideoStatusIsSending - }).ToList(); - } - } - - public class CallinCountryList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class CalloutCountryList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class TollFreeCallinList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class Info - { - public List callin_country_list { get; set; } - public List callout_country_list { get; set; } - public List toll_free_callin_list { get; set; } - } - - public class ThirdParty - { - public string h323_address { get; set; } - public string meeting_number { get; set; } - public string service_provider { get; set; } - public string sip_address { get; set; } - } - - public class MeetingListItem - { - public string accessRole { get; set; } - public string calendarChangeKey { get; set; } - public string calendarID { get; set; } - public bool checkIn { get; set; } - public string creatorEmail { get; set; } - public string creatorName { get; set; } - public string endTime { get; set; } - public string hostName { get; set; } - public bool isInstantMeeting { get; set; } - public bool isPrivate { get; set; } - public string location { get; set; } - public string meetingName { get; set; } - public string meetingNumber { get; set; } - public string scheduledFrom { get; set; } - public string startTime { get; set; } - public ThirdParty third_party { get; set; } - - public MeetingListItem() - { - third_party = new ThirdParty(); - } - } - - public class InfoResult - { - public Info Info { get; set; } - public bool am_i_original_host { get; set; } - public string default_callin_country { get; set; } - public string dialIn { get; set; } - public string international_url { get; set; } - public string invite_email_content { get; set; } - public string invite_email_subject { get; set; } - public bool is_callin_country_list_available { get; set; } - public bool is_calling_room_system_enabled { get; set; } - public bool is_toll_free_callin_list_available { get; set; } - public bool is_view_only { get; set; } - public bool is_waiting_room { get; set; } - public bool is_webinar { get; set; } - public string meeting_id { get; set; } - public MeetingListItem meeting_list_item { get; set; } - public string meeting_password { get; set; } - public string meeting_type { get; set; } - public int my_userid { get; set; } - public int participant_id { get; set; } - public string real_meeting_id { get; set; } - public string schedule_option { get; set; } - public string schedule_option2 { get; set; } - public string support_callout_type { get; set; } - public string toll_free_number { get; set; } - public string user_type { get; set; } - - public InfoResult() - { - Info = new Info(); - meeting_list_item = new MeetingListItem(); - } - } - - public class Phonebook - { - public List Contacts { get; set; } - public int Limit { get; set; } - public int Offset { get; set; } - } - } + } + } + + /// + /// Represents a response from a ZoomRoom system + /// + public class Response + { + public Status Status { get; set; } + public bool Sync { get; set; } + [JsonProperty("topKey")] + public string TopKey { get; set; } + [JsonProperty("type")] + public string Type { get; set; } + + public Response() + { + Status = new Status(); + } + } + + public class Status + { + [JsonProperty("message")] + public string Message { get; set; } + [JsonProperty("state")] + public string State { get; set; } + } + + + /// + /// zStatus class stucture + /// + public class zStatus + { + public class Login + { + [JsonProperty("ZAAPI Release")] + public string ZAAPIRelease { get; set; } + [JsonProperty("Zoom Room Release")] + public string ZoomRoomRelease { get; set; } + } + + public class SystemUnit + { + [JsonProperty("email")] + public string Email { get; set; } + [JsonProperty("login_type")] + public string LoginType { get; set; } + [JsonProperty("meeting_number")] + public string MeetingNumber { get; set; } + [JsonProperty("platform")] + public string Platform { get; set; } + [JsonProperty("room_info")] + public RoomInfo RoomInfo { get; set; } + [JsonProperty("room_version")] + public string RoomVersion { get; set; } + + public SystemUnit() + { + RoomInfo = new RoomInfo(); + } + } + + public class RoomInfo + { + [JsonProperty("account_email")] + public string AccountEmail { get; set; } + [JsonProperty("display_version")] + public string DisplayVersion { get; set; } + [JsonProperty("is_auto_answer_enabled")] + public bool AutoAnswerIsEnabled { get; set; } + [JsonProperty("is_auto_answer_selected")] + public bool AutoAnswerIsSelected { get; set; } + [JsonProperty("room_name")] + public string RoomName { get; set; } + } + + public class CloudPbxInfo + { + [JsonProperty("company_number")] + public string CompanyNumber { get; set; } + [JsonProperty("extension")] + public string Extension { get; set; } + [JsonProperty("isValid")] + public bool IsValid { get; set; } + } + + public enum ePresence + { + PRESENCE_OFFLINE, + PRESENCE_ONLINE, + PRESENCE_AWAY, + PRESENCE_BUSY, + PRESENCE_DND + } + + public class Contact + { + [JsonProperty("avatarURL")] + public string AvatarURL { get; set; } + [JsonProperty("cloud_pbx_info")] + public CloudPbxInfo CloudPbxInfo { get; set; } + [JsonProperty("email")] + public string Email { get; set; } + [JsonProperty("firstName")] + public string FirstName { get; set; } + [JsonProperty("index")] + public int Index { get; set; } + [JsonProperty("isLegacy")] + public bool IsLegacy { get; set; } + [JsonProperty("isZoomRoom")] + public bool IsZoomRoom { get; set; } + [JsonProperty("jid")] + public string Jid { get; set; } + [JsonProperty("lastName")] + public string LastName { get; set; } + [JsonProperty("onDesktop")] + public bool OnDesktop { get; set; } + [JsonProperty("onMobile")] + public bool OnMobile { get; set; } + [JsonProperty("phoneNumber")] + public string PhoneNumber { get; set; } + [JsonProperty("presence")] + public ePresence Presence { get; set; } + [JsonProperty("presence_status")] + public int PresenceStatus { get; set; } + [JsonProperty("screenName")] + public string ScreenName { get; set; } + [JsonProperty("sip_phone_number")] + public string SipPhoneNumber { get; set; } + + + public Contact() + { + CloudPbxInfo = new CloudPbxInfo(); + } + } + + /// + /// Used to be able to inplement IInvitableContact on DirectoryContact + /// + public class ZoomDirectoryContact : DirectoryContact, IInvitableContact + { + + } + + public class Phonebook + { + [JsonProperty("Contacts")] + public List Contacts { get; set; } + + public Phonebook() + { + Contacts = new List(); + } + + /// + /// Converts from zStatus.Contact types to generic directory items + /// + /// + public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts) + { + var directory = new CodecDirectory(); + + var folders = new List(); + + var roomFolder = new DirectoryFolder(); + + var contactFolder = new DirectoryFolder(); + + var contacts = new List(); + + // Check if there are any zoom rooms + var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom); + + if (zoomRooms.Count > 0) + { + // If so, setup a rooms and contacts folder and add them. + roomFolder.Name = "Rooms"; + roomFolder.ParentFolderId = "root"; + roomFolder.FolderId = "rooms"; + + contactFolder.Name = "Contacts"; + contactFolder.ParentFolderId = "root"; + contactFolder.FolderId = "contacts"; + + folders.Add(roomFolder); + folders.Add(contactFolder); + + directory.AddFoldersToDirectory(folders); + } + + try + { + if (zoomContacts.Count == 0) return directory; + { + foreach (Contact c in zoomContacts) + { + var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid}; + + if (folders.Count > 0) + { + contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; + } + + contacts.Add(contact); + } + + directory.AddContactsToDirectory(contacts); + } + } + catch (Exception e) + { + Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e); + } + + return directory; + } + } + + public enum eCallStatus + { + UNKNOWN, + NOT_IN_MEETING, + CONNECTING_MEETING, + IN_MEETING, + LOGGED_OUT + } + + public class ClosedCaption + { + public bool Available { get; set; } + } + + public class Call : NotifiableObject + { + private eCallStatus _status; + private List _participants; + + public bool IsInCall; + + public eCallStatus Status + { + get + { + return _status; + } + set + { + if (value != _status) + { + _status = value; + IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING; + NotifyPropertyChanged("Status"); + } + } + } + public ClosedCaption ClosedCaption { get; set; } + public List Participants + { + get + { + return _participants; + } + set + { + _participants = value; + NotifyPropertyChanged("Participants"); + } + } + public zEvent.SharingState Sharing { get; set; } + + public CallRecordInfo CallRecordInfo { get; set; } + + private zCommand.InfoResult _info; + + public zCommand.InfoResult Info + { + get + { + return _info; + } + set + { + _info = value; + NotifyPropertyChanged("Info"); + } + } + + public Call() + { + ClosedCaption = new ClosedCaption(); + Participants = new List(); + Sharing = new zEvent.SharingState(); + CallRecordInfo = new CallRecordInfo(); + Info = new zCommand.InfoResult(); + } + } + + public class Capabilities + { + public bool aec_Setting_Stored_In_ZR { get; set; } + public bool can_Dtmf_For_Invite_By_Phone { get; set; } + public bool can_Mute_On_Entry { get; set; } + public bool can_Ringing_In_Pstn_Call { get; set; } + public bool can_Switch_To_Specific_Camera { get; set; } + public bool is_Airhost_Disabled { get; set; } + public bool pstn_Call_In_Local_resentation { get; set; } + public bool support_Claim_Host { get; set; } + public bool support_Out_Room_Display { get; set; } + public bool support_Pin_And_Spotlight { get; set; } + public bool supports_Audio_Checkup { get; set; } + public bool supports_CheckIn { get; set; } + public bool supports_Cloud_PBX { get; set; } + public bool supports_Encrypted_Connection { get; set; } + public bool supports_Expel_User_Permanently { get; set; } + public bool supports_H323_DTMF { get; set; } + public bool supports_Hdmi_Cec_Control { get; set; } + public bool supports_Highly_Reverberant_Room { get; set; } + public bool supports_Loading_Contacts_Dynamically { get; set; } + public bool supports_Loading_Participants_Dynamically { get; set; } + public bool supports_Mic_Record_Test { get; set; } + public bool supports_Multi_Share { get; set; } + public bool supports_ShareCamera { get; set; } + public bool supports_Share_For_Floating_And_Content_Only { get; set; } + public bool supports_Sip_Call_out { get; set; } + public bool supports_Software_Audio_Processing { get; set; } + public bool supports_Web_Settings_Push { get; set; } + } + + public class Sharing : NotifiableObject + { + private string _dispState; + private string _password; + + public string directPresentationPairingCode { get; set; } + /// + /// Laptop client sharing key + /// + public string directPresentationSharingKey { get; set; } + public string dispState + { + get + { + return _dispState; + } + set + { + if (value != _dispState) + { + _dispState = value; + NotifyPropertyChanged("dispState"); + } + } + } + public bool isAirHostClientConnected { get; set; } + public bool isBlackMagicConnected { get; set; } + public bool isBlackMagicDataAvailable { get; set; } + public bool isDirectPresentationConnected { get; set; } + public bool isSharingBlackMagic { get; set; } + /// + /// IOS Airplay code + /// + public string password + { + get + { + return _password; + } + set + { + if (value != _password) + { + _password = value; + NotifyPropertyChanged("password"); + } + } + } + public string serverName { get; set; } + public string wifiName { get; set; } + } + + public class NumberOfScreens + { + [JsonProperty("NumberOfCECScreens")] + public int NumOfCECScreens { get; set; } + [JsonProperty("NumberOfScreens")] + public int NumOfScreens { get; set; } + } + + /// + /// AudioInputLine/AudioOutputLine/VideoCameraLine list item + /// + public class AudioVideoInputOutputLineItem + { + public string Alias { get; set; } + public string Name { get; set; } + public bool Selected { get; set; } + public bool combinedDevice { get; set; } + public string id { get; set; } + public bool manuallySelected { get; set; } + public int numberOfCombinedDevices { get; set; } + public int ptzComId { get; set; } + } + + public class Video + { + public bool Optimizable { get; set; } + } + + public class CameraShare : NotifiableObject + { + private bool _canControlCamera; + private bool _isSharing; + + [JsonProperty("can_Control_Camera")] + public bool CanControlCamera + { + get + { + return _canControlCamera; + } + set + { + if (value != _canControlCamera) + { + _canControlCamera = value; + NotifyPropertyChanged("CanControlCamera"); + } + } + } + public string id { get; set; } + public bool is_Mirrored { get; set; } + [JsonProperty("is_Sharing")] + public bool IsSharing + { + get + { + return _isSharing; + } + set + { + if (value != _isSharing) + { + _isSharing = value; + NotifyPropertyChanged("IsSharing"); + } + } + } + public int pan_Tilt_Speed { get; set; } + + } + + public class Layout + { + public bool can_Adjust_Floating_Video { get; set; } + public bool can_Switch_Floating_Share_Content { get; set; } + public bool can_Switch_Share_On_All_Screens { get; set; } + public bool can_Switch_Speaker_View { get; set; } + public bool can_Switch_Wall_View { get; set; } + public bool is_In_First_Page { get; set; } + public bool is_In_Last_Page { get; set; } + public bool is_supported { get; set; } + public int video_Count_In_Current_Page { get; set; } + public string video_type { get; set; } + } + + public class CallRecordInfo + { + public bool canRecord { get; set; } + public bool emailRequired { get; set; } + public bool amIRecording { get; set; } + public bool meetingIsBeingRecorded { get; set; } + } + } + + /// + /// zEvent Class Structure + /// + public class zEvent + { + public class NeedWaitForHost + { + public bool Wait { get; set; } + } + + public class IncomingCallIndication + { + public string callerJID { get; set; } + public string calleeJID { get; set; } + public string meetingID { get; set; } + public string password { get; set; } + public string meetingOption { get; set; } + public long MeetingNumber { get; set; } + public string callerName { get; set; } + public string avatarURL { get; set; } + public int lifeTime { get; set; } + public bool accepted { get; set; } + } + + public class CallConnectError + { + public int error_code { get; set; } + public string error_message { get; set; } + } + + public class CallDisconnect + { + public bool Successful + { + get + { + return success == "on"; + } + } + + public string success { get; set; } + } + + public class Layout + { + public bool Sharethumb { get; set; } + } + + public class Call + { + public Layout Layout { get; set; } + } + + public class Client + { + public Call Call { get; set; } + } + + public enum eSharingState + { + None, + Connecting, + Sending, + Receiving, + Send_Receiving + } + + public class SharingState : NotifiableObject + { + private bool _paused; + private eSharingState _state; + + public bool IsSharing; + + [JsonProperty("paused")] + public bool Paused + { + get + { + return _paused; + } + set + { + if (value != _paused) + { + _paused = value; + NotifyPropertyChanged("Paused"); + } + } + } + [JsonProperty("state")] + public eSharingState State + { + get + { + return _state; + } + set + { + if (value != _state) + { + _state = value; + IsSharing = _state == eSharingState.Sending; + NotifyPropertyChanged("State"); + } + } + } + } + + public class PinStatusOfScreenNotification + { + [JsonProperty("can_be_pinned")] + public bool CanBePinned { get; set; } + [JsonProperty("can_pin_share")] + public bool CanPinShare { get; set; } + [JsonProperty("pinned_share_source_id")] + public int PinnedShareSourceId { get; set; } + [JsonProperty("pinned_user_id")] + public int PinnedUserId { get; set; } + [JsonProperty("screen_index")] + public int ScreenIndex { get; set; } + [JsonProperty("screen_layout")] + public int ScreenLayout { get; set; } + [JsonProperty("share_source_type")] + public int ShareSourceType { get; set; } + [JsonProperty("why_cannot_pin_share")] + public string WhyCannotPinShare { get; set; } + } + + public class PhoneCallStatus:NotifiableObject + { + private bool _isIncomingCall; + private string _peerDisplayName; + private string _peerNumber; + + private bool _offHook; + + public string CallId { get; set; } + public bool IsIncomingCall { + get { return _isIncomingCall; } + set + { + if(value == _isIncomingCall) return; + + _isIncomingCall = value; + NotifyPropertyChanged("IsIncomingCall"); + } } + + public string PeerDisplayName + { + get { return _peerDisplayName; } + set + { + if (value == _peerDisplayName) return; + _peerDisplayName = value; + NotifyPropertyChanged("PeerDisplayName"); + } + } + + public string PeerNumber + { + get { return _peerNumber; } + set + { + if (value == _peerNumber) return; + + _peerNumber = value; + NotifyPropertyChanged("PeerNumber"); + } + } + + public string PeerUri { get; set; } + + private ePhoneCallStatus _status; + public ePhoneCallStatus Status + { + get { return _status; } + set + { + _status = value; + OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted || + _status == ePhoneCallStatus.PhoneCallStatus_InCall || + _status == ePhoneCallStatus.PhoneCallStatus_Init || + _status == ePhoneCallStatus.PhoneCallStatus_Ringing; + } + } + + public bool OffHook + { + get { return _offHook; } + set + { + if (value == _offHook) return; + + _offHook = value; + NotifyPropertyChanged("OffHook"); + } + } + } + + public enum ePhoneCallStatus + { + PhoneCallStatus_Ringing, + PhoneCallStatus_Terminated, + PhoneCallStatus_Accepted, + PhoneCallStatus_InCall, + PhoneCallStatus_Init, + } + } + + /// + /// zConfiguration class structure + /// + public class zConfiguration + { + public class Sharing + { + [JsonProperty("optimize_video_sharing")] + public bool OptimizeVideoSharing { get; set; } + } + + public class Camera : NotifiableObject + { + private bool _mute; + + public bool Mute + { + get { return _mute; } + set + { + Debug.Console(1, "Camera Mute response received: {0}", value); + + if (value == _mute) return; + + _mute = value; + NotifyPropertyChanged("Mute"); + } + } + } + + public class Microphone : NotifiableObject + { + private bool _mute; + + public bool Mute + { + get + { + return _mute; + } + set + { + if(value != _mute) + { + _mute = value; + NotifyPropertyChanged("Mute"); + } + } + } + } + + public enum eLayoutStyle + { + Gallery, + Speaker, + Strip, + ShareAll + } + + public enum eLayoutSize + { + Off, + Size1, + Size2, + Size3, + Strip + } + + public enum eLayoutPosition + { + Center, + Up, + Right, + UpRight, + Down, + DownRight, + Left, + UpLeft, + DownLeft + } + + public class Layout:NotifiableObject + { + public bool ShareThumb { get; set; } + public eLayoutStyle Style { get; set; } + public eLayoutSize Size { get; set; } + + private eLayoutPosition _position; + public eLayoutPosition Position { + get { return _position; } + set + { + _position = value; + NotifyPropertyChanged("Position"); + } } + } + + public class Lock + { + public bool Enable { get; set; } + } + + public class ClosedCaption + { + public bool Visible { get; set; } + public int FontSize { get; set; } + } + + public class MuteUserOnEntry + { + public bool Enable { get; set; } + } + + public class Call + { + public Sharing Sharing { get; set; } + public Camera Camera { get; set; } + public Microphone Microphone { get; set; } + public Layout Layout { get; set; } + public Lock Lock { get; set; } + public MuteUserOnEntry MuteUserOnEntry { get; set; } + public ClosedCaption ClosedCaption { get; set; } + + + public Call() + { + Sharing = new Sharing(); + Camera = new Camera(); + Microphone = new Microphone(); + Layout = new Layout(); + Lock = new Lock(); + MuteUserOnEntry = new MuteUserOnEntry(); + ClosedCaption = new ClosedCaption(); + } + } + + public class Audio + { + public Input Input { get; set; } + public Output Output { get; set; } + + public Audio() + { + Input = new Input(); + Output = new Output(); + } + } + + public class Input : Output + { + [JsonProperty("reduce_reverb")] + public bool ReduceReverb { get; set; } + } + + public class Output : NotifiableObject + { + private int _volume; + + [JsonProperty("volume")] + public int Volume + { + get + { + return _volume; + } + set + { + if (value != _volume) + { + _volume = value; + NotifyPropertyChanged("Volume"); + } + } + } + [JsonProperty("selectedId")] + public string SelectedId { get; set; } + [JsonProperty("is_sap_disabled")] + public bool IsSapDisabled { get; set; } + } + + public class Video : NotifiableObject + { + private bool _hideConfSelfVideo; + + [JsonProperty("hide_conf_self_video")] + public bool HideConfSelfVideo + { + get + { + return _hideConfSelfVideo; + } + set + { + if (value != _hideConfSelfVideo) + { + _hideConfSelfVideo = value; + NotifyPropertyChanged("HideConfSelfVideo"); + } + } + } + + public VideoCamera Camera { get; set; } + + public Video() + { + Camera = new VideoCamera(); + } + } + + public class VideoCamera : NotifiableObject + { + private string _selectedId; + + [JsonProperty("selectedId")] + public string SelectedId { + get + { + return _selectedId; + } + set + { + if (value != _selectedId) + { + _selectedId = value; + NotifyPropertyChanged("SelectedId"); + } + } + + } + public bool Mirror { get; set; } + } + + public class Client + { + public string appVersion { get; set; } + public string deviceSystem { get; set; } + } + + } + + /// + /// zCommand class structure + /// + public class zCommand + { + public class BookingsListResult + { + [JsonProperty("accessRole")] + public string AccessRole { get; set; } + [JsonProperty("calendarChangeKey")] + public string CalendarChangeKey { get; set; } + [JsonProperty("calendarID")] + public string CalendarId { get; set; } + [JsonProperty("checkIn")] + public bool CheckIn { get; set; } + [JsonProperty("creatorEmail")] + public string CreatorEmail { get; set; } + [JsonProperty("creatorName")] + public string CreatorName { get; set; } + [JsonProperty("endTime")] + public DateTime EndTime { get; set; } + [JsonProperty("hostName")] + public string HostName { get; set; } + [JsonProperty("isInstantMeeting")] + public bool IsInstantMeeting { get; set; } + [JsonProperty("isPrivate")] + public bool IsPrivate { get; set; } + [JsonProperty("location")] + public string Location { get; set; } + [JsonProperty("meetingName")] + public string MeetingName { get; set; } + [JsonProperty("meetingNumber")] + public string MeetingNumber { get; set; } + [JsonProperty("scheduledFrom")] + public string ScheduledFrom { get; set; } + [JsonProperty("startTime")] + public DateTime StartTime { get; set; } + [JsonProperty("third_party")] + public ThirdParty ThirdParty { get; set; } + } + + public static List GetGenericMeetingsFromBookingResult(List bookings, + int minutesBeforeMeetingStart) + { + var rv = GetGenericMeetingsFromBookingResult(bookings); + + foreach (var meeting in rv) + { + meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart; + } + + return rv; + } + /// + /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class + /// + /// + /// + public static List GetGenericMeetingsFromBookingResult(List bookings) + { + var meetings = new List(); + + if (Debug.Level > 0) + { + Debug.Console(1, "Meetings List:\n"); + } + + foreach (var b in bookings) + { + var meeting = new Meeting(); + + if (b.MeetingNumber != null) + meeting.Id = b.MeetingNumber; + if (b.CreatorName != null) + meeting.Organizer = b.CreatorName; + if (b.MeetingName != null) + meeting.Title = b.MeetingName; + //if (b.Agenda != null) + // meeting.Agenda = b.Agenda.Value; + if (b.StartTime != null) + meeting.StartTime = b.StartTime; + if (b.EndTime != null) + meeting.EndTime = b.EndTime; + + meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public; + + // No meeting.Calls data exists for Zoom Rooms. Leaving out for now. + var now = DateTime.Now; + if (meeting.StartTime < now && meeting.EndTime < now) + { + Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title); + continue; + } + + meetings.Add(meeting); + + if (Debug.Level > 0) + { + Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer); + Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration); + Debug.Console(1, " Joinable: {0}\n", meeting.Joinable); + } + } + + meetings.OrderBy(m => m.StartTime); + + return meetings; + } + + public class HandStatus + { + [JsonProperty("is_raise_hand")] + public bool IsRaiseHand { get; set; } + [JsonProperty("optimize_vis_validideo_sharing")] + public string IsValid { get; set; } + [JsonProperty("time_stamp")] + public string TimeStamp { get; set; } + } + + public class ListParticipant + { + [JsonProperty("audio_status state")] + public string AudioStatusState { get; set; } + [JsonProperty("audio_status type")] + public string AudioStatusType { get; set; } + [JsonProperty("avatar_url")] + public string AvatarUrl { get; set; } + [JsonProperty("camera_status am_i_controlling")] + public bool CameraStatusAmIControlling { get; set; } + [JsonProperty("camera_status can_i_request_control")] + public bool CameraStatusCanIRequestConrol { get; set; } + [JsonProperty("camera_status can_move_camera")] + public bool CameraStatusCanMoveCamera { get; set; } + [JsonProperty("camera_status can_switch_camera")] + public bool CameraStatusCanSwitchCamera { get; set; } + [JsonProperty("camera_status can_zoom_camera")] + public bool CameraStatusCanZoomCamera { get; set; } + [JsonProperty("can_edit_closed_caption")] + public bool CanEditClosedCaption { get; set; } + [JsonProperty("can_record")] + public bool CanRecord { get; set; } + [JsonProperty("event")] + public string Event { get; set; } + [JsonProperty("hand_status")] + public HandStatus HandStatus { get; set; } + [JsonProperty("isCohost")] + public bool IsCohost { get; set; } + [JsonProperty("is_client_support_closed_caption")] + public bool IsClientSupportClosedCaption { get; set; } + [JsonProperty("is_client_support_coHost")] + public bool IsClientSupportCoHost { get; set; } + [JsonProperty("is_host")] + public bool IsHost { get; set; } + [JsonProperty("is_myself")] + public bool IsMyself { get; set; } + [JsonProperty("is_recording")] + public bool IsRecording { get; set; } + [JsonProperty("is_video_can_mute_byHost")] + public bool IsVideoCanMuteByHost { get; set; } + [JsonProperty("is_video_can_unmute_byHost")] + public bool IsVideoCanUnmuteByHost { get; set; } + [JsonProperty("local_recording_disabled")] + public bool LocalRecordingDisabled { get; set; } + [JsonProperty("user_id")] + public int UserId { get; set; } + [JsonProperty("user_name")] + public string UserName { get; set; } + [JsonProperty("user_type")] + public string UserType { get; set; } + [JsonProperty("video_status has_source")] + public bool VideoStatusHasSource { get; set; } + [JsonProperty("video_status is_receiving")] + public bool VideoStatusIsReceiving { get; set; } + [JsonProperty("video_status is_sending")] + public bool VideoStatusIsSending { get; set; } + + public ListParticipant() + { + HandStatus = new HandStatus(); + } + + public static List GetGenericParticipantListFromParticipantsResult( + List participants) + { + return + participants.Select( + p => + new Participant + { + Name = p.UserName, + IsHost = p.IsHost, + CanMuteVideo = p.IsVideoCanMuteByHost, + CanUnmuteVideo = p.IsVideoCanUnmuteByHost, + AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", + VideoMuteFb = p.VideoStatusIsSending + }).ToList(); + } + } + + public class CallinCountryList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class CalloutCountryList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class TollFreeCallinList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class Info + { + public List callin_country_list { get; set; } + public List callout_country_list { get; set; } + public List toll_free_callin_list { get; set; } + } + + public class ThirdParty + { + public string h323_address { get; set; } + public string meeting_number { get; set; } + public string service_provider { get; set; } + public string sip_address { get; set; } + } + + public class MeetingListItem + { + public string accessRole { get; set; } + public string calendarChangeKey { get; set; } + public string calendarID { get; set; } + public bool checkIn { get; set; } + public string creatorEmail { get; set; } + public string creatorName { get; set; } + public string endTime { get; set; } + public string hostName { get; set; } + public bool isInstantMeeting { get; set; } + public bool isPrivate { get; set; } + public string location { get; set; } + public string meetingName { get; set; } + public string meetingNumber { get; set; } + public string scheduledFrom { get; set; } + public string startTime { get; set; } + public ThirdParty third_party { get; set; } + + public MeetingListItem() + { + third_party = new ThirdParty(); + } + } + + public class InfoResult + { + public Info Info { get; set; } + public bool am_i_original_host { get; set; } + public string default_callin_country { get; set; } + public string dialIn { get; set; } + public string international_url { get; set; } + public string invite_email_content { get; set; } + public string invite_email_subject { get; set; } + public bool is_callin_country_list_available { get; set; } + public bool is_calling_room_system_enabled { get; set; } + public bool is_toll_free_callin_list_available { get; set; } + public bool is_view_only { get; set; } + public bool is_waiting_room { get; set; } + public bool is_webinar { get; set; } + public string meeting_id { get; set; } + public MeetingListItem meeting_list_item { get; set; } + public string meeting_password { get; set; } + public string meeting_type { get; set; } + public int my_userid { get; set; } + public int participant_id { get; set; } + public string real_meeting_id { get; set; } + public string schedule_option { get; set; } + public string schedule_option2 { get; set; } + public string support_callout_type { get; set; } + public string toll_free_number { get; set; } + public string user_type { get; set; } + + public InfoResult() + { + Info = new Info(); + meeting_list_item = new MeetingListItem(); + } + } + + public class Phonebook + { + public List Contacts { get; set; } + public int Limit { get; set; } + public int Offset { get; set; } + } + } } \ No newline at end of file From f0a3b27e3b254b91f192c9d1a5c4b498bb1c807f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 17 Dec 2020 14:28:27 -0700 Subject: [PATCH 049/480] Adds dummy source and room power on implementation --- .../Room/Config/EssentialsTechRoomConfig.cs | 3 +++ .../Room/Types/EssentialsTechRoom.cs | 26 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 292a6b7c..06e67f39 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -5,6 +5,9 @@ namespace PepperDash.Essentials.Room.Config { public class EssentialsTechRoomConfig { + [JsonProperty("dummySourceKey")] + public string DummySourceKey { get; set; } + [JsonProperty("displays")] public List Displays; diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 515a4355..d0de145d 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -28,8 +28,6 @@ namespace PepperDash.Essentials private Dictionary _currentPresets; private ScheduledEventGroup _roomScheduledEventGroup; - private GenericSource DummySource = new GenericSource("$off", "Dummy Source"); - public EssentialsTechRoom(DeviceConfig config) : base(config) { _config = config.Properties.ToObject(); @@ -243,9 +241,17 @@ namespace PepperDash.Essentials public void RoomPowerOn() { + var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs; + + if (dummySource == null) + { + Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey); + return; + } + foreach (var display in _displays) { - + RunDirectRoute(dummySource, display.Value); } } @@ -388,7 +394,7 @@ namespace PepperDash.Essentials return; } - if (source.Key.Equals("$off", StringComparison.OrdinalIgnoreCase)) + if (source == null) { dest.ReleaseRoute(); if (dest is IHasPowerControl) @@ -396,11 +402,6 @@ namespace PepperDash.Essentials } else { - if (source == null) - { - Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", source.Key, dest.Key); - return; - } dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video); } } @@ -418,11 +419,14 @@ namespace PepperDash.Essentials var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs; + if (source == null || dest == null) + { + Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey); + return; + } RunDirectRoute(source, dest); } - - #endregion } From b2402402d9266e18fa396a356d5d5cbbbff0a9d2 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 17 Dec 2020 14:48:01 -0700 Subject: [PATCH 050/480] remove dummy device add --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 -- .../PepperDashEssentialsBase/Display/DisplayBase.cs | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index d0de145d..f0191839 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -48,8 +48,6 @@ namespace PepperDash.Essentials SubscribeToDisplayFeedbacks(); CreateOrUpdateScheduledEvents(); - - DeviceManager.AddDevice(DummySource); } public Dictionary CurrentPresetsFeedbacks { get; private set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs index e4a2cb26..f1b96ac4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/DisplayBase.cs @@ -81,8 +81,6 @@ namespace PepperDash.Essentials.Core } - - public abstract void PowerOn(); public abstract void PowerOff(); public abstract void PowerToggle(); @@ -99,7 +97,7 @@ namespace PepperDash.Essentials.Core } } - public abstract void ExecuteSwitch(object selector); + public abstract void ExecuteSwitch(object selector); protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) @@ -315,7 +313,5 @@ namespace PepperDash.Essentials.Core var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); } - - } } \ No newline at end of file From aa61479adc50f992183b8d3cd57407f7400e5511 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 18 Dec 2020 09:16:40 -0700 Subject: [PATCH 051/480] remove device info stuff from DGE for now --- .../Essentials_DM/Endpoints/DGEs/Dge100Controller.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs index d7996554..39e549cc 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs @@ -39,12 +39,12 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs { _dge = device; _dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs; - _dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo(); + //_dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo(); _dgeEthernetInfo.Use(); DeviceInfo = new DeviceInfo(); - _dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; + //_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; _dc = dc; From 870f2f8fa641d805999b594f8a460deb054adb48 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 18 Dec 2020 14:34:15 -0700 Subject: [PATCH 052/480] properly defines the IsWarming/Cooling FeedbackFuncs and fires feedbacks --- .../Room/Types/EssentialsTechRoom.cs | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index f0191839..a2943528 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -28,6 +28,33 @@ namespace PepperDash.Essentials private Dictionary _currentPresets; private ScheduledEventGroup _roomScheduledEventGroup; + /// + /// + /// + protected override Func IsWarmingFeedbackFunc + { + get + { + return () => + { + return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue); + }; + } + } + /// + /// + /// + protected override Func IsCoolingFeedbackFunc + { + get + { + return () => + { + return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue); + }; + } + } + public EssentialsTechRoom(DeviceConfig config) : base(config) { _config = config.Properties.ToObject(); @@ -111,7 +138,12 @@ namespace PepperDash.Essentials foreach (var display in _displays) { display.Value.PowerIsOnFeedback.OutputChange += - (sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate(); + (sender, args) => + { + RoomPowerIsOnFeedback.InvokeFireUpdate(); + IsWarmingUpFeedback.InvokeFireUpdate(); + IsCoolingDownFeedback.InvokeFireUpdate(); + }; } } @@ -281,16 +313,6 @@ namespace PepperDash.Essentials #region Overrides of EssentialsRoomBase - protected override Func IsWarmingFeedbackFunc - { - get { return () => false; } - } - - protected override Func IsCoolingFeedbackFunc - { - get { return () => false; } - } - protected override Func OnFeedbackFunc { get { return () => RoomPowerIsOn; } From 0a34f48e0a3b45ffbb8dfc0f3b02f2413eab2800 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Fri, 18 Dec 2020 17:07:20 -0500 Subject: [PATCH 053/480] Fixes for the static GetPropertyByName method in DeviceJsonApi...now returns a property object rather than a PropertyInfo object --- .../PepperDashEssentialsBase/Devices/DeviceJsonApi.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs index c7bc7c68..51d5882f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs @@ -83,13 +83,13 @@ namespace PepperDash.Essentials.Core /// public static object GetPropertyByName(string deviceObjectPath, string propertyName) { - var obj = FindObjectOnPath(deviceObjectPath); - if(obj == null) + var dev = FindObjectOnPath(deviceObjectPath); + if(dev == null) return "{ \"error\":\"No Device\"}"; + + object prop = dev.GetType().GetCType().GetProperty(propertyName).GetValue(dev, null); - CType t = obj.GetType(); - - var prop = t.GetProperty(propertyName); + // var prop = t.GetProperty(propertyName); if (prop != null) { return prop; From 0f924360c11f60e39ec6527ef411908789a8bf77 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 10:51:12 -0700 Subject: [PATCH 054/480] fix issues in LinkToApi --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index a2943528..0a47933e 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -380,6 +380,8 @@ namespace PepperDash.Essentials feedback.Value.FireUpdate(); } }; + + return; } i = 0; @@ -388,6 +390,8 @@ namespace PepperDash.Essentials var tuner = setTopBox; trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + + i++; } } From 0a43f43f665704ae8edf87f4732a1958508aaee1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 12:31:00 -0700 Subject: [PATCH 055/480] add ICommunicationMonitor to EiscApiAdvanced --- .../Bridges/BridgeBase.cs | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 86db81ba..33285bff 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core.Bridges /// /// Bridge API using EISC /// - public class EiscApiAdvanced : BridgeApi + public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor { public EiscApiPropertiesConfig PropertiesConfig { get; private set; } @@ -89,6 +89,7 @@ namespace PepperDash.Essentials.Core.Bridges public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) : base(dc.Key) { + CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); JoinMaps = new Dictionary(); PropertiesConfig = dc.Properties.ToObject(); @@ -100,6 +101,19 @@ namespace PepperDash.Essentials.Core.Bridges AddPostActivationAction(LinkDevices); AddPostActivationAction(LinkRooms); + AddPostActivationAction(RegisterEisc); + } + + public override bool CustomActivate() + { + CommunicationMonitor.Start(); + return base.CustomActivate(); + } + + public override bool Deactivate() + { + CommunicationMonitor.Stop(); + return base.Deactivate(); } private void LinkDevices() @@ -137,8 +151,6 @@ namespace PepperDash.Essentials.Core.Bridges bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this); } } - - RegisterEisc(); } private void RegisterEisc() @@ -182,8 +194,6 @@ namespace PepperDash.Essentials.Core.Bridges rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this); } - - RegisterEisc(); } /// @@ -324,6 +334,12 @@ namespace PepperDash.Essentials.Core.Bridges Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e); } } + + #region Implementation of ICommunicationMonitor + + public StatusMonitorBase CommunicationMonitor { get; private set; } + + #endregion } public class EiscApiPropertiesConfig From cc159e306e1295a2aa277f40dd4e0cc060f39148 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 14:40:19 -0700 Subject: [PATCH 056/480] update Essentials to use PepperDash Core 1.0.43 --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec | 2 +- packages.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec index 5db86afc..dff167ed 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec @@ -14,7 +14,7 @@ crestron 3series 4series - + diff --git a/packages.config b/packages.config index c138dd1b..67789ca5 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From ae03b8cd7e1e368619fc32160fc577b89ec0b537 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 16:19:45 -0700 Subject: [PATCH 057/480] fix PresetsList saving to file --- .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 85e5dfdb..d6a9fad0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -266,14 +266,13 @@ namespace PepperDash.Essentials.Core.Presets try { _fileOps.Enter(); - var json = JsonConvert.SerializeObject(PresetsList); + var pl = new PresetsList {Channels = PresetsList, Name = Name}; + var json = JsonConvert.SerializeObject(pl, Formatting.Indented); using (var file = File.Open(_filePath, FileMode.Truncate)) { file.Write(json, Encoding.UTF8); } - - } finally { From 3b0a5285ab5d8d4f4e99397582a1337eade40a9a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 17:00:37 -0700 Subject: [PATCH 058/480] fix order for comm monitor --- .../PepperDashEssentialsBase/Bridges/BridgeBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 33285bff..11ede5a1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -89,7 +89,6 @@ namespace PepperDash.Essentials.Core.Bridges public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) : base(dc.Key) { - CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); JoinMaps = new Dictionary(); PropertiesConfig = dc.Properties.ToObject(); @@ -99,6 +98,8 @@ namespace PepperDash.Essentials.Core.Bridges Eisc.SigChange += Eisc_SigChange; + CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); + AddPostActivationAction(LinkDevices); AddPostActivationAction(LinkRooms); AddPostActivationAction(RegisterEisc); From 7196d0aba8edca612d25aa093e37e1ba1b6f7cd9 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 29 Dec 2020 20:20:49 -0700 Subject: [PATCH 059/480] Adds FusionRoomJoinMap and ability to set IPID and JoinMapKey from config --- PepperDashEssentials/ControlSystem.cs | 20 ++- .../EssentialsHuddleVtc1FusionController.cs | 6 +- .../Room/Config/EssentialsRoomConfig.cs | 29 +++ .../Bridges/JoinMaps/AppleTvJoinMap.cs | 4 +- ...lsHuddleSpaceFusionSystemControllerBase.cs | 169 ++++++++++-------- .../Fusion/FusionRoomJoinMap.cs | 122 +++++++++++++ .../JoinMaps/JoinMapBase.cs | 7 +- .../PepperDash_Essentials_Core.csproj | 1 + 8 files changed, 270 insertions(+), 88 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 58a545f2..9bec571e 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -432,12 +432,26 @@ namespace PepperDash.Essentials var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; if (room != null) { + // default IPID + uint fusionIpId = 0xf1; + + // default to no join map key + string fusionJoinMapKey = string.Empty; + + var fusionConfig = room.Config.Properties["fusion"].ToObject(); + + if (fusionConfig != null) + { + fusionIpId = fusionConfig.IpIdInt; + fusionJoinMapKey = fusionConfig.JoinMapKey; + } + if (room is EssentialsHuddleSpaceRoom) { DeviceManager.AddDevice(room); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, 0xf1)); + DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -449,7 +463,7 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -461,7 +475,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase(room, 0xF1)); + DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 8d9da386..89059cbe 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -16,8 +16,8 @@ namespace PepperDash.Essentials.Fusion { BooleanSigData CodecIsInCall; - public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId) - : base(room, ipId) + public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey) + : base(room, ipId, joinMapKey) { } @@ -166,7 +166,7 @@ namespace PepperDash.Essentials.Fusion CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); // Room to fusion room Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 79844ce4..201b583c 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -177,6 +177,9 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("volumes")] public EssentialsRoomVolumesConfig Volumes { get; set; } + [JsonProperty("fusion")] + public EssentialsRoomFusionConfig Fusion { get; set; } + [JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")] public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; } @@ -220,6 +223,32 @@ namespace PepperDash.Essentials.Room.Config } + public class EssentialsRoomFusionConfig + { + public uint IpIdInt + { + get + { + try + { + return Convert.ToUInt32(IpId, 16); + } + catch (Exception) + { + throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId)); + } + + } + } + + [JsonProperty("ipId")] + public string IpId { get; set; } + + [JsonProperty("joinMapKey")] + public string JoinMapKey { get; set; } + + } + public class EssentialsRoomMicrophonePrivacyConfig { [JsonProperty("deviceKey")] diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs index 070e8f61..478f4e29 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AppleTvJoinMap.cs @@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges /// Join this join map will start at /// Type of the child join map public AppleTvJoinMap(uint joinStart, Type type) : base(joinStart, type) - { - } + { + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index dcc86635..afaee291 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -16,6 +16,8 @@ namespace PepperDash.Essentials.Core.Fusion { public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider { + FusionRoomJoinMap JoinMap; + private const string RemoteOccupancyXml = "Local{0}"; private readonly bool _guidFileExists; @@ -84,11 +86,19 @@ namespace PepperDash.Essentials.Core.Fusion #endregion - public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId) + public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey) : base(room.Key + "-fusion") { try { + JoinMap = new FusionRoomJoinMap(1); + + if (!string.IsNullOrEmpty(joinMapKey)) + { + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + JoinMap.SetCustomJoinData(customJoins); + } + Room = room; _ipId = ipId; @@ -319,7 +329,7 @@ namespace PepperDash.Essentials.Core.Fusion "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", + CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); @@ -327,7 +337,7 @@ namespace PepperDash.Essentials.Core.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.CurrentRoomSourceName.JoinNumber, "Display 1 - Current Source", eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange; @@ -377,24 +387,24 @@ namespace PepperDash.Essentials.Core.Fusion var response = string.Empty; - var systemReboot = FusionRoom.CreateOffsetBoolSig(74, "Processor - Reboot", eSigIoMask.OutputSigOnly); + var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, "Processor - Reboot", eSigIoMask.OutputSigOnly); systemReboot.OutputSig.SetSigFalseAction( () => CrestronConsole.SendControlSystemCommand("reboot", ref response)); } protected void SetUpEthernetValues() { - _ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); - _ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); - _gateway = FusionRoom.CreateOffsetStringSig(52, "Info - Processor - Gateway", eSigIoMask.InputSigOnly); - _hostname = FusionRoom.CreateOffsetStringSig(53, "Info - Processor - Hostname", eSigIoMask.InputSigOnly); - _domain = FusionRoom.CreateOffsetStringSig(54, "Info - Processor - Domain", eSigIoMask.InputSigOnly); - _dns1 = FusionRoom.CreateOffsetStringSig(55, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly); - _dns2 = FusionRoom.CreateOffsetStringSig(56, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly); - _mac1 = FusionRoom.CreateOffsetStringSig(57, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly); - _mac2 = FusionRoom.CreateOffsetStringSig(58, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly); - _netMask1 = FusionRoom.CreateOffsetStringSig(59, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly); - _netMask2 = FusionRoom.CreateOffsetStringSig(60, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly); + _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); + _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); + _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, "Info - Processor - Gateway", eSigIoMask.InputSigOnly); + _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, "Info - Processor - Hostname", eSigIoMask.InputSigOnly); + _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, "Info - Processor - Domain", eSigIoMask.InputSigOnly); + _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly); + _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly); + _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly); + _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly); + _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly); + _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly); } protected void GetProcessorEthernetValues() @@ -447,13 +457,13 @@ namespace PepperDash.Essentials.Core.Fusion protected void GetProcessorInfo() { - _firmware = FusionRoom.CreateOffsetStringSig(61, "Info - Processor - Firmware", eSigIoMask.InputSigOnly); + _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, "Info - Processor - Firmware", eSigIoMask.InputSigOnly); if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) { for (var i = 0; i < Global.ControlSystem.NumProgramsSupported; i++) { - var join = 62 + i; + var join = JoinMap.ProgramNameStart.JoinNumber + i; var progNum = i + 1; _program[i] = FusionRoom.CreateOffsetStringSig((uint) join, string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly); @@ -484,57 +494,60 @@ namespace PepperDash.Essentials.Core.Fusion { if (args.DeviceOnLine) { - CrestronEnvironment.Sleep(200); - - // Send Push Notification Action request: - - const string requestId = "InitialPushRequest"; - - - var actionRequest = - string.Format("\n{0}\n", requestId) + - "RegisterPushModel\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n"; - - Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest); - - FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest; - - GetCustomProperties(); - - // Request current Fusion Server Time - RequestLocalDateTime(null); - - // Setup timer to request time daily - if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed) + CrestronInvoke.BeginInvoke((o) => { - _dailyTimeRequestTimer.Stop(); - _dailyTimeRequestTimer.Dispose(); - } + CrestronEnvironment.Sleep(200); - _dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000); + // Send Push Notification Action request: - _dailyTimeRequestTimer.Reset(86400000, 86400000); + const string requestId = "InitialPushRequest"; + + + var actionRequest = + string.Format("\n{0}\n", requestId) + + "RegisterPushModel\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n"; + + Debug.Console(2, this, "Sending Fusion ActionRequest: \n{0}", actionRequest); + + FusionRoom.ExtenderFusionRoomDataReservedSigs.ActionQuery.StringValue = actionRequest; + + GetCustomProperties(); + + // Request current Fusion Server Time + RequestLocalDateTime(null); + + // Setup timer to request time daily + if (_dailyTimeRequestTimer != null && !_dailyTimeRequestTimer.Disposed) + { + _dailyTimeRequestTimer.Stop(); + _dailyTimeRequestTimer.Dispose(); + } + + _dailyTimeRequestTimer = new CTimer(RequestLocalDateTime, null, 86400000, 86400000); + + _dailyTimeRequestTimer.Reset(86400000, 86400000); + }); } } @@ -641,7 +654,7 @@ namespace PepperDash.Essentials.Core.Fusion /// /// Creates and Ad Hoc meeting with a duration of 1 hour, or until the next meeting if in less than 1 hour. /// - public void CreateAsHocMeeting(string command) + public void CreateAdHocMeeting(string command) { const string requestId = "CreateAdHocMeeting"; @@ -1031,9 +1044,9 @@ namespace PepperDash.Essentials.Core.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source TV " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; - if (i > 5) // We only have five spots + if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots { break; } @@ -1043,9 +1056,9 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source DVD " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; - if (i > 5) // We only have five spots + if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots { break; } @@ -1055,9 +1068,9 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source Laptop " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; - if (i > 10) // We only have ten spots??? + if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? { break; } @@ -1180,12 +1193,12 @@ namespace PepperDash.Essentials.Core.Fusion { attrNum = attrNum + touchpanelNum; - if (attrNum > 10) + if (attrNum > JoinMap.XpanelOnlineStart.JoinSpan) { continue; } attrName = "Online - XPanel " + attrNum; - attrNum += 160; + attrNum += JoinMap.XpanelOnlineStart.JoinNumber; touchpanelNum++; } @@ -1193,12 +1206,12 @@ namespace PepperDash.Essentials.Core.Fusion { attrNum = attrNum + xpanelNum; - if (attrNum > 10) + if (attrNum > JoinMap.TouchpanelOnlineStart.JoinSpan) { continue; } attrName = "Online - Touch Panel " + attrNum; - attrNum += 150; + attrNum += JoinMap.TouchpanelOnlineStart.JoinNumber; xpanelNum++; } @@ -1208,12 +1221,12 @@ namespace PepperDash.Essentials.Core.Fusion if (dev is DisplayBase) { attrNum = attrNum + displayNum; - if (attrNum > 10) + if (attrNum > JoinMap.DisplayOnlineStart.JoinSpan) { continue; } attrName = "Online - Display " + attrNum; - attrNum += 170; + attrNum += JoinMap.DisplayOnlineStart.JoinNumber; displayNum++; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs new file mode 100644 index 00000000..2d220cf9 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core.Bridges; + + +namespace PepperDash.Essentials.Core.Fusion +{ + public class FusionRoomJoinMap : JoinMapBaseAdvanced + { + + // Processor Attributes + [JoinName("ProcessorIp1")] + public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor IP Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorIp2")] + public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor IP Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorGateway")] + public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor Gateway Address", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorHostname")] + public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorDomain")] + public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorDns1")] + public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorDns2")] + public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorMac1")] + public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor MAC Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorMac2")] + public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor MAC Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorNetMask1")] + public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor NetMask Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorNetMask2")] + public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor NetMask Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorFirmware")] + public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor Firmware Version", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProgramNameStart")] + public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10 }, + new JoinMetadata { Description = "Program Names", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("ProcessorReboot")] + public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1 }, + new JoinMetadata { Description = "Processor Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital }); + + + // Source Attributes + [JoinName("CurrentRoomSourceName")] + public JoinDataComplete CurrentRoomSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1 }, + new JoinMetadata { Description = "Current Room Source Name", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("TouchpanelOnlineStart")] + public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10 }, + new JoinMetadata { Description = "Touchpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + + [JoinName("XpanelOnlineStart")] + public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 10 }, + new JoinMetadata { Description = "Xpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + + [JoinName("DisplayOnlineStart")] + public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10 }, + new JoinMetadata { Description = "Display Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + + [JoinName("Display1LaptopSourceStart")] + public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 10 }, + new JoinMetadata { Description = "Display 1 - Source Laptop Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + + [JoinName("Display1DiscPlayerSourceStart")] + public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5 }, + new JoinMetadata { Description = "Display 1 - Source Disc Player Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + + [JoinName("Display1SetTopBoxSourceStart")] + public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5 }, + new JoinMetadata { Description = "Display 1 - Source TV Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + + + /// + /// Constructor to use when instantiating this Join Map without inheriting from it + /// + /// Join this join map will start at + public FusionRoomJoinMap(uint joinStart) + : base(joinStart, typeof(FusionRoomJoinMap)) + { + + } + + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + public FusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index ad5df2e3..de932918 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -327,7 +327,10 @@ namespace PepperDash.Essentials.Core None = 0, ToSIMPL = 1, FromSIMPL = 2, - ToFromSIMPL = ToSIMPL | FromSIMPL + ToFromSIMPL = ToSIMPL | FromSIMPL, + ToFusion = 4, + FromFusion = 8, + ToFromFusion = ToFusion | FromFusion, } [Flags] @@ -340,7 +343,7 @@ namespace PepperDash.Essentials.Core DigitalAnalog = Digital | Analog, DigitalSerial = Digital | Serial, AnalogSerial = Analog | Serial, - DigitalAnalogSerial = Digital | Analog | Serial + DigitalAnalogSerial = Digital | Analog | Serial, } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 49f4b25a..0443bd7f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -220,6 +220,7 @@ + From 708ee1a8ffeabcf7e1910be855908135853a31f2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 30 Dec 2020 17:01:55 -0700 Subject: [PATCH 060/480] #535 Wraps up EssentialsHuddleSpaceFusionSystemControllerBase. Starts on Vtc1FusionController --- .../Fusion/EssentialsHuddleVtc1FusionController.cs | 2 +- ...sentialsHuddleSpaceFusionSystemControllerBase.cs | 10 +++++----- .../Fusion/FusionRoomJoinMap.cs | 13 +++++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 89059cbe..275d7ebe 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -55,7 +55,7 @@ namespace PepperDash.Essentials.Fusion // Map FusionRoom Attributes: // Codec volume - var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); + var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, "Volume - Fader01", eSigIoMask.InputOutputSig); codecVolume.OutputSig.UserObject = new Action(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index afaee291..ef30e153 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core.Fusion { public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider { - FusionRoomJoinMap JoinMap; + protected FusionRoomJoinMap JoinMap; private const string RemoteOccupancyXml = "Local{0}"; private readonly bool _guidFileExists; @@ -494,7 +494,7 @@ namespace PepperDash.Essentials.Core.Fusion { if (args.DeviceOnLine) { - CrestronInvoke.BeginInvoke((o) => + CrestronInvoke.BeginInvoke( (o) => { CrestronEnvironment.Sleep(200); @@ -1303,7 +1303,7 @@ namespace PepperDash.Essentials.Core.Fusion FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; - MapDisplayToRoomJoins(1, 158, defaultDisplay); + MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay); var deviceConfig = @@ -1359,7 +1359,7 @@ namespace PepperDash.Essentials.Core.Fusion /// /// /// a - protected virtual void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) + protected virtual void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display) { var displayName = string.Format("Display {0} - ", displayIndex); @@ -1370,7 +1370,7 @@ namespace PepperDash.Essentials.Core.Fusion return; } // Display volume - var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", + var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, "Volume - Fader01", eSigIoMask.InputOutputSig); defaultDisplayVolume.OutputSig.UserObject = new Action(b => { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs index 2d220cf9..17ed10a8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs @@ -69,12 +69,20 @@ namespace PepperDash.Essentials.Core.Fusion public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1 }, new JoinMetadata { Description = "Processor Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital }); + // Volume Controls + [JoinName("VolumeFader1")] + public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, + new JoinMetadata { Description = "Volume - Fader 1", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog }); + + // Source Attributes [JoinName("CurrentRoomSourceName")] public JoinDataComplete CurrentRoomSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1 }, new JoinMetadata { Description = "Current Room Source Name", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + // Device Online Status [JoinName("TouchpanelOnlineStart")] public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10 }, new JoinMetadata { Description = "Touchpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); @@ -99,6 +107,11 @@ namespace PepperDash.Essentials.Core.Fusion public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5 }, new JoinMetadata { Description = "Display 1 - Source TV Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + // Display 1 + [JoinName("Display1Start")] + public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 }, + new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + /// /// Constructor to use when instantiating this Join Map without inheriting from it From de4f003c67acca043867a9aac3aee4ff6f887300 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 4 Jan 2021 12:10:12 -0700 Subject: [PATCH 061/480] Swapped out hardcoded joins for join map in Vtc1FusionController --- .../EssentialsHuddleVtc1FusionController.cs | 24 ++++++++--------- ...lsHuddleSpaceFusionSystemControllerBase.cs | 4 +-- ...ntialsHuddleSpaceRoomFusionRoomJoinMap.cs} | 27 ++++++++++++++----- .../PepperDash_Essentials_Core.csproj | 2 +- 4 files changed, 36 insertions(+), 21 deletions(-) rename essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/{FusionRoomJoinMap.cs => EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs} (82%) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 275d7ebe..8028271e 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -60,14 +60,14 @@ namespace PepperDash.Essentials.Fusion (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); // In Call Status - CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); + CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); codec.CallStatusChange += new EventHandler(codec_CallStatusChange); // Online status if (codec is ICommunicationMonitor) { var c = codec as ICommunicationMonitor; - var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly); + var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, "Online - VC 1", eSigIoMask.InputSigOnly); codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; c.CommunicationMonitor.StatusChange += (o, a) => { @@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion if (codecHasIpInfo) { - codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly); + codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, "IP Address - VC", eSigIoMask.InputSigOnly); codecIpAddressSig.InputSig.StringValue = codecIpAddress; - codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly); + codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, "IP Port - VC", eSigIoMask.InputSigOnly); codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); } @@ -172,7 +172,7 @@ namespace PepperDash.Essentials.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly); + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.CurrentRoomSourceName.JoinNumber, "Display 1 - Current Source", eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; @@ -197,9 +197,9 @@ namespace PepperDash.Essentials.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source TV " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; - if (i > 5) // We only have five spots + if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots break; } @@ -207,7 +207,7 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source DVD " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > 5) // We only have five spots break; @@ -217,9 +217,9 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs("Display 1 - Source Laptop " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; - if (i > 10) // We only have ten spots??? + if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? break; } @@ -283,7 +283,7 @@ namespace PepperDash.Essentials.Fusion if (defaultDisplay is IDisplayUsage) (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); - MapDisplayToRoomJoins(1, 158, defaultDisplay); + MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay); var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); @@ -328,7 +328,7 @@ namespace PepperDash.Essentials.Fusion } - protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) + protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display) { string displayName = string.Format("Display {0} - ", displayIndex); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index ef30e153..2ca546cc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core.Fusion { public class EssentialsHuddleSpaceFusionSystemControllerBase : Device, IOccupancyStatusProvider { - protected FusionRoomJoinMap JoinMap; + protected EssentialsHuddleSpaceRoomFusionRoomJoinMap JoinMap; private const string RemoteOccupancyXml = "Local{0}"; private readonly bool _guidFileExists; @@ -91,7 +91,7 @@ namespace PepperDash.Essentials.Core.Fusion { try { - JoinMap = new FusionRoomJoinMap(1); + JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1); if (!string.IsNullOrEmpty(joinMapKey)) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs similarity index 82% rename from essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs rename to essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs index 17ed10a8..d388f464 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionRoomJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs @@ -9,7 +9,7 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core.Fusion { - public class FusionRoomJoinMap : JoinMapBaseAdvanced + public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced { // Processor Attributes @@ -74,7 +74,22 @@ namespace PepperDash.Essentials.Core.Fusion public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, new JoinMetadata { Description = "Volume - Fader 1", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog }); + // Codec Info + [JoinName("VcCodecInCall")] + public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1 }, + new JoinMetadata { Description = "VC Codec In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + [JoinName("VcCodecOnline")] + public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1 }, + new JoinMetadata { Description = "VC Codec Online", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + + [JoinName("VcCodecIpAddress")] + public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata { Description = "VC Codec IP Address", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + + [JoinName("VcCodecIpPort")] + public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1 }, + new JoinMetadata { Description = "VC Codec IP Port", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); // Source Attributes [JoinName("CurrentRoomSourceName")] @@ -88,7 +103,7 @@ namespace PepperDash.Essentials.Core.Fusion new JoinMetadata { Description = "Touchpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("XpanelOnlineStart")] - public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 10 }, + public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5 }, new JoinMetadata { Description = "Xpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("DisplayOnlineStart")] @@ -96,7 +111,7 @@ namespace PepperDash.Essentials.Core.Fusion new JoinMetadata { Description = "Display Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("Display1LaptopSourceStart")] - public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 10 }, + public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5 }, new JoinMetadata { Description = "Display 1 - Source Laptop Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); [JoinName("Display1DiscPlayerSourceStart")] @@ -117,8 +132,8 @@ namespace PepperDash.Essentials.Core.Fusion /// Constructor to use when instantiating this Join Map without inheriting from it /// /// Join this join map will start at - public FusionRoomJoinMap(uint joinStart) - : base(joinStart, typeof(FusionRoomJoinMap)) + public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart) + : base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap)) { } @@ -128,7 +143,7 @@ namespace PepperDash.Essentials.Core.Fusion /// /// Join this join map will start at /// Type of the child join map - public FusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type) + public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type) { } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 0443bd7f..e97d30f7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -220,7 +220,7 @@ - + From 4a642b1e3684e17e738a3416a488c17bd1567848 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 4 Jan 2021 16:19:08 -0700 Subject: [PATCH 062/480] Adds UserObject for future use purposes --- .../PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index de932918..3abfb8c7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -411,6 +411,8 @@ namespace PepperDash.Essentials.Core /// [JsonProperty("joinSpan")] public uint JoinSpan { get; set; } + + } /// @@ -422,6 +424,10 @@ namespace PepperDash.Essentials.Core private JoinData _data; public JoinMetadata Metadata { get; set; } + /// + /// To store some future information as you please + /// + public object UserObject { get; private set; } public JoinDataComplete(JoinData data, JoinMetadata metadata) { From d311b6fef9b1747bc2cb444751da8fe4433174b8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 5 Jan 2021 18:21:32 -0700 Subject: [PATCH 063/480] Adds AttributeName property to JoinData allowing attribute name to be set from config as well --- .../EssentialsHuddleVtc1FusionController.cs | 22 ++-- ...lsHuddleSpaceFusionSystemControllerBase.cs | 46 ++++---- ...entialsHuddleSpaceRoomFusionRoomJoinMap.cs | 106 +++++++++--------- .../JoinMaps/JoinMapBase.cs | 18 ++- 4 files changed, 101 insertions(+), 91 deletions(-) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 8028271e..99c07348 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion // Map FusionRoom Attributes: // Codec volume - var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, "Volume - Fader01", eSigIoMask.InputOutputSig); + var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description, eSigIoMask.InputOutputSig); codecVolume.OutputSig.UserObject = new Action(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); // In Call Status - CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); + CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.Metadata.Description, eSigIoMask.InputSigOnly); codec.CallStatusChange += new EventHandler(codec_CallStatusChange); // Online status if (codec is ICommunicationMonitor) { var c = codec as ICommunicationMonitor; - var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, "Online - VC 1", eSigIoMask.InputSigOnly); + var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.Metadata.Description, eSigIoMask.InputSigOnly); codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; c.CommunicationMonitor.StatusChange += (o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; - Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1"); + Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.Metadata.Description); } // Codec IP Address @@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion if (codecHasIpInfo) { - codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, "IP Address - VC", eSigIoMask.InputSigOnly); + codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.Metadata.Description, eSigIoMask.InputSigOnly); codecIpAddressSig.InputSig.StringValue = codecIpAddress; - codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, "IP Port - VC", eSigIoMask.InputSigOnly); + codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.Metadata.Description, eSigIoMask.InputSigOnly); codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); } @@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Fusion FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); } - var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); + var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId); codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction; codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction; codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig); @@ -172,7 +172,7 @@ namespace PepperDash.Essentials.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.CurrentRoomSourceName.JoinNumber, "Display 1 - Current Source", eSigIoMask.InputSigOnly); + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description, eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; @@ -197,7 +197,7 @@ namespace PepperDash.Essentials.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs("Display 1 - Source TV " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots break; @@ -207,7 +207,7 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > 5) // We only have five spots break; @@ -217,7 +217,7 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? break; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 2ca546cc..03e1c090 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -93,6 +93,8 @@ namespace PepperDash.Essentials.Core.Fusion { JoinMap = new EssentialsHuddleSpaceRoomFusionRoomJoinMap(1); + CrestronConsole.AddNewConsoleCommand((o) => JoinMap.PrintJoinMapInfo(), string.Format("ptjnmp-{0}", Key), "Prints Attribute Join Map", ConsoleAccessLevelEnum.AccessOperator); + if (!string.IsNullOrEmpty(joinMapKey)) { var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); @@ -337,7 +339,7 @@ namespace PepperDash.Essentials.Core.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.CurrentRoomSourceName.JoinNumber, "Display 1 - Current Source", + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description, eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange; @@ -387,24 +389,24 @@ namespace PepperDash.Essentials.Core.Fusion var response = string.Empty; - var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, "Processor - Reboot", eSigIoMask.OutputSigOnly); + var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, JoinMap.ProcessorReboot.Metadata.Description, eSigIoMask.OutputSigOnly); systemReboot.OutputSig.SetSigFalseAction( () => CrestronConsole.SendControlSystemCommand("reboot", ref response)); } protected void SetUpEthernetValues() { - _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); - _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); - _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, "Info - Processor - Gateway", eSigIoMask.InputSigOnly); - _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, "Info - Processor - Hostname", eSigIoMask.InputSigOnly); - _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, "Info - Processor - Domain", eSigIoMask.InputSigOnly); - _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, "Info - Processor - DNS 1", eSigIoMask.InputSigOnly); - _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, "Info - Processor - DNS 2", eSigIoMask.InputSigOnly); - _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, "Info - Processor - MAC 1", eSigIoMask.InputSigOnly); - _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, "Info - Processor - MAC 2", eSigIoMask.InputSigOnly); - _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, "Info - Processor - Net Mask 1", eSigIoMask.InputSigOnly); - _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, "Info - Processor - Net Mask 2", eSigIoMask.InputSigOnly); + _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.Metadata.Description, eSigIoMask.InputSigOnly); + _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, JoinMap.ProcessorIp2.Metadata.Description, eSigIoMask.InputSigOnly); + _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, JoinMap.ProcessorGateway.Metadata.Description, eSigIoMask.InputSigOnly); + _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, JoinMap.ProcessorHostname.Metadata.Description, eSigIoMask.InputSigOnly); + _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, JoinMap.ProcessorDomain.Metadata.Description, eSigIoMask.InputSigOnly); + _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, JoinMap.ProcessorDns1.Metadata.Description, eSigIoMask.InputSigOnly); + _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, JoinMap.ProcessorDns2.Metadata.Description, eSigIoMask.InputSigOnly); + _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, JoinMap.ProcessorMac1.Metadata.Description, eSigIoMask.InputSigOnly); + _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, JoinMap.ProcessorMac2.Metadata.Description, eSigIoMask.InputSigOnly); + _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, JoinMap.ProcessorNetMask1.Metadata.Description, eSigIoMask.InputSigOnly); + _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.Metadata.Description, eSigIoMask.InputSigOnly); } protected void GetProcessorEthernetValues() @@ -457,7 +459,7 @@ namespace PepperDash.Essentials.Core.Fusion protected void GetProcessorInfo() { - _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, "Info - Processor - Firmware", eSigIoMask.InputSigOnly); + _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.Metadata.Description, eSigIoMask.InputSigOnly); if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) { @@ -466,7 +468,7 @@ namespace PepperDash.Essentials.Core.Fusion var join = JoinMap.ProgramNameStart.JoinNumber + i; var progNum = i + 1; _program[i] = FusionRoom.CreateOffsetStringSig((uint) join, - string.Format("Info - Processor - Program {0}", progNum), eSigIoMask.InputSigOnly); + string.Format("{0} {1}", JoinMap.ProgramNameStart.Metadata.Description, progNum), eSigIoMask.InputSigOnly); } } @@ -1044,7 +1046,7 @@ namespace PepperDash.Essentials.Core.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs("Display 1 - Source TV " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.Metadata.Description + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots { @@ -1056,7 +1058,7 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs("Display 1 - Source DVD " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots { @@ -1068,7 +1070,7 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs("Display 1 - Source Laptop " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? { @@ -1197,7 +1199,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = "Online - XPanel " + attrNum; + attrName = JoinMap.XpanelOnlineStart.Metadata.Description + " " + attrNum; attrNum += JoinMap.XpanelOnlineStart.JoinNumber; touchpanelNum++; @@ -1210,7 +1212,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = "Online - Touch Panel " + attrNum; + attrName = JoinMap.TouchpanelOnlineStart.Metadata.Description + " " + attrNum; attrNum += JoinMap.TouchpanelOnlineStart.JoinNumber; xpanelNum++; @@ -1225,7 +1227,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = "Online - Display " + attrNum; + attrName = JoinMap.DisplayOnlineStart.Metadata.Description + " " + attrNum; attrNum += JoinMap.DisplayOnlineStart.JoinNumber; displayNum++; @@ -1370,7 +1372,7 @@ namespace PepperDash.Essentials.Core.Fusion return; } // Display volume - var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, "Volume - Fader01", + var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description, eSigIoMask.InputOutputSig); defaultDisplayVolume.OutputSig.UserObject = new Action(b => { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs index d388f464..0b61fed2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs @@ -14,113 +14,113 @@ namespace PepperDash.Essentials.Core.Fusion // Processor Attributes [JoinName("ProcessorIp1")] - public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor IP Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" }, + new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorIp2")] - public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor IP Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" }, + new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorGateway")] - public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor Gateway Address", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" }, + new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorHostname")] - public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" }, + new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorDomain")] - public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - Domain" }, + new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorDns1")] - public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" }, + new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorDns2")] - public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" }, + new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorMac1")] - public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor MAC Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" }, + new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorMac2")] - public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor MAC Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" }, + new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorNetMask1")] - public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor NetMask Address 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" }, + new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorNetMask2")] - public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor NetMask Address 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" }, + new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorFirmware")] - public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor Firmware Version", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" }, + new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProgramNameStart")] - public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10 }, - new JoinMetadata { Description = "Program Names", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" }, + new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorReboot")] - public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1 }, - new JoinMetadata { Description = "Processor Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" }, + new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital }); // Volume Controls [JoinName("VolumeFader1")] - public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, - new JoinMetadata { Description = "Volume - Fader 1", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog }); + public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" }, + new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog }); // Codec Info [JoinName("VcCodecInCall")] - public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1 }, - new JoinMetadata { Description = "VC Codec In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" }, + new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("VcCodecOnline")] - public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1 }, - new JoinMetadata { Description = "VC Codec Online", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" }, + new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("VcCodecIpAddress")] - public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata { Description = "VC Codec IP Address", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" }, + new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("VcCodecIpPort")] - public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1 }, - new JoinMetadata { Description = "VC Codec IP Port", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" }, + new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); // Source Attributes - [JoinName("CurrentRoomSourceName")] - public JoinDataComplete CurrentRoomSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1 }, - new JoinMetadata { Description = "Current Room Source Name", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); + [JoinName("Display1CurrentSourceName")] + public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" }, + new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); // Device Online Status [JoinName("TouchpanelOnlineStart")] - public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10 }, - new JoinMetadata { Description = "Touchpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" }, + new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("XpanelOnlineStart")] - public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5 }, - new JoinMetadata { Description = "Xpanel Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" }, + new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("DisplayOnlineStart")] - public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10 }, - new JoinMetadata { Description = "Display Online Start", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" }, + new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital }); [JoinName("Display1LaptopSourceStart")] - public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5 }, - new JoinMetadata { Description = "Display 1 - Source Laptop Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" }, + new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); [JoinName("Display1DiscPlayerSourceStart")] - public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5 }, - new JoinMetadata { Description = "Display 1 - Source Disc Player Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" }, + new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); [JoinName("Display1SetTopBoxSourceStart")] - public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5 }, - new JoinMetadata { Description = "Display 1 - Source TV Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); + public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" }, + new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital }); // Display 1 [JoinName("Display1Start")] diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index 3abfb8c7..4fe2d537 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -266,7 +266,7 @@ namespace PepperDash.Essentials.Core @"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'", join.Value.JoinNumber, join.Value.JoinSpan, - String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description, + String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label : join.Value.Metadata.Description, join.Value.Metadata.JoinType.ToString(), join.Value.Metadata.JoinCapabilities.ToString()); } @@ -288,7 +288,7 @@ namespace PepperDash.Essentials.Core } else { - Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key); + Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key); } } @@ -397,7 +397,7 @@ namespace PepperDash.Essentials.Core } /// - /// Data describing the join. Can be + /// Data describing the join. Can be overridden from configuratino /// public class JoinData { @@ -411,8 +411,11 @@ namespace PepperDash.Essentials.Core /// [JsonProperty("joinSpan")] public uint JoinSpan { get; set; } - - + /// + /// Fusion Attribute Name (optional) + /// + [JsonProperty("attributeName")] + public string AttributeName { get; set; } } /// @@ -458,6 +461,11 @@ namespace PepperDash.Essentials.Core get { return _data.JoinSpan; } } + public string AttributeName + { + get { return _data.AttributeName; } + } + public void SetCustomJoinData(JoinData customJoinData) { _data = customJoinData; From 9b62849d9dcb9c3cc1d7d470445f3306b07c8106 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 6 Jan 2021 14:45:40 -0700 Subject: [PATCH 064/480] removes old comment --- .../Fusion/EssentialsHuddleVtc1FusionController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 99c07348..b071b681 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -179,7 +179,6 @@ namespace PepperDash.Essentials.Fusion FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); - // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; From 72197e547f0aacf7b55506c0530af238523c506d Mon Sep 17 00:00:00 2001 From: jkdevito Date: Wed, 6 Jan 2021 16:22:54 -0600 Subject: [PATCH 065/480] Updated VideoCodecBase.cs and ZoomRooms.cs to resolve an issue with dialing the currently scheduled meetings. VideoCodecBase.cs changes: 1. Moved the trilist.SetSigFalseActions for DialMeeting 1-3 from the UpdateMeetinsgList mehtod to the LinkVideoCodecScheduleToApi method. - This was necessary to resolve an issue with dialing current meetings. - When the SetSigFalseActions where located in the UpdateMeetingsList, they were using the codec.CodecSchedule.Meetings to dial, which was not updated based on the time of day. 2. Turned the local var currentMeetings into a private list, _currentMeetings, that can be updated by UpdateMeetingsList and then used in LinkVideoCodecScheduleToApi when the trilist actions are executed. 3. Added debug statements to help narrow down the issue and verify the data. ZoomRoom.cs changes: 1. Added debug statement to Dial(Meeting meeting) method to confirm the data passed from LinkVideoCodecScheduleToApi was matching the _currentMeetings list data. --- .../VideoCodec/VideoCodecBase.cs | 2528 +++++++++-------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 1 + 2 files changed, 1276 insertions(+), 1253 deletions(-) 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 0977dea2..6b6d5891 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 @@ -1,1257 +1,1279 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharp.Ssh; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharp; -using PepperDash.Core; -using PepperDash.Core.Intersystem; -using PepperDash.Core.Intersystem.Tokens; -using PepperDash.Core.WebApi.Presets; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Core.Routing; -using PepperDash.Essentials.Devices.Common.Cameras; -using PepperDash.Essentials.Devices.Common.Codec; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; -using PepperDash_Essentials_Core.Bridges.JoinMaps; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; -using Feedback = PepperDash.Essentials.Core.Feedback; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec -{ - public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, - IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced - { - private const int XSigEncoding = 28591; - private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); - protected VideoCodecBase(DeviceConfig config) - : base(config) - { - - StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); - PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); - VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); - SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); - SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); - - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - - ActiveCalls = new List(); - } - - public IBasicCommunication Communication { get; protected set; } - - /// - /// An internal pseudo-source that is routable and connected to the osd input - /// - public DummyRoutingInputsDevice OsdSource { get; protected set; } - - public BoolFeedback StandbyIsOnFeedback { get; private set; } - - protected abstract Func PrivacyModeIsOnFeedbackFunc { get; } - protected abstract Func VolumeLevelFeedbackFunc { get; } - protected abstract Func MuteFeedbackFunc { get; } - protected abstract Func StandbyIsOnFeedbackFunc { get; } - - public List ActiveCalls { get; set; } - - public bool ShowSelfViewByDefault { get; protected set; } - - protected bool SupportsCameraOff; - protected bool SupportsCameraAutoMode; - - public bool IsReady { get; protected set; } - - public virtual List Feedbacks - { - get - { - return new List +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Ssh; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharp; +using PepperDash.Core; +using PepperDash.Core.Intersystem; +using PepperDash.Core.Intersystem.Tokens; +using PepperDash.Core.WebApi.Presets; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Devices.Common.Cameras; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; +using PepperDash_Essentials_Core.Bridges.JoinMaps; +using PepperDash_Essentials_Core.DeviceTypeInterfaces; +using Feedback = PepperDash.Essentials.Core.Feedback; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, + IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced + { + private const int XSigEncoding = 28591; + private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); + protected VideoCodecBase(DeviceConfig config) + : base(config) + { + + StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); + PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); + VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); + MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); + SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); + + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + + ActiveCalls = new List(); + } + + public IBasicCommunication Communication { get; protected set; } + + /// + /// An internal pseudo-source that is routable and connected to the osd input + /// + public DummyRoutingInputsDevice OsdSource { get; protected set; } + + public BoolFeedback StandbyIsOnFeedback { get; private set; } + + protected abstract Func PrivacyModeIsOnFeedbackFunc { get; } + protected abstract Func VolumeLevelFeedbackFunc { get; } + protected abstract Func MuteFeedbackFunc { get; } + protected abstract Func StandbyIsOnFeedbackFunc { get; } + + public List ActiveCalls { get; set; } + + public bool ShowSelfViewByDefault { get; protected set; } + + protected bool SupportsCameraOff; + protected bool SupportsCameraAutoMode; + + public bool IsReady { get; protected set; } + + public virtual List Feedbacks + { + get + { + return new List { PrivacyModeIsOnFeedback, SharingSourceFeedback - }; - } - } - - protected abstract Func SharingSourceFeedbackFunc { get; } - protected abstract Func SharingContentIsOnFeedbackFunc { get; } - - #region ICodecAudio Members - - public abstract void PrivacyModeOn(); - public abstract void PrivacyModeOff(); - public abstract void PrivacyModeToggle(); - public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } - - - public BoolFeedback MuteFeedback { get; private set; } - - public abstract void MuteOff(); - - public abstract void MuteOn(); - - public abstract void SetVolume(ushort level); - - public IntFeedback VolumeLevelFeedback { get; private set; } - - public abstract void MuteToggle(); - - public abstract void VolumeDown(bool pressRelease); - - - public abstract void VolumeUp(bool pressRelease); - - #endregion - - #region IHasContentSharing Members - - public abstract void StartSharing(); - public abstract void StopSharing(); - - public bool AutoShareContentWhileInCall { get; protected set; } - - public StringFeedback SharingSourceFeedback { get; private set; } - public BoolFeedback SharingContentIsOnFeedback { get; private set; } - - #endregion - - #region IHasDialer Members - - /// - /// Fires when the status of any active, dialing, or incoming call changes or is new - /// - public event EventHandler CallStatusChange; - - /// - /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected - /// - public bool IsInCall - { - get - { - var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall); - return value; - } - } - - public abstract void Dial(string number); - public abstract void EndCall(CodecActiveCallItem call); - public abstract void EndAllCalls(); - public abstract void AcceptCall(CodecActiveCallItem call); - public abstract void RejectCall(CodecActiveCallItem call); - public abstract void SendDtmf(string s); - - #endregion - - #region IRoutingInputsOutputs Members - - public RoutingPortCollection InputPorts { get; private set; } - - public RoutingPortCollection OutputPorts { get; private set; } - - #endregion - - #region IUsageTracking Members - - /// - /// This object can be added by outside users of this class to provide usage tracking - /// for various services - /// - public UsageTracking UsageTracker { get; set; } - - #endregion - - #region iVideoCodecInfo Members - - public VideoCodecInfo CodecInfo { get; protected set; } - - #endregion - - public event EventHandler IsReadyChange; - public abstract void Dial(Meeting meeting); - - public virtual void Dial(IInvitableContact contact) - { - } - - public abstract void ExecuteSwitch(object selector); - - /// - /// Helper method to fire CallStatusChange event with old and new status - /// - protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call) - { - call.Status = newStatus; - - OnCallStatusChange(call); - } - - /// - /// - /// - /// - /// - /// - protected virtual void OnCallStatusChange(CodecActiveCallItem item) - { - var handler = CallStatusChange; - if (handler != null) - { - handler(this, new CodecCallStatusItemChangeEventArgs(item)); - } - - if (AutoShareContentWhileInCall) - { - StartSharing(); - } - - if (UsageTracker != null) - { - if (IsInCall && !UsageTracker.UsageTrackingStarted) - { - UsageTracker.StartDeviceUsage(); - } - else if (UsageTracker.UsageTrackingStarted && !IsInCall) - { - UsageTracker.EndDeviceUsage(); - } - } - } - - /// - /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data. - /// - protected void SetIsReady() - { - CrestronInvoke.BeginInvoke( (o) => - { - try - { - IsReady = true; - var h = IsReadyChange; - if (h != null) - { - h(this, new EventArgs()); - } - } - catch (Exception e) - { - Debug.Console(2, this, "Error in SetIsReady() : {0}", e); - } - }); - } - - // **** DEBUGGING THINGS **** - /// - /// - /// - public virtual void ListCalls() - { - var sb = new StringBuilder(); - foreach (var c in ActiveCalls) - { - sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status); - } - Debug.Console(1, this, "\n{0}\n", sb.ToString()); - } - - public abstract void StandbyActivate(); - - public abstract void StandbyDeactivate(); - - #region Implementation of IBridgeAdvanced - - public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); - - protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, - EiscApiAdvanced bridge) - { - var joinMap = new VideoCodecControllerJoinMap(joinStart); - - var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - - if (customJoins != null) - { - joinMap.SetCustomJoinData(customJoins); - } - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - - Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); - - - - LinkVideoCodecDtmfToApi(trilist, joinMap); - - LinkVideoCodecCallControlsToApi(trilist, joinMap); - - LinkVideoCodecContentSharingToApi(trilist, joinMap); - - LinkVideoCodecPrivacyToApi(trilist, joinMap); - - LinkVideoCodecVolumeToApi(trilist, joinMap); - - if (codec is ICommunicationMonitor) - { - LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); - } - - if (codec is IHasCodecCameras) - { - LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); - } - - if (codec is IHasCodecSelfView) - { - LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); - LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); - } - - if (codec is IHasCameraOff) - { - trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); - LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); - } - - if (codec is IHasCodecLayouts) - { - LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); - } - - if (codec is IHasSelfviewPosition) - { - LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); - } - - if (codec is IHasDirectory) - { - LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); - } - - if (codec is IHasScheduleAwareness) - { - LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); - } - - if (codec is IHasParticipants) - { - LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); - } - - if (codec is IHasFarEndContentStatus) - { - (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); - } - - if (codec is IHasPhoneDialing) - { - LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); - } - - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; - - if (codec is IHasDirectory) - { - (codec as IHasDirectory).SetCurrentDirectoryToRoot(); - } - - if (codec is IHasScheduleAwareness) - { - (codec as IHasScheduleAwareness).GetSchedule(); - } - - if (codec is IHasParticipants) - { - UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); - - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCodecSelfView) - { - (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraAutoMode) - { - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraOff) - { - (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); - } - - if (codec is IHasPhoneDialing) - { - (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); - } - - SharingContentIsOnFeedback.FireUpdate(); - - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; - } - - private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber, - () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue)); - - trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall); - } - - private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle); - - codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]); - } - - private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff); - - codec.CameraIsOffFeedback.OutputChange += (o, a) => - { - if (a.BoolValue) - { - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - - var autoCodec = codec as IHasCameraAutoMode; - - if (autoCodec == null) return; - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue); - }; - - if (codec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - - var autoModeCodec = codec as IHasCameraAutoMode; - - if (autoModeCodec == null) return; - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); - } - - private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]); - MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn); - trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff); - trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle); - - VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]); - - trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp); - trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown); - - trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume); - - } - - private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]); - PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn); - trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff); - trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle); - } - - private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - } - - private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.Participants.ParticipantsListHasChanged += (sender, args) => - { - string participantsXSig; - - if (codec.Participants.CurrentParticipants.Count == 0) - { - participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); - return; - } - - participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); - - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort) codec.Participants.CurrentParticipants.Count); - }; - } - - private string UpdateParticipantsXSig(List currentParticipants) - { - const int maxParticipants = 50; - const int maxDigitals = 5; - const int maxStrings = 1; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings * maxParticipants; //15 - var stringIndex = 0; - var meetingIndex = 0; - - var tokenArray = new XSigToken[maxParticipants * offset]; - - foreach (var participant in currentParticipants) - { - if (meetingIndex >= maxParticipants * offset) break; - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb); - tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); - tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); - tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - while (meetingIndex < maxParticipants*offset) - { - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); - tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); - tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); - tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); - SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]); - - SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing); - trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing); - - trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); - } - - private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule); - - trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) => - { - codec.CodecSchedule.MeetingWarningMinutes = i; - }); - - codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap); - - codec.CodecSchedule.MeetingEventChange += - (sender, args) => - { - if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning) - { - UpdateMeetingsList(codec, trilist, joinMap); - } - }; - } - - private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - var currentTime = DateTime.Now; - var currentMeetings = - codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); - - var meetingsData = UpdateMeetingsListXSig(currentMeetings); - - trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); - - trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => - { - if(codec.CodecSchedule.Meetings[0] != null) - Dial(codec.CodecSchedule.Meetings[0]); - }); - trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => - { - if (codec.CodecSchedule.Meetings[1] != null) - Dial(codec.CodecSchedule.Meetings[1]); - }); - trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => - { - if (codec.CodecSchedule.Meetings[2] != null) - Dial(codec.CodecSchedule.Meetings[2]); - }); - - trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)currentMeetings.Count); - } - - private string UpdateMeetingsListXSig(List meetings) - { - const int maxMeetings = 3; - const int maxDigitals = 2; - const int maxStrings = 7; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings*maxMeetings; //15 - var stringIndex = 0; - var meetingIndex = 0; - - var tokenArray = new XSigToken[maxMeetings*offset]; - /* - * Digitals - * IsJoinable - 1 - * IsDialable - 2 - * - * Serials - * Organizer - 1 - * Title - 2 - * Start Date - 3 - * Start Time - 4 - * End Date - 5 - * End Time - 6 - */ - - - foreach(var meeting in meetings) - { - var currentTime = DateTime.Now; - - if(meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; - - if (meetingIndex >= maxMeetings*offset) - { - Debug.Console(2, this, "Max Meetings reached"); - break;} - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0"); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString()); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString()); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString()); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString()); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); - - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - while (meetingIndex < maxMeetings*offset) - { - Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", - meetingIndex, maxMeetings*offset); - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig( - trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); - - trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory); - - trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i)); - - trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); - - trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents); - - codec.DirectoryResultReturned += (sender, args) => - { - trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort) args.Directory.CurrentDirectoryResults.Count); - - var clearBytes = XSigHelpers.ClearOutputs(); - - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, - Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); - - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); - }; - } - - private void SelectDirectoryEntry(IHasDirectory codec, ushort i) - { - var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; - - if (entry is DirectoryFolder) - { - codec.GetDirectoryFolderContents(entry.FolderId); - return; - } - - var dialableEntry = entry as IInvitableContact; - - if (dialableEntry != null) - { - Dial(dialableEntry); - return; - } - - var entryToDial = entry as DirectoryContact; - - if (entryToDial == null) return; - - Dial(entryToDial.ContactMethods[0].Number); - } - - private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) - { - var contactIndex = 1; - var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count]; - - foreach(var entry in directory.CurrentDirectoryResults) - { - var arrayIndex = contactIndex - 1; - - if (entry is DirectoryFolder && entry.ParentFolderId == "root") - { - tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name)); - - contactIndex++; - - continue; - } - - if(isRoot && String.IsNullOrEmpty(entry.FolderId)) continue; - - tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name); - - contactIndex++; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber, - () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue)); - - //End All calls for now - trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls); - - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - CallStatusChange += (sender, args) => - { - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); - Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); - trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); - - if (args.CallItem.Direction == eCodecCallDirection.Incoming) - { - trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); - trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); - } - - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; - } - - private string UpdateCallStatusXSig() - { - const int maxCalls = 8; - const int maxStrings = 5; - const int offset = 6; - var stringIndex = 0; - var digitalIndex = maxStrings * maxCalls; - var arrayIndex = 0; - - var tokenArray = new XSigToken[maxCalls*offset]; //set array size for number of calls * pieces of info - - foreach (var call in ActiveCalls) - { - if (arrayIndex >= maxCalls * offset) - break; - //digitals - tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); - - //serials - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); - tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); - tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); - - arrayIndex += offset; - stringIndex += maxStrings; - digitalIndex++; - } - while (digitalIndex < maxCalls) - { - //digitals - tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false); - - //serials - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty); - - arrayIndex += offset; - stringIndex += maxStrings; - digitalIndex++; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0")); - trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1")); - trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2")); - trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3")); - trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4")); - trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5")); - trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6")); - trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7")); - trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8")); - trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9")); - trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*")); - trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#")); - } - - private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle); - - codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]); - } - - private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); - trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff); - - codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) => - { - var offCodec = codec as IHasCameraOff; - - if (offCodec != null) - { - if (offCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - }; - - var offModeCodec = codec as IHasCameraOff; - - if (offModeCodec != null) - { - if (offModeCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - } - - private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist, - VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle); - - codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]); - } - - private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - //Camera PTZ - trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.TiltUp(); - else camera.TiltStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.TiltDown(); - else camera.TiltStop(); - }); - trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.PanLeft(); - else camera.PanStop(); - }); - trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.PanRight(); - else camera.PanStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.ZoomIn(); - else camera.ZoomStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.ZoomOut(); - else camera.ZoomStop(); - }); - - //Camera Select - trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) => - { - if (codec.SelectedCamera == null) return; - - codec.SelectCamera(codec.Cameras[i].Key); - }); - - codec.CameraSelected += (sender, args) => - { - var i = (ushort) codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key); - - if (codec is IHasCodecRoomPresets) - { - return; - } - - if (!(args.SelectedCamera is IHasCameraPresets)) - { - return; - } - - var cam = args.SelectedCamera as IHasCameraPresets; - SetCameraPresetNames(cam.Presets); - - (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets); - - trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, - (a) => - { - cam.PresetSelect(a); - trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a); - }); - - trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, - () => - { - cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, - String.Empty); - trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); - }); - }; - - if (!(codec is IHasCodecRoomPresets)) return; - - var presetCodec = codec as IHasCodecRoomPresets; - - presetCodec.CodecRoomPresetsListHasChanged += - (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets); - - //Camera Presets - trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) => - { - presetCodec.CodecRoomPresetSelect(i); - - trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i); - }); - - trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, - () => - { - presetCodec.CodecRoomPresetStore( - trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty); - trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); - }); - } - - private string SetCameraPresetNames(IEnumerable presets) - { - return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); - } - - private string SetCameraPresetNames(IEnumerable presets) - { - return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); - } - - private string SetCameraPresetNames(ICollection presets) - { - var i = 1; //start index for xsig; - - var tokenArray = new XSigToken[presets.Count]; - - foreach (var preset in presets) - { - var cameraPreset = new XSigSerialToken(i, preset); - tokenArray[i - 1] = cameraPreset; - i++; - } - - return GetXSigString(tokenArray); - } - - private string GetXSigString(XSigToken[] tokenArray) - { - string returnString; - using (var s = new MemoryStream()) - { - using (var tw = new XSigTokenStreamWriter(s, true)) - { - tw.WriteXSigData(tokenArray); - } - - var xSig = s.ToArray(); - - returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length); - } - - return returnString; - } - - #endregion - } - - - /// - /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info - /// - public class CodecPhonebookSyncState : IKeyed - { - private bool _InitialSyncComplete; - - public CodecPhonebookSyncState(string key) - { - Key = key; - - CodecDisconnected(); - } - - public bool InitialSyncComplete - { - get { return _InitialSyncComplete; } - private set - { - if (value == true) - { - var handler = InitialSyncCompleted; - if (handler != null) - { - handler(this, new EventArgs()); - } - } - _InitialSyncComplete = value; - } - } - - public bool InitialPhonebookFoldersWasReceived { get; private set; } - - public bool NumberOfContactsWasReceived { get; private set; } - - public bool PhonebookRootEntriesWasRecieved { get; private set; } - - public bool PhonebookHasFolders { get; private set; } - - public int NumberOfContacts { get; private set; } - - #region IKeyed Members - - public string Key { get; private set; } - - #endregion - - public event EventHandler InitialSyncCompleted; - - public void InitialPhonebookFoldersReceived() - { - InitialPhonebookFoldersWasReceived = true; - - CheckSyncStatus(); - } - - public void PhonebookRootEntriesReceived() - { - PhonebookRootEntriesWasRecieved = true; - - CheckSyncStatus(); - } - - public void SetPhonebookHasFolders(bool value) - { - PhonebookHasFolders = value; - - Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders); - } - - public void SetNumberOfContacts(int contacts) - { - NumberOfContacts = contacts; - NumberOfContactsWasReceived = true; - - Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts); - - CheckSyncStatus(); - } - - public void CodecDisconnected() - { - InitialPhonebookFoldersWasReceived = false; - PhonebookHasFolders = false; - NumberOfContacts = 0; - NumberOfContactsWasReceived = false; - } - - private void CheckSyncStatus() - { - if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) - { - InitialSyncComplete = true; - Debug.Console(1, this, "Initial Phonebook Sync Complete!"); - } - else - { - InitialSyncComplete = false; - } - } - } + }; + } + } + + protected abstract Func SharingSourceFeedbackFunc { get; } + protected abstract Func SharingContentIsOnFeedbackFunc { get; } + + #region ICodecAudio Members + + public abstract void PrivacyModeOn(); + public abstract void PrivacyModeOff(); + public abstract void PrivacyModeToggle(); + public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } + + + public BoolFeedback MuteFeedback { get; private set; } + + public abstract void MuteOff(); + + public abstract void MuteOn(); + + public abstract void SetVolume(ushort level); + + public IntFeedback VolumeLevelFeedback { get; private set; } + + public abstract void MuteToggle(); + + public abstract void VolumeDown(bool pressRelease); + + + public abstract void VolumeUp(bool pressRelease); + + #endregion + + #region IHasContentSharing Members + + public abstract void StartSharing(); + public abstract void StopSharing(); + + public bool AutoShareContentWhileInCall { get; protected set; } + + public StringFeedback SharingSourceFeedback { get; private set; } + public BoolFeedback SharingContentIsOnFeedback { get; private set; } + + #endregion + + #region IHasDialer Members + + /// + /// Fires when the status of any active, dialing, or incoming call changes or is new + /// + public event EventHandler CallStatusChange; + + /// + /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected + /// + public bool IsInCall + { + get + { + var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall); + return value; + } + } + + public abstract void Dial(string number); + public abstract void EndCall(CodecActiveCallItem call); + public abstract void EndAllCalls(); + public abstract void AcceptCall(CodecActiveCallItem call); + public abstract void RejectCall(CodecActiveCallItem call); + public abstract void SendDtmf(string s); + + #endregion + + #region IRoutingInputsOutputs Members + + public RoutingPortCollection InputPorts { get; private set; } + + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + #region IUsageTracking Members + + /// + /// This object can be added by outside users of this class to provide usage tracking + /// for various services + /// + public UsageTracking UsageTracker { get; set; } + + #endregion + + #region iVideoCodecInfo Members + + public VideoCodecInfo CodecInfo { get; protected set; } + + #endregion + + public event EventHandler IsReadyChange; + public abstract void Dial(Meeting meeting); + + public virtual void Dial(IInvitableContact contact) + { + } + + public abstract void ExecuteSwitch(object selector); + + /// + /// Helper method to fire CallStatusChange event with old and new status + /// + protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call) + { + call.Status = newStatus; + + OnCallStatusChange(call); + } + + /// + /// + /// + /// + /// + /// + protected virtual void OnCallStatusChange(CodecActiveCallItem item) + { + var handler = CallStatusChange; + if (handler != null) + { + handler(this, new CodecCallStatusItemChangeEventArgs(item)); + } + + if (AutoShareContentWhileInCall) + { + StartSharing(); + } + + if (UsageTracker != null) + { + if (IsInCall && !UsageTracker.UsageTrackingStarted) + { + UsageTracker.StartDeviceUsage(); + } + else if (UsageTracker.UsageTrackingStarted && !IsInCall) + { + UsageTracker.EndDeviceUsage(); + } + } + } + + /// + /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data. + /// + protected void SetIsReady() + { + CrestronInvoke.BeginInvoke((o) => + { + try + { + IsReady = true; + var h = IsReadyChange; + if (h != null) + { + h(this, new EventArgs()); + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error in SetIsReady() : {0}", e); + } + }); + } + + // **** DEBUGGING THINGS **** + /// + /// + /// + public virtual void ListCalls() + { + var sb = new StringBuilder(); + foreach (var c in ActiveCalls) + { + sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status); + } + Debug.Console(1, this, "\n{0}\n", sb.ToString()); + } + + public abstract void StandbyActivate(); + + public abstract void StandbyDeactivate(); + + #region Implementation of IBridgeAdvanced + + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + + protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + var joinMap = new VideoCodecControllerJoinMap(joinStart); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); + + + + LinkVideoCodecDtmfToApi(trilist, joinMap); + + LinkVideoCodecCallControlsToApi(trilist, joinMap); + + LinkVideoCodecContentSharingToApi(trilist, joinMap); + + LinkVideoCodecPrivacyToApi(trilist, joinMap); + + LinkVideoCodecVolumeToApi(trilist, joinMap); + + if (codec is ICommunicationMonitor) + { + LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); + } + + if (codec is IHasCodecCameras) + { + LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); + } + + if (codec is IHasCodecSelfView) + { + LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); + LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); + } + + if (codec is IHasCameraOff) + { + trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); + LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); + } + + if (codec is IHasCodecLayouts) + { + LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); + } + + if (codec is IHasSelfviewPosition) + { + LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); + } + + if (codec is IHasDirectory) + { + LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); + } + + if (codec is IHasScheduleAwareness) + { + LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); + } + + if (codec is IHasParticipants) + { + LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); + } + + if (codec is IHasFarEndContentStatus) + { + (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); + } + + if (codec is IHasPhoneDialing) + { + LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); + } + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + if (codec is IHasDirectory) + { + (codec as IHasDirectory).SetCurrentDirectoryToRoot(); + } + + if (codec is IHasScheduleAwareness) + { + (codec as IHasScheduleAwareness).GetSchedule(); + } + + if (codec is IHasParticipants) + { + UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); + + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCodecSelfView) + { + (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraAutoMode) + { + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraOff) + { + (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); + } + + if (codec is IHasPhoneDialing) + { + (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); + } + + SharingContentIsOnFeedback.FireUpdate(); + + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } + + private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber, + () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue)); + + trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall); + } + + private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle); + + codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]); + } + + private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff); + + codec.CameraIsOffFeedback.OutputChange += (o, a) => + { + if (a.BoolValue) + { + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + + var autoCodec = codec as IHasCameraAutoMode; + + if (autoCodec == null) return; + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue); + }; + + if (codec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + + var autoModeCodec = codec as IHasCameraAutoMode; + + if (autoModeCodec == null) return; + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); + } + + private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]); + MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn); + trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff); + trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle); + + VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]); + + trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp); + trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown); + + trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume); + + } + + private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]); + PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn); + trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff); + trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle); + } + + private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + } + + private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.Participants.ParticipantsListHasChanged += (sender, args) => + { + string participantsXSig; + + if (codec.Participants.CurrentParticipants.Count == 0) + { + participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + return; + } + + participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); + + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + }; + } + + private string UpdateParticipantsXSig(List currentParticipants) + { + const int maxParticipants = 50; + const int maxDigitals = 5; + const int maxStrings = 1; + const int offset = maxDigitals + maxStrings; + var digitalIndex = maxStrings * maxParticipants; //15 + var stringIndex = 0; + var meetingIndex = 0; + + var tokenArray = new XSigToken[maxParticipants * offset]; + + foreach (var participant in currentParticipants) + { + if (meetingIndex >= maxParticipants * offset) break; + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb); + tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); + tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); + tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + while (meetingIndex < maxParticipants * offset) + { + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); + tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); + tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); + SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]); + + SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing); + trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing); + + trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); + } + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + private List _currentMeetings = new List(); + + private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule); + + trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) => + { + codec.CodecSchedule.MeetingWarningMinutes = i; + }); + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => + { + var mtg = 1; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting1.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => + { + var mtg = 2; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting2.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => + { + var mtg = 3; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting3.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + + codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap); + codec.CodecSchedule.MeetingEventChange += (sender, args) => + { + if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning) + { + UpdateMeetingsList(codec, trilist, joinMap); + } + }; + } + + private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + var currentTime = DateTime.Now; + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + // - changed var currentMeetings >> field _currentMeetings + //_currentMeetings.Clear(); + _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + // - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi + + var meetingsData = UpdateMeetingsListXSig(_currentMeetings); + trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); + trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); + } + + private string UpdateMeetingsListXSig(List meetings) + { + const int maxMeetings = 3; + const int maxDigitals = 2; + const int maxStrings = 7; + const int offset = maxDigitals + maxStrings; + var digitalIndex = maxStrings * maxMeetings; //15 + var stringIndex = 0; + var meetingIndex = 0; + + var tokenArray = new XSigToken[maxMeetings * offset]; + /* + * Digitals + * IsJoinable - 1 + * IsDialable - 2 + * + * Serials + * Organizer - 1 + * Title - 2 + * Start Date - 3 + * Start Time - 4 + * End Date - 5 + * End Time - 6 + * Id - 7 + */ + + + foreach (var meeting in meetings) + { + var currentTime = DateTime.Now; + + if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; + + if (meetingIndex >= maxMeetings * offset) + { + Debug.Console(2, this, "Max Meetings reached"); + break; + } + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0"); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString()); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString()); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString()); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString()); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); + + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + while (meetingIndex < maxMeetings * offset) + { + Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", + meetingIndex, maxMeetings * offset); + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig( + trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); + + trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory); + + trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i)); + + trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); + + trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents); + + codec.DirectoryResultReturned += (sender, args) => + { + trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)args.Directory.CurrentDirectoryResults.Count); + + var clearBytes = XSigHelpers.ClearOutputs(); + + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, + Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); + var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); + }; + } + + private void SelectDirectoryEntry(IHasDirectory codec, ushort i) + { + var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; + + if (entry is DirectoryFolder) + { + codec.GetDirectoryFolderContents(entry.FolderId); + return; + } + + var dialableEntry = entry as IInvitableContact; + + if (dialableEntry != null) + { + Dial(dialableEntry); + return; + } + + var entryToDial = entry as DirectoryContact; + + if (entryToDial == null) return; + + Dial(entryToDial.ContactMethods[0].Number); + } + + private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) + { + var contactIndex = 1; + var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count]; + + foreach (var entry in directory.CurrentDirectoryResults) + { + var arrayIndex = contactIndex - 1; + + if (entry is DirectoryFolder && entry.ParentFolderId == "root") + { + tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name)); + + contactIndex++; + + continue; + } + + if (isRoot && String.IsNullOrEmpty(entry.FolderId)) continue; + + tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name); + + contactIndex++; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber, + () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue)); + + //End All calls for now + trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls); + + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + CallStatusChange += (sender, args) => + { + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); + Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); + trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); + + if (args.CallItem.Direction == eCodecCallDirection.Incoming) + { + trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); + trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); + } + + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } + + private string UpdateCallStatusXSig() + { + const int maxCalls = 8; + const int maxStrings = 5; + const int offset = 6; + var stringIndex = 0; + var digitalIndex = maxStrings * maxCalls; + var arrayIndex = 0; + + var tokenArray = new XSigToken[maxCalls * offset]; //set array size for number of calls * pieces of info + + foreach (var call in ActiveCalls) + { + if (arrayIndex >= maxCalls * offset) + break; + //digitals + tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); + + //serials + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); + tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); + tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); + + arrayIndex += offset; + stringIndex += maxStrings; + digitalIndex++; + } + while (digitalIndex < maxCalls) + { + //digitals + tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false); + + //serials + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty); + + arrayIndex += offset; + stringIndex += maxStrings; + digitalIndex++; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0")); + trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1")); + trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2")); + trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3")); + trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4")); + trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5")); + trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6")); + trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7")); + trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8")); + trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9")); + trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*")); + trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#")); + } + + private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle); + + codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]); + } + + private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); + trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff); + + codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) => + { + var offCodec = codec as IHasCameraOff; + + if (offCodec != null) + { + if (offCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + }; + + var offModeCodec = codec as IHasCameraOff; + + if (offModeCodec != null) + { + if (offModeCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + } + + private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist, + VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle); + + codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]); + } + + private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + //Camera PTZ + trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.TiltUp(); + else camera.TiltStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.TiltDown(); + else camera.TiltStop(); + }); + trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.PanLeft(); + else camera.PanStop(); + }); + trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.PanRight(); + else camera.PanStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.ZoomIn(); + else camera.ZoomStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.ZoomOut(); + else camera.ZoomStop(); + }); + + //Camera Select + trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) => + { + if (codec.SelectedCamera == null) return; + + codec.SelectCamera(codec.Cameras[i].Key); + }); + + codec.CameraSelected += (sender, args) => + { + var i = (ushort)codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key); + + if (codec is IHasCodecRoomPresets) + { + return; + } + + if (!(args.SelectedCamera is IHasCameraPresets)) + { + return; + } + + var cam = args.SelectedCamera as IHasCameraPresets; + SetCameraPresetNames(cam.Presets); + + (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets); + + trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, + (a) => + { + cam.PresetSelect(a); + trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a); + }); + + trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, + () => + { + cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, + String.Empty); + trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); + }); + }; + + if (!(codec is IHasCodecRoomPresets)) return; + + var presetCodec = codec as IHasCodecRoomPresets; + + presetCodec.CodecRoomPresetsListHasChanged += + (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets); + + //Camera Presets + trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) => + { + presetCodec.CodecRoomPresetSelect(i); + + trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i); + }); + + trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, + () => + { + presetCodec.CodecRoomPresetStore( + trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty); + trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); + }); + } + + private string SetCameraPresetNames(IEnumerable presets) + { + return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); + } + + private string SetCameraPresetNames(IEnumerable presets) + { + return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); + } + + private string SetCameraPresetNames(ICollection presets) + { + var i = 1; //start index for xsig; + + var tokenArray = new XSigToken[presets.Count]; + + foreach (var preset in presets) + { + var cameraPreset = new XSigSerialToken(i, preset); + tokenArray[i - 1] = cameraPreset; + i++; + } + + return GetXSigString(tokenArray); + } + + private string GetXSigString(XSigToken[] tokenArray) + { + string returnString; + using (var s = new MemoryStream()) + { + using (var tw = new XSigTokenStreamWriter(s, true)) + { + tw.WriteXSigData(tokenArray); + } + + var xSig = s.ToArray(); + + returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length); + } + + return returnString; + } + + #endregion + } + + + /// + /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info + /// + public class CodecPhonebookSyncState : IKeyed + { + private bool _InitialSyncComplete; + + public CodecPhonebookSyncState(string key) + { + Key = key; + + CodecDisconnected(); + } + + public bool InitialSyncComplete + { + get { return _InitialSyncComplete; } + private set + { + if (value == true) + { + var handler = InitialSyncCompleted; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + _InitialSyncComplete = value; + } + } + + public bool InitialPhonebookFoldersWasReceived { get; private set; } + + public bool NumberOfContactsWasReceived { get; private set; } + + public bool PhonebookRootEntriesWasRecieved { get; private set; } + + public bool PhonebookHasFolders { get; private set; } + + public int NumberOfContacts { get; private set; } + + #region IKeyed Members + + public string Key { get; private set; } + + #endregion + + public event EventHandler InitialSyncCompleted; + + public void InitialPhonebookFoldersReceived() + { + InitialPhonebookFoldersWasReceived = true; + + CheckSyncStatus(); + } + + public void PhonebookRootEntriesReceived() + { + PhonebookRootEntriesWasRecieved = true; + + CheckSyncStatus(); + } + + public void SetPhonebookHasFolders(bool value) + { + PhonebookHasFolders = value; + + Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders); + } + + public void SetNumberOfContacts(int contacts) + { + NumberOfContacts = contacts; + NumberOfContactsWasReceived = true; + + Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts); + + CheckSyncStatus(); + } + + public void CodecDisconnected() + { + InitialPhonebookFoldersWasReceived = false; + PhonebookHasFolders = false; + NumberOfContacts = 0; + NumberOfContactsWasReceived = false; + } + + private void CheckSyncStatus() + { + if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) + { + InitialSyncComplete = true; + Debug.Console(1, this, "Initial Phonebook Sync Complete!"); + } + else + { + InitialSyncComplete = false; + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index fc440e5b..980c7a61 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1655,6 +1655,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void Dial(Meeting meeting) { + Debug.Console(1, this,"Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title); SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id)); } From 89990971001734da09d7a02a0ea6b15452e20a21 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 6 Jan 2021 16:12:12 -0700 Subject: [PATCH 066/480] Adds additional debug to help with room on/off events --- .../Room/Types/EssentialsTechRoom.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 0a47933e..bfa56646 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -261,8 +261,16 @@ namespace PepperDash.Essentials CrestronInvoke.BeginInvoke((o) => { + Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count); + foreach (var a in eventConfig.Actions) { + Debug.Console(2, this, +@"Attempting to run action: +DeviceKey: {0} +MethodName: {1} +Params: {2}" + , a.DeviceKey, a.MethodName, a.Params); DeviceJsonApi.DoDeviceAction(a); } }); @@ -271,6 +279,8 @@ namespace PepperDash.Essentials public void RoomPowerOn() { + Debug.Console(2, this, "Room Powering On"); + var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs; if (dummySource == null) @@ -287,6 +297,8 @@ namespace PepperDash.Essentials public void RoomPowerOff() { + Debug.Console(2, this, "Room Powering Off"); + foreach (var display in _displays) { display.Value.PowerOff(); From 3c1ed6e58aac601f4db9442ff8a8f654caa9d547 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 7 Jan 2021 12:41:29 -0600 Subject: [PATCH 067/480] Added debug statements to ExecuteNumericSwitch in DmTx4kz302CController --- .../Endpoints/Transmitters/DmTx4kz302CController.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index 1e44396c..1c5ce36e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -282,6 +282,12 @@ namespace PepperDash.Essentials.DM ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); break; } + default: + { + Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input); + break; + } + } @@ -289,6 +295,7 @@ namespace PepperDash.Essentials.DM public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { + Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) Tx.VideoSource = (eVst)inputSelector; From 82029894e47bc5a06ca07fe21ab3bdc9d1ae4794 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 7 Jan 2021 14:46:49 -0700 Subject: [PATCH 068/480] Changed to use passed in type value for signal type instead of assuming both audio and video --- .../Transmitters/DmTx4kz302CController.cs | 713 +++++++++--------- 1 file changed, 360 insertions(+), 353 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index 1c5ce36e..fb8f3ac5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -1,44 +1,44 @@ -using Crestron.SimplSharpPro; -using System; -using System.Linq; -//using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.DM -{ - using eVst = eX02VideoSourceType; - using eAst = eX02AudioSourceType; - - +using Crestron.SimplSharpPro; +using System; +using System.Linq; +//using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.DM +{ + using eVst = eX02VideoSourceType; + using eAst = eX02AudioSourceType; + + [Description("Wrapper class for DM-TX-4K-Z-302-C")] - public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback, - IIROutputPorts, IComPorts - { - public DmTx4kz302C Tx { get; private set; } - - public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } - public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } - public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } - public RoutingOutputPort DmOut { get; private set; } - public RoutingOutputPort HdmiLoopOut { get; private set; } - - public override StringFeedback ActiveVideoInputFeedback { get; protected set; } - public IntFeedback VideoSourceNumericFeedback { get; protected set; } - public IntFeedback AudioSourceNumericFeedback { get; protected set; } - public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } - public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } - public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } - public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } - public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } - - //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } + public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback, + IIROutputPorts, IComPorts + { + public DmTx4kz302C Tx { get; private set; } + + public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } + public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } + public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } + public RoutingOutputPort DmOut { get; private set; } + public RoutingOutputPort HdmiLoopOut { get; private set; } + + public override StringFeedback ActiveVideoInputFeedback { get; protected set; } + public IntFeedback VideoSourceNumericFeedback { get; protected set; } + public IntFeedback AudioSourceNumericFeedback { get; protected set; } + public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } + public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } + public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } + public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } + public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } + + //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; } //IroutingNumericEvent @@ -52,279 +52,286 @@ namespace PepperDash.Essentials.DM { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } - - /// - /// Helps get the "real" inputs, including when in Auto - /// - public eX02VideoSourceType ActualActiveVideoInput - { - get - { - if (Tx.VideoSourceFeedback != eVst.Auto) - return Tx.VideoSourceFeedback; - if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - return eVst.Hdmi1; - if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) - return eVst.Hdmi2; - - return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled; - } - } - public RoutingPortCollection InputPorts - { - get - { - return new RoutingPortCollection - { - HdmiIn1, - HdmiIn2, - DisplayPortIn, - AnyVideoInput - }; - } - } - public RoutingPortCollection OutputPorts - { - get - { - return new RoutingPortCollection { DmOut, HdmiLoopOut }; - } - } - public DmTx4kz302CController(string key, string name, DmTx4kz302C tx) - : base(key, name, tx) - { - Tx = tx; - - HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, + } + + /// + /// Helps get the "real" inputs, including when in Auto + /// + public eX02VideoSourceType ActualActiveVideoInput + { + get + { + if (Tx.VideoSourceFeedback != eVst.Auto) + return Tx.VideoSourceFeedback; + if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + return eVst.Hdmi1; + if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) + return eVst.Hdmi2; + + return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled; + } + } + public RoutingPortCollection InputPorts + { + get + { + return new RoutingPortCollection + { + HdmiIn1, + HdmiIn2, + DisplayPortIn, + AnyVideoInput + }; + } + } + public RoutingPortCollection OutputPorts + { + get + { + return new RoutingPortCollection { DmOut, HdmiLoopOut }; + } + } + public DmTx4kz302CController(string key, string name, DmTx4kz302C tx) + : base(key, name, tx) + { + Tx = tx; + + HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])) { FeedbackMatchObject = eVst.Hdmi1 - }; - HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, + }; + HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])) { FeedbackMatchObject = eVst.Hdmi2 - }; - DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this, + }; + DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this, VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput)) { FeedbackMatchObject = eVst.DisplayPort - }; - ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", - () => ActualActiveVideoInput.ToString()); - - Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; - Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; - Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange; - Tx.BaseEvent += Tx_BaseEvent; - Tx.OnlineStatusChange += Tx_OnlineStatusChange; - - VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - - HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); - - HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpStateFeedback = - new IntFeedback( - () => - tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback - ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback - : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; - - Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); - - Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); - - DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue); - - - var combinedFuncs = new VideoStatusFuncsWrapper - { - HdcpActiveFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), - - HdcpStateFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); - return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : ""; - }, - - VideoResolutionFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); - if (ActualActiveVideoInput == eVst.Hdmi2) - return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); - return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : ""; - }, - VideoSyncFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Vga - && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) - - }; - - AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); - - DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, null, this); - HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - - - AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, - AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, - AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, - AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, - Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback); - - // Set Ports for CEC - HdmiIn1.Port = Tx.HdmiInputs[1]; - HdmiIn2.Port = Tx.HdmiInputs[2]; - HdmiLoopOut.Port = Tx.HdmiOutput; - DmOut.Port = Tx.DmOutput; - } - - void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) - { - Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); - - switch (args.EventId) - { - case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: - DisplayPortVideoSyncFeedback.FireUpdate(); - break; - } - } - - - - public override bool CustomActivate() - { - // Link up all of these damned events to the various RoutingPorts via a helper handler - Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); - Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); - - Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); - Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); - - Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); - Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); - - // Base does register and sets up comm monitoring. - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); - - if (Hdmi1VideoSyncFeedback != null) - { - Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); - } - if (Hdmi2VideoSyncFeedback != null) - { - Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); - } - if (DisplayPortVideoSyncFeedback != null) - { - DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]); - } - - LinkDmTxToApi(this, trilist, joinMap, bridge); - } - - public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) - { - Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); - - switch (input) - { - case 0: - { - ExecuteSwitch(eVst.Auto, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 1: - { - ExecuteSwitch(HdmiIn1.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 2: - { - ExecuteSwitch(HdmiIn2.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 3: - { - ExecuteSwitch(DisplayPortIn.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 4: - { - ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } + }; + ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", + () => ActualActiveVideoInput.ToString()); + + Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; + Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; + Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange; + Tx.BaseEvent += Tx_BaseEvent; + Tx.OnlineStatusChange += Tx_OnlineStatusChange; + + VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + + HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); + + HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpStateFeedback = + new IntFeedback( + () => + tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback + ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback + : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; + + Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); + + Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); + + DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue); + + + var combinedFuncs = new VideoStatusFuncsWrapper + { + HdcpActiveFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), + + HdcpStateFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); + return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : ""; + }, + + VideoResolutionFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); + if (ActualActiveVideoInput == eVst.Hdmi2) + return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); + return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : ""; + }, + VideoSyncFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Vga + && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) + + }; + + AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); + + DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, null, this); + HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + + AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, + AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, + AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, + AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, + Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback); + + // Set Ports for CEC + HdmiIn1.Port = Tx.HdmiInputs[1]; + HdmiIn2.Port = Tx.HdmiInputs[2]; + HdmiLoopOut.Port = Tx.HdmiOutput; + DmOut.Port = Tx.DmOutput; + } + + void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) + { + Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); + + switch (args.EventId) + { + case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: + DisplayPortVideoSyncFeedback.FireUpdate(); + break; + } + } + + + + public override bool CustomActivate() + { + // Link up all of these damned events to the various RoutingPorts via a helper handler + Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); + Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); + + Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); + Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); + + Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); + Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); + + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); + + if (Hdmi1VideoSyncFeedback != null) + { + Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); + } + if (Hdmi2VideoSyncFeedback != null) + { + Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); + } + if (DisplayPortVideoSyncFeedback != null) + { + DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]); + } + + LinkDmTxToApi(this, trilist, joinMap, bridge); + } + + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) + { + Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); + + switch (input) + { + case 0: + { + ExecuteSwitch(eVst.Auto, null, type); + break; + } + case 1: + { + ExecuteSwitch(HdmiIn1.Selector, null, type); + break; + } + case 2: + { + ExecuteSwitch(HdmiIn2.Selector, null, type); + break; + } + case 3: + { + ExecuteSwitch(DisplayPortIn.Selector, null, type); + break; + } + case 4: + { + ExecuteSwitch(eVst.AllDisabled, null, type); + break; + } default: { Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input); break; - } - - } - - - } - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); - if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) - Tx.VideoSource = (eVst)inputSelector; - - // NOTE: It's possible that this particular TX model may not like the AudioSource property being set. - // The SIMPL definition only shows a single analog for AudioVideo Source - if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - //it doesn't - Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); - //Tx.AudioSource = (eAst)inputSelector; - } - - void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) - { - Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); - - switch (args.EventId) - { - case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: - case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: - case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); - HdcpStateFeedback.FireUpdate(); - break; - case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); - break; - } + } + + } + + + } + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + try + { + Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); + if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) + Tx.VideoSource = (eVst)inputSelector; + + // NOTE: It's possible that this particular TX model may not like the AudioSource property being set. + // The SIMPL definition only shows a single analog for AudioVideo Source + if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + //it doesn't + Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); + //Tx.AudioSource = (eAst)inputSelector; + } + catch (Exception e) + { + Debug.Console(2, this, "Exception in ExecuteSwitch: {0}", e); + } + } + + void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) + { + Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); + + switch (args.EventId) + { + case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: + case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: + case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); + HdcpStateFeedback.FireUpdate(); + break; + case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); + break; + } } void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) @@ -363,57 +370,57 @@ namespace PepperDash.Essentials.DM OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio)); break; } - } - - /// - /// Relays the input stream change to the appropriate RoutingInputPort. - /// - void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return; - inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); - } - - /// - /// Relays the VideoAttributes change to a RoutingInputPort - /// - void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds - //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", - // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); - switch (eventId) - { - case VideoAttributeEventIds.HdcpActiveFeedbackEventId: - inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HdcpStateFeedbackEventId: - inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: - case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - } - } - - - #region IIROutputPorts Members - public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } - public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } - #endregion - - #region IComPorts Members - public CrestronCollection ComPorts { get { return Tx.ComPorts; } } - public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } - #endregion - } + } + + /// + /// Relays the input stream change to the appropriate RoutingInputPort. + /// + void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return; + inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); + } + + /// + /// Relays the VideoAttributes change to a RoutingInputPort + /// + void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds + //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", + // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); + switch (eventId) + { + case VideoAttributeEventIds.HdcpActiveFeedbackEventId: + inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HdcpStateFeedbackEventId: + inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: + case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + } + } + + + #region IIROutputPorts Members + public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } + public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } + #endregion + + #region IComPorts Members + public CrestronCollection ComPorts { get { return Tx.ComPorts; } } + public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } + #endregion + } } \ No newline at end of file From 91abe4c09a78c904193a285692e6170c7922c22a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 7 Jan 2021 15:23:35 -0700 Subject: [PATCH 069/480] Updates to IR files and Enter command --- IR Drivers/Comcast X1.ir | Bin 3757 -> 3757 bytes IR Drivers/DirecTV H21.ir | Bin 3854 -> 3872 bytes .../SetTopBox/IRSetTopBoxBase.cs | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/IR Drivers/Comcast X1.ir b/IR Drivers/Comcast X1.ir index bff5afff90cd427859f081cb3ae4b0ec91ce3004..4f6c638e63b27f78ee33fd30f295b789b8b7c2b0 100644 GIT binary patch delta 16 XcmZ20yH<8WD664?xsl<nYguCN_1FC Pby>>wSjsjo%Hab54CfFe delta 41 xcmZ1=*C!{!^1(BR Date: Thu, 7 Jan 2021 19:31:24 -0500 Subject: [PATCH 070/480] Add safety check for casting device into interface (device as IRoutingInputsOutputs).InputPorts will throw Exception on accessing InputPorts property if device do not implement such interface. --- .../PepperDashEssentialsBase/Devices/DeviceManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index 0e4efa10..55bc523a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -360,9 +360,9 @@ namespace PepperDash.Essentials.Core { var device = GetDeviceForKey(s); - if (device == null) return; - var inputPorts = (device as IRoutingInputsOutputs).InputPorts; - var outputPorts = (device as IRoutingInputsOutputs).OutputPorts; + if (device == null) return; + var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null; + var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null; if (inputPorts != null) { Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count); From 030d69c190f9cfd3127ebbcc327d732d7ac4ce66 Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Tue, 12 Jan 2021 09:20:15 -0500 Subject: [PATCH 071/480] fixes a bug where the system monitor bridge wasn't updating - fires off all program start/stop/register feedbacks when they are created to set initial state --- .../Monitoring/SystemMonitorController.cs | 1352 +++++++++-------- 1 file changed, 679 insertions(+), 673 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index eadaab12..ec18c995 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -1,106 +1,106 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.Diagnostics; -using PepperDash.Core; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.Core.Monitoring -{ - /// - /// Wrapper for the static SystemMonitor class to extend functionality and provide external access - /// to SystemMonitor via APIs - /// - public class SystemMonitorController : EssentialsBridgeableDevice - { - private const long UptimePollTime = 300000; - private CTimer _uptimePollTimer; - - private string _uptime; - private string _lastStart; - - public event EventHandler SystemMonitorPropertiesChanged; - - public Dictionary ProgramStatusFeedbackCollection; - public Dictionary EthernetStatusFeedbackCollection; - - public IntFeedback TimeZoneFeedback { get; protected set; } - public StringFeedback TimeZoneTextFeedback { get; protected set; } - - public StringFeedback IoControllerVersionFeedback { get; protected set; } - public StringFeedback SnmpVersionFeedback { get; protected set; } - public StringFeedback BaCnetAppVersionFeedback { get; protected set; } - public StringFeedback ControllerVersionFeedback { get; protected set; } - - //new feedbacks. Issue #50 - public StringFeedback SerialNumberFeedback { get; protected set; } - public StringFeedback ModelFeedback { get; set; } - - public StringFeedback UptimeFeedback { get; set; } - public StringFeedback LastStartFeedback { get; set; } - - public SystemMonitorController(string key) - : base(key) - { - Debug.Console(2, this, "Adding SystemMonitorController."); - - SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; - - TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); - TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); - - IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); - SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); - BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); - ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); - - SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); - ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); - UptimeFeedback = new StringFeedback(() => _uptime); - LastStartFeedback = new StringFeedback(()=> _lastStart); - - ProgramStatusFeedbackCollection = new Dictionary(); - - foreach (var prog in SystemMonitor.ProgramCollection) - { - var program = new ProgramStatusFeedbacks(prog); - ProgramStatusFeedbackCollection.Add(prog.Number, program); - } - - CreateEthernetStatusFeedbacks(); - UpdateEthernetStatusFeeedbacks(); - - _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); - - SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; - SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; - CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; - CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; - } - - private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) - { - if (programEventType != eProgramStatusEventType.Stopping) return; - - _uptimePollTimer.Stop(); - _uptimePollTimer.Dispose(); - _uptimePollTimer = null; - } - - private void PollUptime(object obj) - { - var consoleResponse = string.Empty; - - CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); - - ParseUptime(consoleResponse); - - UptimeFeedback.FireUpdate(); - LastStartFeedback.FireUpdate(); +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.Diagnostics; +using PepperDash.Core; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.Core.Monitoring +{ + /// + /// Wrapper for the static SystemMonitor class to extend functionality and provide external access + /// to SystemMonitor via APIs + /// + public class SystemMonitorController : EssentialsBridgeableDevice + { + private const long UptimePollTime = 300000; + private CTimer _uptimePollTimer; + + private string _uptime; + private string _lastStart; + + public event EventHandler SystemMonitorPropertiesChanged; + + public Dictionary ProgramStatusFeedbackCollection; + public Dictionary EthernetStatusFeedbackCollection; + + public IntFeedback TimeZoneFeedback { get; protected set; } + public StringFeedback TimeZoneTextFeedback { get; protected set; } + + public StringFeedback IoControllerVersionFeedback { get; protected set; } + public StringFeedback SnmpVersionFeedback { get; protected set; } + public StringFeedback BaCnetAppVersionFeedback { get; protected set; } + public StringFeedback ControllerVersionFeedback { get; protected set; } + + //new feedbacks. Issue #50 + public StringFeedback SerialNumberFeedback { get; protected set; } + public StringFeedback ModelFeedback { get; set; } + + public StringFeedback UptimeFeedback { get; set; } + public StringFeedback LastStartFeedback { get; set; } + + public SystemMonitorController(string key) + : base(key) + { + Debug.Console(2, this, "Adding SystemMonitorController."); + + SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; + + TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); + TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); + + IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); + SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); + BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); + ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); + + SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); + ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); + UptimeFeedback = new StringFeedback(() => _uptime); + LastStartFeedback = new StringFeedback(()=> _lastStart); + + ProgramStatusFeedbackCollection = new Dictionary(); + + foreach (var prog in SystemMonitor.ProgramCollection) + { + var program = new ProgramStatusFeedbacks(prog); + ProgramStatusFeedbackCollection.Add(prog.Number, program); + } + + CreateEthernetStatusFeedbacks(); + UpdateEthernetStatusFeeedbacks(); + + _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); + + SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; + SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; + CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; + } + + private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType != eProgramStatusEventType.Stopping) return; + + _uptimePollTimer.Stop(); + _uptimePollTimer.Dispose(); + _uptimePollTimer = null; + } + + private void PollUptime(object obj) + { + var consoleResponse = string.Empty; + + CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); + + ParseUptime(consoleResponse); + + UptimeFeedback.FireUpdate(); + LastStartFeedback.FireUpdate(); } private void ParseUptime(string response) @@ -123,94 +123,94 @@ namespace PepperDash.Essentials.Core.Monitoring _uptime = uptimeRaw.Substring(forIndex + 4); } - private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) - { - if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; - - foreach (var fb in EthernetStatusFeedbackCollection) - { - fb.Value.UpdateEthernetStatus(); - } - } - - private void CreateEthernetStatusFeedbacks() - { - EthernetStatusFeedbackCollection = new Dictionary(); - - Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); - - for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) - { - Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); - var ethernetInterface = new EthernetStatusFeedbacks(i); - EthernetStatusFeedbackCollection.Add(i, ethernetInterface); - } - } - - private void UpdateEthernetStatusFeeedbacks() - { - foreach (var iface in EthernetStatusFeedbackCollection) - { - iface.Value.CurrentIpAddressFeedback.FireUpdate(); - iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); - iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); - iface.Value.StaticIpAddressFeedback.FireUpdate(); - iface.Value.StaticSubnetMaskFeedback.FireUpdate(); - iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); - iface.Value.HostNameFeedback.FireUpdate(); - iface.Value.DnsServerFeedback.FireUpdate(); - iface.Value.DomainFeedback.FireUpdate(); - iface.Value.DhcpStatusFeedback.FireUpdate(); - iface.Value.MacAddressFeedback.FireUpdate(); - } - } - - /// - /// Gets data in separate thread - /// - private void RefreshSystemMonitorData() - { - // this takes a while, launch a new thread - CrestronInvoke.BeginInvoke(UpdateFeedback); - } - - private void UpdateFeedback(object o) - { - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - IoControllerVersionFeedback.FireUpdate(); - SnmpVersionFeedback.FireUpdate(); - BaCnetAppVersionFeedback.FireUpdate(); - ControllerVersionFeedback.FireUpdate(); - SerialNumberFeedback.FireUpdate(); - ModelFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - - private void OnSystemMonitorPropertiesChanged() - { - var handler = SystemMonitorPropertiesChanged; - if (handler != null) - { - handler(this, new EventArgs()); - } - } - - public override bool CustomActivate() - { - RefreshSystemMonitorData(); - - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) { - var joinMap = new SystemMonitorJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) + if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; + + foreach (var fb in EthernetStatusFeedbackCollection) + { + fb.Value.UpdateEthernetStatus(); + } + } + + private void CreateEthernetStatusFeedbacks() + { + EthernetStatusFeedbackCollection = new Dictionary(); + + Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); + + for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) + { + Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); + var ethernetInterface = new EthernetStatusFeedbacks(i); + EthernetStatusFeedbackCollection.Add(i, ethernetInterface); + } + } + + private void UpdateEthernetStatusFeeedbacks() + { + foreach (var iface in EthernetStatusFeedbackCollection) + { + iface.Value.CurrentIpAddressFeedback.FireUpdate(); + iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); + iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); + iface.Value.StaticIpAddressFeedback.FireUpdate(); + iface.Value.StaticSubnetMaskFeedback.FireUpdate(); + iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); + iface.Value.HostNameFeedback.FireUpdate(); + iface.Value.DnsServerFeedback.FireUpdate(); + iface.Value.DomainFeedback.FireUpdate(); + iface.Value.DhcpStatusFeedback.FireUpdate(); + iface.Value.MacAddressFeedback.FireUpdate(); + } + } + + /// + /// Gets data in separate thread + /// + private void RefreshSystemMonitorData() + { + // this takes a while, launch a new thread + CrestronInvoke.BeginInvoke(UpdateFeedback); + } + + private void UpdateFeedback(object o) + { + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + IoControllerVersionFeedback.FireUpdate(); + SnmpVersionFeedback.FireUpdate(); + BaCnetAppVersionFeedback.FireUpdate(); + ControllerVersionFeedback.FireUpdate(); + SerialNumberFeedback.FireUpdate(); + ModelFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + private void OnSystemMonitorPropertiesChanged() + { + var handler = SystemMonitorPropertiesChanged; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + + public override bool CustomActivate() + { + RefreshSystemMonitorData(); + + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new SystemMonitorJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); if (bridge != null) @@ -220,11 +220,11 @@ namespace PepperDash.Essentials.Core.Monitoring else { Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - Debug.Console(2, this, "Linking API starting at join: {0}", joinStart); - + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(2, this, "Linking API starting at join: {0}", joinStart); + TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone.JoinNumber]); TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName.JoinNumber]); @@ -235,18 +235,18 @@ namespace PepperDash.Essentials.Core.Monitoring SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber.JoinNumber]); ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model.JoinNumber]); UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime.JoinNumber]); - LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]); - - // iterate the program status feedback collection and map all the joins - LinkProgramInfoJoins(this, trilist, joinMap); - - LinkEthernetInfoJoins(this, trilist, joinMap); - } - - private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) + LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]); + + // iterate the program status feedback collection and map all the joins + LinkProgramInfoJoins(this, trilist, joinMap); + + LinkEthernetInfoJoins(this, trilist, joinMap); + } + + private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) { - uint ethernetSlotJoinStart = 0; - foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) + uint ethernetSlotJoinStart = 0; + foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) { fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress.JoinNumber]); fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask.JoinNumber]); @@ -258,494 +258,500 @@ namespace PepperDash.Essentials.Core.Monitoring fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress.JoinNumber]); fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain.JoinNumber]); fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer.JoinNumber]); - fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]); - - ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber; - } - } - - private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, - SystemMonitorJoinMap joinMap) + fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]); + + ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber; + } + } + + private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, + SystemMonitorJoinMap joinMap) { - uint programSlotJoinStart = 0; - - foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) - { + uint programSlotJoinStart = 0; + + foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) + { var programNumber = p.Value.Program.Number; - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber, + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber, + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber, - b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); p.Value.ProgramRegisteredFeedback.LinkInputSig( trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber, - b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); p.Value.ProgramUnregisteredFeedback.LinkInputSig( trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber]); - p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]); + p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]); p.Value.ProgramCompileTimeFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]); p.Value.CrestronDataBaseVersionFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]); p.Value.EnvironmentVersionFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]); p.Value.AggregatedProgramInfoFeedback.LinkInputSig( trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo.JoinNumber]); - programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber; - } - } - - //// Sets the time zone - //public void SetTimeZone(int timeZone) - //{ - // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone; - //} - - /// - /// Responds to program change events and triggers the appropriate feedbacks to update - /// - /// - /// - private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) - { - Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); - Debug.Console(2, this, "Event Type: {0}", args.EventType); - - var program = ProgramStatusFeedbackCollection[sender.Number]; - - switch (args.EventType) - { - case eProgramChangeEventType.OperatingState: - program.ProgramStartedFeedback.FireUpdate(); - program.ProgramStoppedFeedback.FireUpdate(); - program.ProgramInfo.OperatingState = args.OperatingState; - if (args.OperatingState == eProgramOperatingState.Start) - program.GetProgramInfo(); - else - { - program.AggregatedProgramInfoFeedback.FireUpdate(); - program.OnProgramInfoChanged(); - } - break; - case eProgramChangeEventType.RegistrationState: - program.ProgramRegisteredFeedback.FireUpdate(); - program.ProgramUnregisteredFeedback.FireUpdate(); - program.ProgramInfo.RegistrationState = args.RegistrationState; - program.GetProgramInfo(); - break; - } - } - - /// - /// Responds to time zone changes and updates the appropriate feedbacks - /// - /// - private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) - { - Debug.Console(2, this, "Time Zone Change Detected."); - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - - public class EthernetStatusFeedbacks - { - public StringFeedback HostNameFeedback { get; protected set; } - public StringFeedback DnsServerFeedback { get; protected set; } - public StringFeedback DomainFeedback { get; protected set; } - public StringFeedback MacAddressFeedback { get; protected set; } - public StringFeedback DhcpStatusFeedback { get; protected set; } - - public StringFeedback CurrentIpAddressFeedback { get; protected set; } - public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } - public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } - - public StringFeedback StaticIpAddressFeedback { get; protected set; } - public StringFeedback StaticSubnetMaskFeedback { get; protected set; } - public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } - - public EthernetStatusFeedbacks(short adapterIndex) - { - Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); - Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); - HostNameFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); - - CurrentIpAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); - CurrentDefaultGatewayFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); - CurrentSubnetMaskFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); - StaticIpAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); - StaticDefaultGatewayFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); - StaticSubnetMaskFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); - DomainFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); - DnsServerFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); - MacAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); - - DhcpStatusFeedback = new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); - } - - public void UpdateEthernetStatus() - { - HostNameFeedback.FireUpdate(); - CurrentIpAddressFeedback.FireUpdate(); - CurrentSubnetMaskFeedback.FireUpdate(); - CurrentDefaultGatewayFeedback.FireUpdate(); - StaticIpAddressFeedback.FireUpdate(); - StaticSubnetMaskFeedback.FireUpdate(); - StaticDefaultGatewayFeedback.FireUpdate(); - DomainFeedback.FireUpdate(); - DnsServerFeedback.FireUpdate(); - MacAddressFeedback.FireUpdate(); - DhcpStatusFeedback.FireUpdate(); - } - } - - - public class ProgramStatusFeedbacks - { - public event EventHandler ProgramInfoChanged; - - public Program Program; - - public ProgramInfo ProgramInfo { get; set; } - - public BoolFeedback ProgramStartedFeedback; - public BoolFeedback ProgramStoppedFeedback; - public BoolFeedback ProgramRegisteredFeedback; - public BoolFeedback ProgramUnregisteredFeedback; - - public StringFeedback ProgramNameFeedback; - public StringFeedback ProgramCompileTimeFeedback; - public StringFeedback CrestronDataBaseVersionFeedback; - // SIMPL windows version - public StringFeedback EnvironmentVersionFeedback; - public StringFeedback AggregatedProgramInfoFeedback; - - public ProgramStatusFeedbacks(Program program) - { - ProgramInfo = new ProgramInfo(program.Number); - - Program = program; - - ProgramInfo.OperatingState = Program.OperatingState; - ProgramInfo.RegistrationState = Program.RegistrationState; - - ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); - ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); - ProgramRegisteredFeedback = - new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); - ProgramUnregisteredFeedback = - new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); - - ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); - ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); - CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); - EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); - - AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); - - GetProgramInfo(); - } - - /// - /// Retrieves information about a running program - /// - public void GetProgramInfo() - { - CrestronInvoke.BeginInvoke(GetProgramInfo); - } - - private void GetProgramInfo(object o) - { - Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); - - string response = null; - - if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) - { - Debug.Console(2, "Program {0} not registered. Setting default values for program information.", - Program.Number); - - ProgramInfo = new ProgramInfo(Program.Number) - { - OperatingState = Program.OperatingState, - RegistrationState = Program.RegistrationState - }; - - return; - } - - var success = CrestronConsole.SendControlSystemCommand( - string.Format("progcomments:{0}", Program.Number), ref response); - - if (!success) - { - Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); - UpdateFeedbacks(); - return; - } - - if (response.ToLower().Contains("bad or incomplete")) - { - Debug.Console(2, - "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", - Program.Number); - - // Assume no valid program info. Constructing a new object will wipe all properties - ProgramInfo = new ProgramInfo(Program.Number) - { - OperatingState = Program.OperatingState, - RegistrationState = Program.RegistrationState - }; - - UpdateFeedbacks(); - - return; - } - - - // Shared properteis - ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); - ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); - ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); - ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); - - - if (ProgramInfo.ProgramFile.Contains(".dll")) - { - // 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"); - } - else if (ProgramInfo.ProgramFile.Contains(".smw")) - { - // SIMPL Windows Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); - ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); - ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); - ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); - ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); - } - Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); - - UpdateFeedbacks(); - } - - private void UpdateFeedbacks() - { - ProgramNameFeedback.FireUpdate(); - ProgramCompileTimeFeedback.FireUpdate(); - CrestronDataBaseVersionFeedback.FireUpdate(); - EnvironmentVersionFeedback.FireUpdate(); - - AggregatedProgramInfoFeedback.FireUpdate(); - - OnProgramInfoChanged(); - } - - public void OnProgramInfoChanged() - { - //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number); - var handler = ProgramInfoChanged; - if (handler != null) - { - handler(this, new ProgramInfoEventArgs(ProgramInfo)); - } - } - - private string ParseConsoleData(string data, string line, string startString, string endString) - { - var outputData = ""; - - if (data.Length <= 0) return outputData; - - try - { - //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); - var linePosition = data.IndexOf(line, StringComparison.Ordinal); - var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + - startString.Length; - var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); - outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); - //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); - } - catch (Exception e) - { - Debug.Console(1, "Error Parsing Console Data:\r{0}", e); - } - - return outputData; - } - } - } - - /// - /// Class for serializing program slot information - /// - public class ProgramInfo - { - // Shared properties - - [JsonProperty("programNumber")] - public uint ProgramNumber { get; private set; } - - [JsonConverter(typeof (StringEnumConverter))] - [JsonProperty("operatingState")] - public eProgramOperatingState OperatingState { get; set; } - - [JsonConverter(typeof (StringEnumConverter))] - [JsonProperty("registrationState")] - public eProgramRegistrationState RegistrationState { get; set; } - - [JsonProperty("programFile")] - public string ProgramFile { get; set; } - - [JsonProperty("friendlyName")] - public string FriendlyName { get; set; } - - [JsonProperty("compilerRevision")] - public string CompilerRevision { get; set; } - - [JsonProperty("compileTime")] - public string CompileTime { get; set; } - - [JsonProperty("include4Dat")] - public string Include4Dat { get; set; } - - // SIMPL Windows properties - [JsonProperty("systemName")] - public string SystemName { get; set; } - - [JsonProperty("crestronDb")] - public string CrestronDb { get; set; } - - [JsonProperty("environment")] - public string Environment { get; set; } - - [JsonProperty("programmer")] - public string Programmer { get; set; } - - - // SSP Properties - [JsonProperty("applicationName")] - public string ApplicationName { get; set; } - - [JsonProperty("programTool")] - public string ProgramTool { get; set; } - - [JsonProperty("minFirmwareVersion")] - public string MinFirmwareVersion { get; set; } - - [JsonProperty("plugInVersion")] - public string PlugInVersion { get; set; } - - public ProgramInfo(uint number) - { - ProgramNumber = number; - - ProgramFile = ""; - FriendlyName = ""; - CompilerRevision = ""; - CompileTime = ""; - Include4Dat = ""; - - SystemName = ""; - CrestronDb = ""; - Environment = ""; - Programmer = ""; - - ApplicationName = ""; - ProgramTool = ""; - MinFirmwareVersion = ""; - PlugInVersion = ""; - } - } - - public class ProgramInfoEventArgs : EventArgs - { - public ProgramInfo ProgramInfo; - - public ProgramInfoEventArgs(ProgramInfo progInfo) - { - ProgramInfo = progInfo; - } - } + programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber; + } + } + + //// Sets the time zone + //public void SetTimeZone(int timeZone) + //{ + // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone; + //} + + /// + /// Responds to program change events and triggers the appropriate feedbacks to update + /// + /// + /// + private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) + { + Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); + Debug.Console(2, this, "Event Type: {0}", args.EventType); + + var program = ProgramStatusFeedbackCollection[sender.Number]; + + switch (args.EventType) + { + case eProgramChangeEventType.OperatingState: + program.ProgramStartedFeedback.FireUpdate(); + program.ProgramStoppedFeedback.FireUpdate(); + program.ProgramInfo.OperatingState = args.OperatingState; + if (args.OperatingState == eProgramOperatingState.Start) + program.GetProgramInfo(); + else + { + program.AggregatedProgramInfoFeedback.FireUpdate(); + program.OnProgramInfoChanged(); + } + break; + case eProgramChangeEventType.RegistrationState: + program.ProgramRegisteredFeedback.FireUpdate(); + program.ProgramUnregisteredFeedback.FireUpdate(); + program.ProgramInfo.RegistrationState = args.RegistrationState; + program.GetProgramInfo(); + break; + } + } + + /// + /// Responds to time zone changes and updates the appropriate feedbacks + /// + /// + private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) + { + Debug.Console(2, this, "Time Zone Change Detected."); + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + public class EthernetStatusFeedbacks + { + public StringFeedback HostNameFeedback { get; protected set; } + public StringFeedback DnsServerFeedback { get; protected set; } + public StringFeedback DomainFeedback { get; protected set; } + public StringFeedback MacAddressFeedback { get; protected set; } + public StringFeedback DhcpStatusFeedback { get; protected set; } + + public StringFeedback CurrentIpAddressFeedback { get; protected set; } + public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } + public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } + + public StringFeedback StaticIpAddressFeedback { get; protected set; } + public StringFeedback StaticSubnetMaskFeedback { get; protected set; } + public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } + + public EthernetStatusFeedbacks(short adapterIndex) + { + Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); + Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); + HostNameFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); + + CurrentIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + CurrentDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + CurrentSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + StaticIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + StaticDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + StaticSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + DomainFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); + DnsServerFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); + MacAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); + + DhcpStatusFeedback = new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); + } + + public void UpdateEthernetStatus() + { + HostNameFeedback.FireUpdate(); + CurrentIpAddressFeedback.FireUpdate(); + CurrentSubnetMaskFeedback.FireUpdate(); + CurrentDefaultGatewayFeedback.FireUpdate(); + StaticIpAddressFeedback.FireUpdate(); + StaticSubnetMaskFeedback.FireUpdate(); + StaticDefaultGatewayFeedback.FireUpdate(); + DomainFeedback.FireUpdate(); + DnsServerFeedback.FireUpdate(); + MacAddressFeedback.FireUpdate(); + DhcpStatusFeedback.FireUpdate(); + } + } + + + public class ProgramStatusFeedbacks + { + public event EventHandler ProgramInfoChanged; + + public Program Program; + + public ProgramInfo ProgramInfo { get; set; } + + public BoolFeedback ProgramStartedFeedback; + public BoolFeedback ProgramStoppedFeedback; + public BoolFeedback ProgramRegisteredFeedback; + public BoolFeedback ProgramUnregisteredFeedback; + + public StringFeedback ProgramNameFeedback; + public StringFeedback ProgramCompileTimeFeedback; + public StringFeedback CrestronDataBaseVersionFeedback; + // SIMPL windows version + public StringFeedback EnvironmentVersionFeedback; + public StringFeedback AggregatedProgramInfoFeedback; + + public ProgramStatusFeedbacks(Program program) + { + ProgramInfo = new ProgramInfo(program.Number); + + Program = program; + + ProgramInfo.OperatingState = Program.OperatingState; + ProgramInfo.RegistrationState = Program.RegistrationState; + + ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); + ProgramStartedFeedback.FireUpdate(); + + ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); + ProgramStoppedFeedback.FireUpdate(); + + ProgramRegisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); + ProgramRegisteredFeedback.FireUpdate(); + + ProgramUnregisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); + ProgramUnregisteredFeedback.FireUpdate(); + + ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); + CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); + EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); + AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); + + GetProgramInfo(); + } + + /// + /// Retrieves information about a running program + /// + public void GetProgramInfo() + { + CrestronInvoke.BeginInvoke(GetProgramInfo); + } + + private void GetProgramInfo(object o) + { + Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + + string response = null; + + if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) + { + Debug.Console(2, "Program {0} not registered. Setting default values for program information.", + Program.Number); + + ProgramInfo = new ProgramInfo(Program.Number) + { + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; + + return; + } + + var success = CrestronConsole.SendControlSystemCommand( + string.Format("progcomments:{0}", Program.Number), ref response); + + if (!success) + { + Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); + UpdateFeedbacks(); + return; + } + + if (response.ToLower().Contains("bad or incomplete")) + { + Debug.Console(2, + "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", + Program.Number); + + // Assume no valid program info. Constructing a new object will wipe all properties + ProgramInfo = new ProgramInfo(Program.Number) + { + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; + + UpdateFeedbacks(); + + return; + } + + + // Shared properteis + ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); + ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); + ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); + ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + + + if (ProgramInfo.ProgramFile.Contains(".dll")) + { + // 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"); + } + else if (ProgramInfo.ProgramFile.Contains(".smw")) + { + // SIMPL Windows Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); + ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); + ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); + ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); + ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + } + Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); + + UpdateFeedbacks(); + } + + private void UpdateFeedbacks() + { + ProgramNameFeedback.FireUpdate(); + ProgramCompileTimeFeedback.FireUpdate(); + CrestronDataBaseVersionFeedback.FireUpdate(); + EnvironmentVersionFeedback.FireUpdate(); + + AggregatedProgramInfoFeedback.FireUpdate(); + + OnProgramInfoChanged(); + } + + public void OnProgramInfoChanged() + { + //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number); + var handler = ProgramInfoChanged; + if (handler != null) + { + handler(this, new ProgramInfoEventArgs(ProgramInfo)); + } + } + + private string ParseConsoleData(string data, string line, string startString, string endString) + { + var outputData = ""; + + if (data.Length <= 0) return outputData; + + try + { + //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); + var linePosition = data.IndexOf(line, StringComparison.Ordinal); + var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + + startString.Length; + var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); + outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); + //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); + } + catch (Exception e) + { + Debug.Console(1, "Error Parsing Console Data:\r{0}", e); + } + + return outputData; + } + } + } + + /// + /// Class for serializing program slot information + /// + public class ProgramInfo + { + // Shared properties + + [JsonProperty("programNumber")] + public uint ProgramNumber { get; private set; } + + [JsonConverter(typeof (StringEnumConverter))] + [JsonProperty("operatingState")] + public eProgramOperatingState OperatingState { get; set; } + + [JsonConverter(typeof (StringEnumConverter))] + [JsonProperty("registrationState")] + public eProgramRegistrationState RegistrationState { get; set; } + + [JsonProperty("programFile")] + public string ProgramFile { get; set; } + + [JsonProperty("friendlyName")] + public string FriendlyName { get; set; } + + [JsonProperty("compilerRevision")] + public string CompilerRevision { get; set; } + + [JsonProperty("compileTime")] + public string CompileTime { get; set; } + + [JsonProperty("include4Dat")] + public string Include4Dat { get; set; } + + // SIMPL Windows properties + [JsonProperty("systemName")] + public string SystemName { get; set; } + + [JsonProperty("crestronDb")] + public string CrestronDb { get; set; } + + [JsonProperty("environment")] + public string Environment { get; set; } + + [JsonProperty("programmer")] + public string Programmer { get; set; } + + + // SSP Properties + [JsonProperty("applicationName")] + public string ApplicationName { get; set; } + + [JsonProperty("programTool")] + public string ProgramTool { get; set; } + + [JsonProperty("minFirmwareVersion")] + public string MinFirmwareVersion { get; set; } + + [JsonProperty("plugInVersion")] + public string PlugInVersion { get; set; } + + public ProgramInfo(uint number) + { + ProgramNumber = number; + + ProgramFile = ""; + FriendlyName = ""; + CompilerRevision = ""; + CompileTime = ""; + Include4Dat = ""; + + SystemName = ""; + CrestronDb = ""; + Environment = ""; + Programmer = ""; + + ApplicationName = ""; + ProgramTool = ""; + MinFirmwareVersion = ""; + PlugInVersion = ""; + } + } + + public class ProgramInfoEventArgs : EventArgs + { + public ProgramInfo ProgramInfo; + + public ProgramInfoEventArgs(ProgramInfo progInfo) + { + ProgramInfo = progInfo; + } + } } \ No newline at end of file From 8ccbed6d812c55da7d4182794368624bfb6a87fe Mon Sep 17 00:00:00 2001 From: Maxim Batourine Date: Sat, 16 Jan 2021 22:57:45 -0500 Subject: [PATCH 072/480] Add hdbasettx device --- .../Endpoints/Transmitters/DmTxHelpers.cs | 10 +- .../Transmitters/HDBaseTTxController.cs | 113 ++++++++++++++++++ 2 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs index fd80ac1f..4d8e41f6 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs @@ -122,7 +122,9 @@ namespace PepperDash.Essentials.DM return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num])); if (typeName.StartsWith("dmtx401")) return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num])); - } + if (typeName.StartsWith("hdbasettx")) + return new HDBaseTTxController(key, name, new HDTx3CB(chassis.Inputs[num])); + } else { if (typeName.StartsWith("dmtx200")) @@ -145,7 +147,9 @@ namespace PepperDash.Essentials.DM return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num])); if (typeName.StartsWith("dmtx401")) return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num])); - } + if (typeName.StartsWith("hdbasettx")) + return new HDBaseTTxController(key, name, new HDTx3CB(ipid, chassis.Inputs[num])); + } } catch (Exception e) { @@ -355,7 +359,7 @@ namespace PepperDash.Essentials.DM public DmTxControllerFactory() { TypeNames = new List() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c", - "dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g" }; + "dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g", "hdbasettx" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs new file mode 100644 index 00000000..800da2a9 --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs @@ -0,0 +1,113 @@ +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.Endpoints.Transmitters; +using Newtonsoft.Json; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.DM +{ + /// + /// Controller class for suitable for HDBaseT transmitters + /// + [Description("Wrapper Class for HDBaseT devices based on HDTx3CB class")] + public class HDBaseTTxController: BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts + { + public RoutingInputPort HdmiIn { get; private set; } + public RoutingOutputPort DmOut { get; private set; } + + public HDBaseTTxController(string key, string name, HDTx3CB tx) + : base(key, name, tx) + { + HdmiIn = new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this) { Port = tx }; + + DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, null, this); + + InputPorts = new RoutingPortCollection { HdmiIn }; + OutputPorts = new RoutingPortCollection { DmOut }; + } + + #region IRoutingInputs Members + + public RoutingPortCollection InputPorts { get; private set; } + + #endregion + + #region IRoutingOutputs Members + + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + #region IComPorts Members + + public CrestronCollection ComPorts { get { return (Hardware as HDTx3CB).ComPorts; } } + public int NumberOfComPorts { get { return (Hardware as HDTx3CB).NumberOfComPorts; } } + + #endregion + + #region CrestronBridgeableBaseDevice abstract overrides + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new HDBaseTTxControllerJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + + } + + #endregion + } + + public class HDBaseTTxControllerJoinMap : JoinMapBaseAdvanced + { + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "HDBaseT device online feedback", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + /// + /// Plugin device BridgeJoinMap constructor + /// + /// This will be the join it starts on the EISC bridge + public HDBaseTTxControllerJoinMap(uint joinStart) + : base(joinStart, typeof(HDBaseTTxControllerJoinMap)) + { + } + } +} \ No newline at end of file From 6d66c5adee5208fc410af8b81870f6dc18a1a9ae Mon Sep 17 00:00:00 2001 From: Maxim Batourine Date: Mon, 18 Jan 2021 13:16:19 -0500 Subject: [PATCH 073/480] add HDBaseTTxController to project file --- .../Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj | 1 + 1 file changed, 1 insertion(+) 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 b1ea1b42..63b20c98 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -108,6 +108,7 @@ + From 7945bce854c6643c9547ccd42580034887a767d5 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Mon, 18 Jan 2021 15:37:39 -0600 Subject: [PATCH 074/480] Upadted VideoCodecBase LinkVideoCodecCallControlsToApi IncomingCall bridge action to reference "args.CallItem.Status == eCodecCallStatus.Ringing" (previously referencing "args.CallItem.Status != eCodecCallStatus.Disconnected") --- .../VideoCodec/VideoCodecBase.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) 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 6b6d5891..8765b0e1 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 @@ -74,10 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { get { - return new List - { - PrivacyModeIsOnFeedback, - SharingSourceFeedback + return new List + { + PrivacyModeIsOnFeedback, + SharingSourceFeedback }; } } @@ -677,19 +677,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec var meetingIndex = 0; var tokenArray = new XSigToken[maxMeetings * offset]; - /* - * Digitals - * IsJoinable - 1 - * IsDialable - 2 - * - * Serials - * Organizer - 1 - * Title - 2 - * Start Date - 3 - * Start Time - 4 - * End Date - 5 - * End Time - 6 - * Id - 7 + /* + * Digitals + * IsJoinable - 1 + * IsDialable - 2 + * + * Serials + * Organizer - 1 + * Title - 2 + * Start Date - 3 + * Start Time - 4 + * End Date - 5 + * End Time - 6 + * Id - 7 */ @@ -848,7 +848,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); - trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); + trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); if (args.CallItem.Direction == eCodecCallDirection.Incoming) { From 52494ca13e5bcc49f0c6446b145c0770ef64b2c4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 21 Jan 2021 15:04:01 -0700 Subject: [PATCH 075/480] Changes to correct datatype for joinMaps in config --- .gitignore | 1 + .../PepperDashEssentialsBase/Config/BasicConfig.cs | 4 +++- .../Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs | 2 +- .../PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs | 8 ++++---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 501c2f26..94b7d400 100644 --- a/.gitignore +++ b/.gitignore @@ -388,3 +388,4 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd +essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index 904bfc74..e76bbf9b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -7,6 +7,8 @@ using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; +using Newtonsoft.Json.Linq; + namespace PepperDash.Essentials.Core.Config { /// @@ -27,7 +29,7 @@ namespace PepperDash.Essentials.Core.Config public List TieLines { get; set; } [JsonProperty("joinMaps")] - public Dictionary JoinMaps { get; set; } + public Dictionary JoinMaps { get; set; } /// /// Checks SourceLists for a given list and returns it if found. Otherwise, returns null diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs index 0b61fed2..33f2fe1b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs @@ -30,7 +30,7 @@ namespace PepperDash.Essentials.Core.Fusion new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorDomain")] - public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - Domain" }, + public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" }, new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial }); [JoinName("ProcessorDns1")] diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index 4fe2d537..52d56dfd 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; - return joinMap; + return joinMap.ToString(); } /// @@ -48,11 +48,11 @@ namespace PepperDash.Essentials.Core if (string.IsNullOrEmpty(joinMapKey)) return null; - var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; + var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; - if (joinMapSerialzed == null) return null; + if (joinMapJToken == null) return null; - var joinMapData = JsonConvert.DeserializeObject>(joinMapSerialzed); + var joinMapData = joinMapJToken.ToObject>(); return joinMapData; } From 9d354fb0ed821a75ff4e514a06bb4bfab207b1f0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 21 Jan 2021 16:46:21 -0700 Subject: [PATCH 076/480] custom fusion joinmap working. updates to hotfix PD.Core build --- PepperDashEssentials/ControlSystem.cs | 15 +- .../EssentialsHuddleVtc1FusionController.cs | 20 +- .../Config/BasicConfig.cs | 2 +- .../Config/Essentials/ConfigReader.cs | 360 +++++++++--------- ...lsHuddleSpaceFusionSystemControllerBase.cs | 49 +-- .../JoinMaps/JoinMapBase.cs | 37 +- packages.config | 2 +- 7 files changed, 255 insertions(+), 230 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 9bec571e..7ffb57b5 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -438,12 +438,17 @@ namespace PepperDash.Essentials // default to no join map key string fusionJoinMapKey = string.Empty; - var fusionConfig = room.Config.Properties["fusion"].ToObject(); - - if (fusionConfig != null) + if (room.Config.Properties["fusion"] != null) { - fusionIpId = fusionConfig.IpIdInt; - fusionJoinMapKey = fusionConfig.JoinMapKey; + Debug.Console(2, "Custom Fusion config found. Using custom values"); + + var fusionConfig = room.Config.Properties["fusion"].ToObject(); + + if (fusionConfig != null) + { + fusionIpId = fusionConfig.IpIdInt; + fusionJoinMapKey = fusionConfig.JoinMapKey; + } } if (room is EssentialsHuddleSpaceRoom) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index b071b681..c4a68d4e 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion // Map FusionRoom Attributes: // Codec volume - var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description, eSigIoMask.InputOutputSig); + var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig); codecVolume.OutputSig.UserObject = new Action(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); // In Call Status - CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.Metadata.Description, eSigIoMask.InputSigOnly); + CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly); codec.CallStatusChange += new EventHandler(codec_CallStatusChange); // Online status if (codec is ICommunicationMonitor) { var c = codec as ICommunicationMonitor; - var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.Metadata.Description, eSigIoMask.InputSigOnly); + var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, eSigIoMask.InputSigOnly); codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; c.CommunicationMonitor.StatusChange += (o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; }; - Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.Metadata.Description); + Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName); } // Codec IP Address @@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion if (codecHasIpInfo) { - codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.Metadata.Description, eSigIoMask.InputSigOnly); + codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly); codecIpAddressSig.InputSig.StringValue = codecIpAddress; - codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.Metadata.Description, eSigIoMask.InputSigOnly); + codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly); codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); } @@ -172,7 +172,7 @@ namespace PepperDash.Essentials.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description, eSigIoMask.InputSigOnly); + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; @@ -196,7 +196,7 @@ namespace PepperDash.Essentials.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots break; @@ -206,7 +206,7 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > 5) // We only have five spots break; @@ -216,7 +216,7 @@ namespace PepperDash.Essentials.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? break; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index e76bbf9b..7cbaa5a1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -29,7 +29,7 @@ namespace PepperDash.Essentials.Core.Config public List TieLines { get; set; } [JsonProperty("joinMaps")] - public Dictionary JoinMaps { get; set; } + public Dictionary JoinMaps { get; set; } /// /// Checks SourceLists for a given list and returns it if found. Otherwise, returns null diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs index 48a026c2..e99206e8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs @@ -1,195 +1,195 @@ -using System; +using System; using System.Linq; using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; -using PepperDash.Core.Config; - -namespace PepperDash.Essentials.Core.Config -{ - /// - /// Loads the ConfigObject from the file - /// +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Core; +using PepperDash.Core.Config; + +namespace PepperDash.Essentials.Core.Config +{ + /// + /// Loads the ConfigObject from the file + /// public class ConfigReader { public const string LocalConfigPresent = @" *************************************************** ************* Using Local config file ************* -***************************************************"; - - public static EssentialsConfig ConfigObject { get; private set; } - - public static bool LoadConfig2() - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file."); - try - { - // Check for local config file first - var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName; - - bool localConfigFound = false; - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath); - - // Check for local config directory first - - var configFiles = GetConfigFiles(filePath); - - if (configFiles != null) - { - if (configFiles.Length > 1) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, - "****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****"); - return false; - } - if(configFiles.Length == 1) - { +***************************************************"; + + public static EssentialsConfig ConfigObject { get; private set; } + + public static bool LoadConfig2() + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file."); + try + { + // Check for local config file first + var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName; + + bool localConfigFound = false; + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath); + + // Check for local config directory first + + var configFiles = GetConfigFiles(filePath); + + if (configFiles != null) + { + if (configFiles.Length > 1) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, + "****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****"); + return false; + } + if(configFiles.Length == 1) + { localConfigFound = true; - - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, - "Local Configuration file not present.", filePath); - - } - - // Check for Portal Config - if(!localConfigFound) - { - filePath = Global.FilePathPrefix + Global.ConfigFileName; - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath); - - configFiles = GetConfigFiles(filePath); - - if (configFiles != null) - { - Debug.Console(2, "{0} config files found matching pattern", configFiles.Length); - - if (configFiles.Length > 1) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, - "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****"); - return false; - } - else if (configFiles.Length == 1) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath); - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found."); - return false; - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Error, - "ERROR: Portal Configuration file not present. Please load file and reset program."); - return false; - } - } - - // Get the actual file path + + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, + "Local Configuration file not present.", filePath); + + } + + // Check for Portal Config + if(!localConfigFound) + { + filePath = Global.FilePathPrefix + Global.ConfigFileName; + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath); + + configFiles = GetConfigFiles(filePath); + + if (configFiles != null) + { + Debug.Console(2, "{0} config files found matching pattern", configFiles.Length); + + if (configFiles.Length > 1) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, + "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****"); + return false; + } + else if (configFiles.Length == 1) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found."); + return false; + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Error, + "ERROR: Portal Configuration file not present. Please load file and reset program."); + return false; + } + } + + // Get the actual file path filePath = configFiles[0].FullName; // Generate debug statement if using a local file. if (localConfigFound) { GetLocalFileMessage(filePath); - } - - // Read the file - using (StreamReader fs = new StreamReader(filePath)) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath); - - if (localConfigFound) - { - ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject(); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config"); - - return true; - } - else - { - var doubleObj = JObject.Parse(fs.ReadToEnd()); - ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject(); - - // Extract SystemUrl and TemplateUrl into final config output - - if (doubleObj["system_url"] != null) - { - ConfigObject.SystemUrl = doubleObj["system_url"].Value(); - } - - if (doubleObj["template_url"] != null) - { - ConfigObject.TemplateUrl = doubleObj["template_url"].Value(); - } - } - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config"); - - return true; - } - } - catch (Exception e) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e); - return false; - } - } - - /// - /// Returns all the files from the directory specified. - /// - /// - /// - public static FileInfo[] GetConfigFiles(string filePath) - { - // Get the directory - var dir = Path.GetDirectoryName(filePath); - - if (Directory.Exists(dir)) - { - Debug.Console(1, "Searching in Directory '{0}'", dir); - // Get the directory info - var dirInfo = new DirectoryInfo(dir); - - // Get the file name - var fileName = Path.GetFileName(filePath); - Debug.Console(1, "For Config Files matching: '{0}'", fileName); - - // Get the files that match from the directory - return dirInfo.GetFiles(fileName); - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, - "Directory not found: ", dir); - - return null; - } - } - - /// - /// Returns the group for a given device key in config - /// - /// - /// - public static string GetGroupForDeviceKey(string key) - { - var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase)); - return dev == null ? null : dev.Group; + } + + // Read the file + using (StreamReader fs = new StreamReader(filePath)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath); + + if (localConfigFound) + { + ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject(); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config"); + + return true; + } + else + { + var doubleObj = JObject.Parse(fs.ReadToEnd()); + ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject(); + + // Extract SystemUrl and TemplateUrl into final config output + + if (doubleObj["system_url"] != null) + { + ConfigObject.SystemUrl = doubleObj["system_url"].Value(); + } + + if (doubleObj["template_url"] != null) + { + ConfigObject.TemplateUrl = doubleObj["template_url"].Value(); + } + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config"); + + return true; + } + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e); + return false; + } + } + + /// + /// Returns all the files from the directory specified. + /// + /// + /// + public static FileInfo[] GetConfigFiles(string filePath) + { + // Get the directory + var dir = Path.GetDirectoryName(filePath); + + if (Directory.Exists(dir)) + { + Debug.Console(1, "Searching in Directory '{0}'", dir); + // Get the directory info + var dirInfo = new DirectoryInfo(dir); + + // Get the file name + var fileName = Path.GetFileName(filePath); + Debug.Console(1, "For Config Files matching: '{0}'", fileName); + + // Get the files that match from the directory + return dirInfo.GetFiles(fileName); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, + "Directory not found: ", dir); + + return null; + } + } + + /// + /// Returns the group for a given device key in config + /// + /// + /// + public static string GetGroupForDeviceKey(string key) + { + var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase)); + return dev == null ? null : dev.Group; } private static void GetLocalFileMessage(string filePath) @@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core.Config Debug.Console(2, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath); Debug.Console(0, newDebugString.ToString()); - } - - } + } + + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 03e1c090..9574743e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -98,7 +98,10 @@ namespace PepperDash.Essentials.Core.Fusion if (!string.IsNullOrEmpty(joinMapKey)) { var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - JoinMap.SetCustomJoinData(customJoins); + if (customJoins != null) + { + JoinMap.SetCustomJoinData(customJoins); + } } Room = room; @@ -339,7 +342,7 @@ namespace PepperDash.Essentials.Core.Fusion Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); // Moved to - CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.Metadata.Description, + CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. var hasCurrentSourceInfoChange = Room as IHasCurrentSourceInfoChange; @@ -389,24 +392,24 @@ namespace PepperDash.Essentials.Core.Fusion var response = string.Empty; - var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, JoinMap.ProcessorReboot.Metadata.Description, eSigIoMask.OutputSigOnly); + var systemReboot = FusionRoom.CreateOffsetBoolSig(JoinMap.ProcessorReboot.JoinNumber, JoinMap.ProcessorReboot.AttributeName, eSigIoMask.OutputSigOnly); systemReboot.OutputSig.SetSigFalseAction( () => CrestronConsole.SendControlSystemCommand("reboot", ref response)); } protected void SetUpEthernetValues() { - _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.Metadata.Description, eSigIoMask.InputSigOnly); - _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, JoinMap.ProcessorIp2.Metadata.Description, eSigIoMask.InputSigOnly); - _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, JoinMap.ProcessorGateway.Metadata.Description, eSigIoMask.InputSigOnly); - _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, JoinMap.ProcessorHostname.Metadata.Description, eSigIoMask.InputSigOnly); - _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, JoinMap.ProcessorDomain.Metadata.Description, eSigIoMask.InputSigOnly); - _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, JoinMap.ProcessorDns1.Metadata.Description, eSigIoMask.InputSigOnly); - _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, JoinMap.ProcessorDns2.Metadata.Description, eSigIoMask.InputSigOnly); - _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, JoinMap.ProcessorMac1.Metadata.Description, eSigIoMask.InputSigOnly); - _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, JoinMap.ProcessorMac2.Metadata.Description, eSigIoMask.InputSigOnly); - _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, JoinMap.ProcessorNetMask1.Metadata.Description, eSigIoMask.InputSigOnly); - _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.Metadata.Description, eSigIoMask.InputSigOnly); + _ip1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp1.JoinNumber, JoinMap.ProcessorIp1.AttributeName, eSigIoMask.InputSigOnly); + _ip2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorIp2.JoinNumber, JoinMap.ProcessorIp2.AttributeName, eSigIoMask.InputSigOnly); + _gateway = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorGateway.JoinNumber, JoinMap.ProcessorGateway.AttributeName, eSigIoMask.InputSigOnly); + _hostname = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorHostname.JoinNumber, JoinMap.ProcessorHostname.AttributeName, eSigIoMask.InputSigOnly); + _domain = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDomain.JoinNumber, JoinMap.ProcessorDomain.AttributeName, eSigIoMask.InputSigOnly); + _dns1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns1.JoinNumber, JoinMap.ProcessorDns1.AttributeName, eSigIoMask.InputSigOnly); + _dns2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorDns2.JoinNumber, JoinMap.ProcessorDns2.AttributeName, eSigIoMask.InputSigOnly); + _mac1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac1.JoinNumber, JoinMap.ProcessorMac1.AttributeName, eSigIoMask.InputSigOnly); + _mac2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorMac2.JoinNumber, JoinMap.ProcessorMac2.AttributeName, eSigIoMask.InputSigOnly); + _netMask1 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask1.JoinNumber, JoinMap.ProcessorNetMask1.AttributeName, eSigIoMask.InputSigOnly); + _netMask2 = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorNetMask2.JoinNumber, JoinMap.ProcessorNetMask2.AttributeName, eSigIoMask.InputSigOnly); } protected void GetProcessorEthernetValues() @@ -459,7 +462,7 @@ namespace PepperDash.Essentials.Core.Fusion protected void GetProcessorInfo() { - _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.Metadata.Description, eSigIoMask.InputSigOnly); + _firmware = FusionRoom.CreateOffsetStringSig(JoinMap.ProcessorFirmware.JoinNumber, JoinMap.ProcessorFirmware.AttributeName, eSigIoMask.InputSigOnly); if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) { @@ -468,7 +471,7 @@ namespace PepperDash.Essentials.Core.Fusion var join = JoinMap.ProgramNameStart.JoinNumber + i; var progNum = i + 1; _program[i] = FusionRoom.CreateOffsetStringSig((uint) join, - string.Format("{0} {1}", JoinMap.ProgramNameStart.Metadata.Description, progNum), eSigIoMask.InputSigOnly); + string.Format("{0} {1}", JoinMap.ProgramNameStart.AttributeName, progNum), eSigIoMask.InputSigOnly); } } @@ -1046,7 +1049,7 @@ namespace PepperDash.Essentials.Core.Fusion uint i = 1; foreach (var kvp in setTopBoxes) { - TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.Metadata.Description + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1SetTopBoxSourceStart.AttributeName + " " + i, JoinMap.Display1SetTopBoxSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots { @@ -1058,7 +1061,7 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in discPlayers) { - TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.Metadata.Description + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1DiscPlayerSourceStart.JoinSpan) // We only have five spots { @@ -1070,7 +1073,7 @@ namespace PepperDash.Essentials.Core.Fusion i = 1; foreach (var kvp in laptops) { - TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.Metadata.Description + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); + TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice); i++; if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots??? { @@ -1199,7 +1202,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = JoinMap.XpanelOnlineStart.Metadata.Description + " " + attrNum; + attrName = JoinMap.XpanelOnlineStart.AttributeName + " " + attrNum; attrNum += JoinMap.XpanelOnlineStart.JoinNumber; touchpanelNum++; @@ -1212,7 +1215,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = JoinMap.TouchpanelOnlineStart.Metadata.Description + " " + attrNum; + attrName = JoinMap.TouchpanelOnlineStart.AttributeName + " " + attrNum; attrNum += JoinMap.TouchpanelOnlineStart.JoinNumber; xpanelNum++; @@ -1227,7 +1230,7 @@ namespace PepperDash.Essentials.Core.Fusion { continue; } - attrName = JoinMap.DisplayOnlineStart.Metadata.Description + " " + attrNum; + attrName = JoinMap.DisplayOnlineStart.AttributeName + " " + attrNum; attrNum += JoinMap.DisplayOnlineStart.JoinNumber; displayNum++; @@ -1372,7 +1375,7 @@ namespace PepperDash.Essentials.Core.Fusion return; } // Display volume - var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.Metadata.Description, + var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig); defaultDisplayVolume.OutputSig.UserObject = new Action(b => { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index 52d56dfd..b9825749 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -45,16 +45,33 @@ namespace PepperDash.Essentials.Core /// public static Dictionary TryGetJoinMapAdvancedForDevice(string joinMapKey) { - if (string.IsNullOrEmpty(joinMapKey)) + try + { + if (string.IsNullOrEmpty(joinMapKey)) + return null; + + if (!ConfigReader.ConfigObject.JoinMaps.ContainsKey(joinMapKey)) + { + Debug.Console(2, "No Join Map found in config with key: '{0}'", joinMapKey); + return null; + } + + Debug.Console(2, "Attempting to load custom join map with key: {0}", joinMapKey); + + var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; + + if (joinMapJToken == null) + return null; + + var joinMapData = joinMapJToken.ToObject>(); + + return joinMapData; + } + catch (Exception e) + { + Debug.Console(2, "Error getting join map for key: '{0}'. Error: {1}", joinMapKey, e); return null; - - var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey]; - - if (joinMapJToken == null) return null; - - var joinMapData = joinMapJToken.ToObject>(); - - return joinMapData; + } } } @@ -266,7 +283,7 @@ namespace PepperDash.Essentials.Core @"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'", join.Value.JoinNumber, join.Value.JoinSpan, - String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label : join.Value.Metadata.Description, + String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName, join.Value.Metadata.JoinType.ToString(), join.Value.Metadata.JoinCapabilities.ToString()); } diff --git a/packages.config b/packages.config index 67789ca5..c7d374b3 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 2a5810b671c7c2ce6b56d24e2717588bb84c6abe Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 21 Jan 2021 17:01:43 -0700 Subject: [PATCH 077/480] Updates PD.Core to 1.0.45 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index c7d374b3..b60e8578 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From dfc90e58dc3d91b9ea21326149818ef87d39902f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 21 Jan 2021 17:19:01 -0700 Subject: [PATCH 078/480] Adds EssentialsTechRoomFusionSystemController --- PepperDashEssentials/ControlSystem.cs | 4 +- ...ssentialsTechRoomFusionSystemController.cs | 92 +++++++++++++++++++ .../PepperDashEssentials.csproj | 1 + 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 7ffb57b5..74f3c617 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -480,7 +480,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); + DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); @@ -588,7 +588,7 @@ namespace PepperDash.Essentials return ((logoDark != null && logoDark == "system") || (logoLight != null && logoLight == "system") || (logo != null && logo == "system")); } - catch (Exception e) + catch { Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config"); return false; diff --git a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs new file mode 100644 index 00000000..a069dbd4 --- /dev/null +++ b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Fusion; + +namespace PepperDash.Essentials.Fusion +{ + public class EssentialsTechRoomFusionSystemController : EssentialsHuddleSpaceFusionSystemControllerBase + { + public EssentialsTechRoomFusionSystemController(EssentialsTechRoom room, uint ipId, string joinMapKey) + : base(room, ipId, joinMapKey) + { + + } + + protected override void SetUpDisplay() + { + try + { + var displays = (Room as EssentialsTechRoom).Displays; + + foreach (var display in displays.Cast()) + { + display.UsageTracker = new UsageTracking(display) { UsageIsTracked = true }; + display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; + + var dispPowerOnAction = new Action(b => + { + if (!b) + { + display.PowerOn(); + } + }); + var dispPowerOffAction = new Action(b => + { + if (!b) + { + display.PowerOff(); + } + }); + + var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(display.Key); + + FusionAsset tempAsset; + + if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) + { + tempAsset = FusionStaticAssets[deviceConfig.Uid]; + } + else + { + // Create a new asset + tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), + display.Name, "Display", ""); + FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); + } + + var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", + tempAsset.InstanceId); + dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; + dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; + + var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback; + if (defaultTwoWayDisplay != null) + { + defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); + if (display is IDisplayUsage) + { + (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + } + + defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); + } + + // Use extension methods + dispAsset.TrySetMakeModel(display); + dispAsset.TryLinkAssetErrorToCommunication(display); + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error setting up displays in Fusion: {0}", e); + } + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 969c1f40..b7df4b0d 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -133,6 +133,7 @@ + From c9fee785f931a090418f91b4422a1a569588d060 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 22 Jan 2021 11:08:35 -0700 Subject: [PATCH 079/480] Static Assets for displays now tested and working --- .../Fusion/EssentialsTechRoomFusionSystemController.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs index a069dbd4..7e465b4d 100644 --- a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs +++ b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs @@ -23,10 +23,15 @@ namespace PepperDash.Essentials.Fusion { try { + var displays = (Room as EssentialsTechRoom).Displays; - foreach (var display in displays.Cast()) + Debug.Console(1, this, "Setting up Static Assets for {0} Displays", displays.Count); + + foreach (var display in displays.Values.Cast()) { + Debug.Console(2, this, "Setting up Static Asset for {0}", display.Key); + display.UsageTracker = new UsageTracking(display) { UsageIsTracked = true }; display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; @@ -51,6 +56,7 @@ namespace PepperDash.Essentials.Fusion if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) { + // Used existing asset tempAsset = FusionStaticAssets[deviceConfig.Uid]; } else From 65747b6ad296b57e639b5f58d793ca931e0cb544 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 25 Jan 2021 10:55:27 -0700 Subject: [PATCH 080/480] #560 Adds constructors with priority and fixed debug statments to use error log --- .../Queues/GenericQueue.cs | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 1f27fe1e..05757213 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -15,23 +15,36 @@ namespace PepperDash_Essentials_Core.Queues protected readonly Thread _worker; protected readonly CEvent _waitHandle = new CEvent(); - private readonly bool _delayEnabled; - private readonly int _delayTime; + private bool _delayEnabled; + private int _delayTime; /// /// If the instance has been disposed. /// public bool Disposed { get; private set; } + /// + /// Constructor with no thread priority + /// + /// + public GenericQueue(string key) + : this(key, Thread.eThreadPriority.NotSet) + { + + } + /// /// Constructor for generic queue with no pacing /// /// Key - public GenericQueue(string key) + public GenericQueue(string key, Thread.eThreadPriority priority) { _key = key; _queue = new CrestronQueue(); - _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running); + _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) + { + Priority = priority + }; CrestronEnvironment.ProgramStatusEventHandler += programEvent => { @@ -49,11 +62,28 @@ namespace PepperDash_Essentials_Core.Queues /// Pacing in ms between actions public GenericQueue(string key, int pacing) : this(key) + { + SetDelayValues(pacing); + } + + /// + /// Constructor with pacing and priority + /// + /// + /// + /// + public GenericQueue(string key, int pacing, Thread.eThreadPriority priority) + : this(key, priority) + { + SetDelayValues(pacing); + } + + private void SetDelayValues(int pacing) { _delayEnabled = pacing > 0; _delayTime = pacing; } - + /// /// Thread callback /// @@ -83,7 +113,7 @@ namespace PepperDash_Essentials_Core.Queues } catch (Exception ex) { - Debug.ConsoleWithLog(0, this, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace); + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace); } } else _waitHandle.Wait(); From 42c483f581ce5d1d09102455b0022a317e98f0a9 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 25 Jan 2021 17:56:20 -0700 Subject: [PATCH 081/480] Updates to properly clear errors when there are none and set message to "Room Ok." --- .../Monitoring/StatusMonitorCollection.cs | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs index d9b5b33a..7f985fe0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/StatusMonitorCollection.cs @@ -64,30 +64,34 @@ namespace PepperDash.Essentials.Core initialStatus = MonitorStatus.InWarning; prefix = "2:"; } - else if (InWarning.Count() > 0) + else if (IsOk.Count() > 0) initialStatus = MonitorStatus.IsOk; else initialStatus = MonitorStatus.StatusUnknown; // Build the error message string - if (InError.Count() > 0 || InWarning.Count() > 0) - { - StringBuilder sb = new StringBuilder(prefix); - if (InError.Count() > 0) - { - // Do string splits and joins - sb.Append(string.Format("{0} Errors:", InError.Count())); - foreach (var mon in InError) - sb.Append(string.Format("{0}, ", mon.Parent.Key)); - } - if (InWarning.Count() > 0) - { - sb.Append(string.Format("{0} Warnings:", InWarning.Count())); - foreach (var mon in InWarning) - sb.Append(string.Format("{0}, ", mon.Parent.Key)); - } - Message = sb.ToString(); - } + if (InError.Count() > 0 || InWarning.Count() > 0) + { + StringBuilder sb = new StringBuilder(prefix); + if (InError.Count() > 0) + { + // Do string splits and joins + sb.Append(string.Format("{0} Errors:", InError.Count())); + foreach (var mon in InError) + sb.Append(string.Format("{0}, ", mon.Parent.Key)); + } + if (InWarning.Count() > 0) + { + sb.Append(string.Format("{0} Warnings:", InWarning.Count())); + foreach (var mon in InWarning) + sb.Append(string.Format("{0}, ", mon.Parent.Key)); + } + Message = sb.ToString(); + } + else + { + Message = "Room Ok."; + } // Want to fire even if status doesn't change because the message may. Status = initialStatus; From 24e59e147471db3f154499cf6578328379fd4828 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 26 Jan 2021 11:05:42 -0700 Subject: [PATCH 082/480] Update PepperDash_Essentials_Core.nuspec --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec index dff167ed..e736dcbf 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec @@ -14,7 +14,7 @@ crestron 3series 4series - + From 809639c3f90d30e90865bd4641186a83bb76018d Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Tue, 26 Jan 2021 13:17:55 -0500 Subject: [PATCH 083/480] Validate method now checks the parameter --- .../PepperDashEssentialsBase/Queues/ComsMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs index 92c97248..fce6291d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs @@ -40,7 +40,7 @@ namespace PepperDash_Essentials_Core.Queues private void Validate(IBasicCommunication coms, object message) { - if (_coms == null) + if (coms == null) throw new ArgumentNullException("coms"); if (message == null) From b7d719607169081b4762f23275e21037283e2ef3 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 26 Jan 2021 12:32:04 -0700 Subject: [PATCH 084/480] Sets the queue size to 25 --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 05757213..5ca8a793 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -40,7 +40,7 @@ namespace PepperDash_Essentials_Core.Queues public GenericQueue(string key, Thread.eThreadPriority priority) { _key = key; - _queue = new CrestronQueue(); + _queue = new CrestronQueue(25); _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) { Priority = priority From 57641493063023b9fb85a0dbd7a109824145d2c2 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 27 Jan 2021 10:48:23 -0700 Subject: [PATCH 085/480] #560 set default queue thread priority to medium --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 5ca8a793..b4c6befa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -28,7 +28,7 @@ namespace PepperDash_Essentials_Core.Queues /// /// public GenericQueue(string key) - : this(key, Thread.eThreadPriority.NotSet) + : this(key, Thread.eThreadPriority.MediumPriority) { } @@ -37,6 +37,7 @@ namespace PepperDash_Essentials_Core.Queues /// Constructor for generic queue with no pacing /// /// Key + /// public GenericQueue(string key, Thread.eThreadPriority priority) { _key = key; From 21f9795bcd3a103a97aeefed756e919089d82011 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 28 Jan 2021 14:05:59 -0700 Subject: [PATCH 086/480] Implements ITvPresetsProvider on IrSetTopBoxBase --- .../DeviceTypeInterfaces/ISetTopBoxControls.cs | 2 +- .../UI PageManagers/SetTopBoxThreePanelPageManager.cs | 4 ++-- .../UI PageManagers/SetTopBoxTwoPanelPageManager.cs | 4 ++-- .../SetTopBox/IRSetTopBoxBase.cs | 9 +++++---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ISetTopBoxControls.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ISetTopBoxControls.cs index 8b043cac..a9a92126 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ISetTopBoxControls.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ISetTopBoxControls.cs @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core /// bool HasDpad { get; } - PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; } + PepperDash.Essentials.Core.Presets.DevicePresetsModel TvPresets { get; } void LoadPresets(string filePath); void DvrList(bool pressRelease); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxThreePanelPageManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxThreePanelPageManager.cs index f8838aed..e0f44046 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxThreePanelPageManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxThreePanelPageManager.cs @@ -169,9 +169,9 @@ namespace PepperDash.Essentials.Core.PageManagers } // Build presets - if (stb.HasPresets && stb.PresetsModel != null) + if (stb.HasPresets && stb.TvPresets != null) { - PresetsView = new DevicePresetsView(trilist, stb.PresetsModel); + PresetsView = new DevicePresetsView(trilist, stb.TvPresets); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxTwoPanelPageManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxTwoPanelPageManager.cs index cb1e1840..2797695e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxTwoPanelPageManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI PageManagers/SetTopBoxTwoPanelPageManager.cs @@ -18,8 +18,8 @@ namespace PepperDash.Essentials.Core.PageManagers { SetTopBox = stb; TriList = trilist; - if(stb.PresetsModel != null) - PresetsView = new DevicePresetsView(trilist, stb.PresetsModel); + if(stb.TvPresets != null) + PresetsView = new DevicePresetsView(trilist, stb.TvPresets); } public override void Show() diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs index 2746a04a..394d7b8d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs @@ -12,11 +12,12 @@ using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Devices.Common { [Description("Wrapper class for an IR Set Top Box")] - public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl + public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl, ITvPresetsProvider { public IrOutputPortController IrPort { get; private set; } @@ -28,7 +29,7 @@ namespace PepperDash.Essentials.Devices.Common public bool HasDpad { get; set; } public bool HasNumeric { get; set; } - public DevicePresetsModel PresetsModel { get; private set; } + public DevicePresetsModel TvPresets { get; private set; } public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont, SetTopBoxPropertiesConfig props) @@ -66,8 +67,8 @@ namespace PepperDash.Essentials.Devices.Common public void LoadPresets(string filePath) { - PresetsModel = new DevicePresetsModel(Key + "-presets", this, filePath); - DeviceManager.AddDevice(PresetsModel); + TvPresets = new DevicePresetsModel(Key + "-presets", this, filePath); + DeviceManager.AddDevice(TvPresets); } From 1228431bc2bc0982301d6941920d3d991cd02ef6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 29 Jan 2021 14:18:48 -0700 Subject: [PATCH 087/480] remove unnecessary debug statements --- .../Essentials Devices Common/Display/SamsungMDCDisplay.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs index 47c08cea..65e38408 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/SamsungMDCDisplay.cs @@ -149,7 +149,7 @@ namespace PepperDash.Essentials.Devices.Displays public override bool CustomActivate() { Communication.Connect(); - CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); }; + CommunicationMonitor.StatusChange += (o, a) => Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); CommunicationMonitor.Start(); return true; } @@ -188,9 +188,6 @@ namespace PepperDash.Essentials.Devices.Displays IncomingBuffer.CopyTo(newBytes, 0); e.Bytes.CopyTo(newBytes, IncomingBuffer.Length); - if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1 - Debug.Console(2, this, "Received:{0}", ComTextHelper.GetEscapedText(newBytes)); - // Need to find AA FF and have for (int i = 0; i < newBytes.Length; i++) { @@ -364,8 +361,6 @@ namespace PepperDash.Essentials.Devices.Displays } checksum = checksum & 0x000000FF; // mask off MSBs b[b.Length - 1] = (byte)checksum; - if(Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1 - Debug.Console(2, this, "Sending:{0}", ComTextHelper.GetEscapedText(b)); if (b[1] == 0x12) LastCommandSentWasVolume = true; From c6cfecdbbbf94373f069fea9d288f7d014d8b70a Mon Sep 17 00:00:00 2001 From: jkdevito Date: Mon, 1 Feb 2021 08:24:54 -0600 Subject: [PATCH 088/480] Added console command to print occupancy sensor settings in console. --- .../CenOdtOccupancySensorBaseController.cs | 1057 +++++++++-------- .../GlsOccupancySensorBaseController.cs | 855 ++++++------- .../GlsOdtOccupancySensorController.cs | 358 +++--- 3 files changed, 1196 insertions(+), 1074 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index 603abeef..acbd6a4c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -13,561 +13,602 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { - [Description("Wrapper class for CEN-ODT-C-POE")] - public class CenOdtOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider - { - public CenOdtCPoe OccSensor { get; private set; } + [Description("Wrapper class for CEN-ODT-C-POE")] + public class CenOdtOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider + { + public CenOdtCPoe OccSensor { get; private set; } - public BoolFeedback RoomIsOccupiedFeedback { get; private set; } + public BoolFeedback RoomIsOccupiedFeedback { get; private set; } - public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; } + public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; } - public BoolFeedback RawOccupancyFeedback { get; private set; } + public BoolFeedback RawOccupancyFeedback { get; private set; } - public BoolFeedback PirSensorEnabledFeedback { get; private set; } + public BoolFeedback PirSensorEnabledFeedback { get; private set; } - public BoolFeedback LedFlashEnabledFeedback { get; private set; } + public BoolFeedback LedFlashEnabledFeedback { get; private set; } - public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; } + public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; } - public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; } + public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; } - public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; } + public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; } - public IntFeedback CurrentTimeoutFeedback { get; private set; } + public IntFeedback CurrentTimeoutFeedback { get; private set; } - public IntFeedback RemoteTimeoutFeedback { get; private set; } + public IntFeedback RemoteTimeoutFeedback { get; private set; } - public IntFeedback InternalPhotoSensorValue { get; set; } + public IntFeedback InternalPhotoSensorValue { get; set; } - public IntFeedback ExternalPhotoSensorValue { get; set; } + public IntFeedback ExternalPhotoSensorValue { get; set; } - public BoolFeedback OrWhenVacatedFeedback { get; private set; } + public BoolFeedback OrWhenVacatedFeedback { get; private set; } - public BoolFeedback AndWhenVacatedFeedback { get; private set; } + public BoolFeedback AndWhenVacatedFeedback { get; private set; } - public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } + public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } - public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } + public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } - public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } + public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } - public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; } + public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; } - public BoolFeedback RawOccupancyPirFeedback { get; private set; } + public BoolFeedback RawOccupancyPirFeedback { get; private set; } - public BoolFeedback RawOccupancyUsFeedback { get; private set; } + public BoolFeedback RawOccupancyUsFeedback { get; private set; } - // Debug properties - public bool InTestMode { get; private set; } + // Debug properties + public bool InTestMode { get; private set; } - public bool TestRoomIsOccupiedFeedback { get; private set; } + public bool TestRoomIsOccupiedFeedback { get; private set; } - public Func RoomIsOccupiedFeedbackFunc - { - get - { - return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue; - } - } + public Func RoomIsOccupiedFeedbackFunc + { + get + { + return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue; + } + } - public CenOdtOccupancySensorBaseController(string key, string name, CenOdtCPoe sensor) - : base(key, name, sensor) - { - OccSensor = sensor; + public CenOdtOccupancySensorBaseController(string key, string name, CenOdtCPoe sensor) + : base(key, name, sensor) + { + OccSensor = sensor; - RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); + RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); - PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PassiveInfraredSensorEnabledFeedback.BoolValue); + PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PassiveInfraredSensorEnabledFeedback.BoolValue); - LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue); + LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue); - ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue); + ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - PirSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback); + PirSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback); - PirSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback); + PirSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback); - CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue); + CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue); - RemoteTimeoutFeedback = new IntFeedback(() => OccSensor.RemoteTimeout.UShortValue); + RemoteTimeoutFeedback = new IntFeedback(() => OccSensor.RemoteTimeout.UShortValue); - GraceOccupancyDetectedFeedback = new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); + GraceOccupancyDetectedFeedback = new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); - RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedFeedback.BoolValue); + RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedFeedback.BoolValue); - InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue); + InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue); - //ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ex.UShortValue); + //ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ex.UShortValue); - AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); + AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); - OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); + OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); - UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideAEnabledFeedback.BoolValue); + UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideAEnabledFeedback.BoolValue); - UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideBEnabledFeedback.BoolValue); + UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UltrasonicSensorSideBEnabledFeedback.BoolValue); - RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByPassiveInfraredSensorFeedback.BoolValue); + RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByPassiveInfraredSensorFeedback.BoolValue); - RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByUltrasonicSensorFeedback.BoolValue); + RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByUltrasonicSensorFeedback.BoolValue); - UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback); + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback); - UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback); + UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback); - OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent); + OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent); - OccSensor.CenOccupancySensorChange += new GenericEventHandler(OccSensor_CenOccupancySensorChange); + OccSensor.CenOccupancySensorChange += new GenericEventHandler(OccSensor_CenOccupancySensorChange); - } + CrestronConsole.AddNewConsoleCommand(GetSettings, + "occsensorstatus", + "Reports current occupancy sensor settings. Requires a device key.", + ConsoleAccessLevelEnum.AccessOperator); + } - - - - - /// - /// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs. - /// - /// - /// - protected virtual void OccSensor_CenOccupancySensorChange(object device, GenericEventArgs args) - { - if (args.EventId == GlsOccupancySensorBase.PirEnabledFeedbackEventId) - PirSensorEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId) - LedFlashEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId) - ShortTimeoutEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId) - PirSensitivityInOccupiedStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId) - PirSensitivityInVacantStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) - RawOccupancyPirFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) - RawOccupancyUsFeedback.FireUpdate(); - } - - protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) - { - Debug.Console(2, this, "PoEOccupancySensorChange EventId: {0}", args.EventId); - - if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId - || args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId) - { - Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); - RoomIsOccupiedFeedback.FireUpdate(); - } - else if (args.EventId == GlsOccupancySensorBase.TimeoutFeedbackEventId) - CurrentTimeoutFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.TimeoutLocalFeedbackEventId) - RemoteTimeoutFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId) - GraceOccupancyDetectedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyFeedbackEventId) - RawOccupancyFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId) - InternalPhotoSensorValue.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId) - ExternalPhotoSensorValue.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) - AndWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId) - OrWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId) - UltrasonicAEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) - UltrasonicBEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) - UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) - UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); - } - - public void SetTestMode(bool mode) - { - InTestMode = mode; - - Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode); - } - - public void SetTestOccupiedState(bool state) - { - if (!InTestMode) - Debug.Console(1, "Mock mode not enabled"); - else - { - TestRoomIsOccupiedFeedback = state; - - RoomIsOccupiedFeedback.FireUpdate(); - } - } - - /// - /// Enables or disables the PIR sensor - /// - /// - public void SetPirEnable(bool state) - { - if (state) - { - OccSensor.EnablePassiveInfraredSensor(); - } - else - { - OccSensor.DisablePassiveInfraredSensor(); - } - } - - /// - /// Enables or disables the LED Flash - /// - /// - public void SetLedFlashEnable(bool state) - { - if (state) - { - OccSensor.EnableLedFlash(); - } - else - { - OccSensor.DisableLedFlash(); - } - } - - /// - /// Enables or disables short timeout based on state - /// - /// - public void SetShortTimeoutState(bool state) - { - if (state) - { - OccSensor.EnableShortTimeout(); - } - else - { - OccSensor.DisableShortTimeout(); - } - } - - public void IncrementPirSensitivityInOccupiedState(bool pressRelease) - { - if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 3) - { - OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback + 1; - } - } - - public void DecrementPirSensitivityInOccupiedState(bool pressRelease) - { - if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 0) - { - OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback - 1; - } - } - - public void IncrementPirSensitivityInVacantState(bool pressRelease) - { - if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 3) - { - OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback + 1; - } - } - - public void DecrementPirSensitivityInVacantState(bool pressRelease) - { - if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 0) - { - OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback - 1; - } - } - - public void IncrementUsSensitivityInOccupiedState(bool pressRelease) - { - if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 3) - { - OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 4) - { - OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback == 4) - { - OccSensor.UltrasonicSensorSensitivityInOccupiedState = 0; - } - } - - public void DecrementUsSensitivityInOccupiedState(bool pressRelease) - { - if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 0 - && (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 4) - { - OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 3 - && (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 7) - { - OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1; - } - } - - public void IncrementUsSensitivityInVacantState(bool pressRelease) - { - if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 3) - { - OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 4) - { - OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback == 4) - { - OccSensor.UltrasonicSensorSensitivityInVacantState = 0; - } - } - - public void DecrementUsSensitivityInVacantState(bool pressRelease) - { - if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 0 - && (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 4) - { - OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1; - } - else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 3 - && (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 7) - { - OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1; - } - } - - public void ForceOccupied() - { - OccSensor.ForceOccupied(); - } - - public void ForceVacant() - { - OccSensor.ForceVacant(); - } - - public void EnableRawStates(bool state) - { - if (state) - { - OccSensor.EnableRawStates(); - } - else - OccSensor.DisableRawStates(); - } - - public void SetRemoteTimeout(ushort time) - { - OccSensor.RemoteTimeout.UShortValue = time; - } - - public void SetInternalPhotoSensorMinChange(ushort value) - { - OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value; - } - - /// - /// Sets the OrWhenVacated state - /// - /// - public void SetOrWhenVacatedState(bool state) - { - if (state) - { - OccSensor.OrWhenVacated(); - } - } - - /// - /// Sets the AndWhenVacated state - /// - /// - public void SetAndWhenVacatedState(bool state) - { - if (state) - { - OccSensor.AndWhenVacated(); - } - } - - /// - /// Enables or disables the Ultrasonic A sensor - /// - /// - public void SetUsAEnable(bool state) - { - if (state) - { - OccSensor.EnableUltrasonicSensorSideA(); - } - else - { - OccSensor.DisableUltrasonicSensorSideA(); - } - } - - - /// - /// Enables or disables the Ultrasonic B sensor - /// - /// - public void SetUsBEnable(bool state) - { - if (state) - { - OccSensor.EnableUltrasonicSensorSideB(); - } - else - { - OccSensor.DisableUltrasonicSensorSideB(); - } - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); - } - - protected void LinkOccSensorToApi(CenOdtOccupancySensorBaseController occController, - BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - CenOdtOccupancySensorBaseJoinMap joinMap = new CenOdtOccupancySensorBaseJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.Online.JoinNumber]); - trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; - - trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => - { - if (args.DeviceOnLine) - { - trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; - } - } - ); - - // Occupied status - trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, new Action(() => occController.ForceOccupied())); - trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, new Action(() => occController.ForceVacant())); - occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); - occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); - occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); - trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, new Action((b) => occController.EnableRawStates(b))); - - // Timouts - trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, new Action((u) => occController.SetRemoteTimeout(u))); - occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); - occController.RemoteTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); - - // LED Flash - trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(true))); - trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(false))); - occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); - - // Short Timeout - trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(true))); - trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(false))); - occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); - - // PIR Sensor - trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, new Action(() => occController.SetPirEnable(true))); - trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, new Action(() => occController.SetPirEnable(false))); - occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); - - // PIR Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, new Action((b) => occController.IncrementPirSensitivityInOccupiedState(b))); - trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, new Action((b) => occController.DecrementPirSensitivityInOccupiedState(b))); - occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); - - // PIR Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, new Action((b) => occController.IncrementPirSensitivityInVacantState(b))); - trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, new Action((b) => occController.DecrementPirSensitivityInVacantState(b))); - occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); - - // OR When Vacated - trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, new Action((b) => occController.SetOrWhenVacatedState(b))); - occController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); - - // AND When Vacated - trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, new Action((b) => occController.SetAndWhenVacatedState(b))); - occController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); - - // Ultrasonic A Sensor - trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(true))); - trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(false))); - occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); - - // Ultrasonic B Sensor - trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(true))); - trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(false))); - occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); - - // US Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, new Action((b) => occController.IncrementUsSensitivityInOccupiedState(b))); - trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, new Action((b) => occController.DecrementUsSensitivityInOccupiedState(b))); - occController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); - - // US Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, new Action((b) => occController.IncrementUsSensitivityInVacantState(b))); - trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, new Action((b) => occController.DecrementUsSensitivityInVacantState(b))); - occController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); - - //Sensor Raw States - occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); - occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); - - } - - public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory - { - public CenOdtOccupancySensorBaseControllerFactory() - { - TypeNames = new List() { "cenodtcpoe", "cenodtocc" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); - - var typeName = dc.Type.ToLower(); - var key = dc.Key; - var name = dc.Name; - var comm = CommFactory.GetControlPropertiesConfig(dc); - - var occSensor = new CenOdtCPoe(comm.IpIdInt, Global.ControlSystem); - - if (occSensor == null) - { - Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); - return null; - } - - return new CenOdtOccupancySensorBaseController(key, name, occSensor); - } - } - } + /// + /// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs. + /// + /// + /// + protected virtual void OccSensor_CenOccupancySensorChange(object device, GenericEventArgs args) + { + if (args.EventId == GlsOccupancySensorBase.PirEnabledFeedbackEventId) + PirSensorEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId) + LedFlashEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId) + ShortTimeoutEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId) + PirSensitivityInOccupiedStateFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId) + PirSensitivityInVacantStateFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) + RawOccupancyPirFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) + RawOccupancyUsFeedback.FireUpdate(); + } + + protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) + { + Debug.Console(2, this, "PoEOccupancySensorChange EventId: {0}", args.EventId); + + if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId + || args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId) + { + Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); + RoomIsOccupiedFeedback.FireUpdate(); + } + else if (args.EventId == GlsOccupancySensorBase.TimeoutFeedbackEventId) + CurrentTimeoutFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.TimeoutLocalFeedbackEventId) + RemoteTimeoutFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId) + GraceOccupancyDetectedFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.RawOccupancyFeedbackEventId) + RawOccupancyFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId) + InternalPhotoSensorValue.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId) + ExternalPhotoSensorValue.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) + AndWhenVacatedFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId) + OrWhenVacatedFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId) + UltrasonicAEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) + UltrasonicBEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) + UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) + UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); + } + + public void SetTestMode(bool mode) + { + InTestMode = mode; + + Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode); + } + + public void SetTestOccupiedState(bool state) + { + if (!InTestMode) + Debug.Console(1, "Mock mode not enabled"); + else + { + TestRoomIsOccupiedFeedback = state; + + RoomIsOccupiedFeedback.FireUpdate(); + } + } + + /// + /// Enables or disables the PIR sensor + /// + /// + public void SetPirEnable(bool state) + { + if (state) + { + OccSensor.EnablePassiveInfraredSensor(); + } + else + { + OccSensor.DisablePassiveInfraredSensor(); + } + } + + /// + /// Enables or disables the LED Flash + /// + /// + public void SetLedFlashEnable(bool state) + { + if (state) + { + OccSensor.EnableLedFlash(); + } + else + { + OccSensor.DisableLedFlash(); + } + } + + /// + /// Enables or disables short timeout based on state + /// + /// + public void SetShortTimeoutState(bool state) + { + if (state) + { + OccSensor.EnableShortTimeout(); + } + else + { + OccSensor.DisableShortTimeout(); + } + } + + public void IncrementPirSensitivityInOccupiedState(bool pressRelease) + { + if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 3) + { + OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback + 1; + } + } + + public void DecrementPirSensitivityInOccupiedState(bool pressRelease) + { + if ((int)OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback != 0) + { + OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback - 1; + } + } + + public void IncrementPirSensitivityInVacantState(bool pressRelease) + { + if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 3) + { + OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback + 1; + } + } + + public void DecrementPirSensitivityInVacantState(bool pressRelease) + { + if ((int)OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback != 0) + { + OccSensor.PassiveInfraredSensorSensitivityInVacantState = OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback - 1; + } + } + + public void IncrementUsSensitivityInOccupiedState(bool pressRelease) + { + if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 3) + { + OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 4) + { + OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback == 4) + { + OccSensor.UltrasonicSensorSensitivityInOccupiedState = 0; + } + } + + public void DecrementUsSensitivityInOccupiedState(bool pressRelease) + { + if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 0 + && (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 4) + { + OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback - 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback > 3 + && (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback < 7) + { + OccSensor.UltrasonicSensorSensitivityInOccupiedState = OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback + 1; + } + } + + public void IncrementUsSensitivityInVacantState(bool pressRelease) + { + if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 3) + { + OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 4) + { + OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback == 4) + { + OccSensor.UltrasonicSensorSensitivityInVacantState = 0; + } + } + + public void DecrementUsSensitivityInVacantState(bool pressRelease) + { + if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 0 + && (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 4) + { + OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback - 1; + } + else if ((int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback > 3 + && (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback < 7) + { + OccSensor.UltrasonicSensorSensitivityInVacantState = OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback + 1; + } + } + + public void ForceOccupied() + { + OccSensor.ForceOccupied(); + } + + public void ForceVacant() + { + OccSensor.ForceVacant(); + } + + public void EnableRawStates(bool state) + { + if (state) + { + OccSensor.EnableRawStates(); + } + else + OccSensor.DisableRawStates(); + } + + public void SetRemoteTimeout(ushort time) + { + OccSensor.RemoteTimeout.UShortValue = time; + } + + public void SetInternalPhotoSensorMinChange(ushort value) + { + OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value; + } + + /// + /// Sets the OrWhenVacated state + /// + /// + public void SetOrWhenVacatedState(bool state) + { + if (state) + { + OccSensor.OrWhenVacated(); + } + } + + /// + /// Sets the AndWhenVacated state + /// + /// + public void SetAndWhenVacatedState(bool state) + { + if (state) + { + OccSensor.AndWhenVacated(); + } + } + + /// + /// Enables or disables the Ultrasonic A sensor + /// + /// + public void SetUsAEnable(bool state) + { + if (state) + { + OccSensor.EnableUltrasonicSensorSideA(); + } + else + { + OccSensor.DisableUltrasonicSensorSideA(); + } + } + + + /// + /// Enables or disables the Ultrasonic B sensor + /// + /// + public void SetUsBEnable(bool state) + { + if (state) + { + OccSensor.EnableUltrasonicSensorSideB(); + } + else + { + OccSensor.DisableUltrasonicSensorSideB(); + } + } + + private static void GetSettings(string key) + { + var dev = DeviceManager.GetDeviceForKey(key); + if (dev == null) return; + + var sensor = dev as CenOdtOccupancySensorBaseController; + if (sensor == null) return; + + if (!sensor.Hardware.IsOnline) + { + Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); + return; + } + + var dash = new string('*', 50); + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + + Debug.Console(0, sensor.Key, "Timeout Current: {0} | Remote: {1}", + sensor.CurrentTimeoutFeedback.UShortValue, + sensor.RemoteTimeoutFeedback.UShortValue); + + Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", + sensor.ShortTimeoutEnabledFeedback.BoolValue); + + Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + sensor.PirSensorEnabledFeedback.BoolValue, + sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, + sensor.PirSensitivityInVacantStateFeedback.UShortValue); + + Debug.Console(0, sensor.Key, "Ultrasonic Enabled A: {0} | B: {1}", + sensor.UltrasonicAEnabledFeedback.BoolValue, + sensor.UltrasonicBEnabledFeedback.BoolValue); + + Debug.Console(0, sensor.Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", + sensor.UltrasonicSensitivityInOccupiedStateFeedback.UShortValue, + sensor.UltrasonicSensitivityInVacantStateFeedback.UShortValue); + + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + } + + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + protected void LinkOccSensorToApi(CenOdtOccupancySensorBaseController occController, + BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + CenOdtOccupancySensorBaseJoinMap joinMap = new CenOdtOccupancySensorBaseJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.Online.JoinNumber]); + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; + + trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => + { + if (args.DeviceOnLine) + { + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; + } + } + ); + + // Occupied status + trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, new Action(() => occController.ForceOccupied())); + trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, new Action(() => occController.ForceVacant())); + occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); + occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); + occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); + trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, new Action((b) => occController.EnableRawStates(b))); + + // Timouts + trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, new Action((u) => occController.SetRemoteTimeout(u))); + occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); + occController.RemoteTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); + + // LED Flash + trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(true))); + trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, new Action(() => occController.SetLedFlashEnable(false))); + occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); + + // Short Timeout + trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(true))); + trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, new Action(() => occController.SetShortTimeoutState(false))); + occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); + + // PIR Sensor + trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, new Action(() => occController.SetPirEnable(true))); + trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, new Action(() => occController.SetPirEnable(false))); + occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); + + // PIR Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, new Action((b) => occController.IncrementPirSensitivityInOccupiedState(b))); + trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, new Action((b) => occController.DecrementPirSensitivityInOccupiedState(b))); + occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); + + // PIR Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, new Action((b) => occController.IncrementPirSensitivityInVacantState(b))); + trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, new Action((b) => occController.DecrementPirSensitivityInVacantState(b))); + occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); + + // OR When Vacated + trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, new Action((b) => occController.SetOrWhenVacatedState(b))); + occController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); + + // AND When Vacated + trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, new Action((b) => occController.SetAndWhenVacatedState(b))); + occController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); + + // Ultrasonic A Sensor + trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(true))); + trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, new Action(() => occController.SetUsAEnable(false))); + occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); + + // Ultrasonic B Sensor + trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(true))); + trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, new Action(() => occController.SetUsBEnable(false))); + occController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); + + // US Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, new Action((b) => occController.IncrementUsSensitivityInOccupiedState(b))); + trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, new Action((b) => occController.DecrementUsSensitivityInOccupiedState(b))); + occController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); + + // US Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, new Action((b) => occController.IncrementUsSensitivityInVacantState(b))); + trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, new Action((b) => occController.DecrementUsSensitivityInVacantState(b))); + occController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); + + //Sensor Raw States + occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); + occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); + + } + + public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory + { + public CenOdtOccupancySensorBaseControllerFactory() + { + TypeNames = new List() { "cenodtcpoe", "cenodtocc" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + var typeName = dc.Type.ToLower(); + var key = dc.Key; + var name = dc.Name; + var comm = CommFactory.GetControlPropertiesConfig(dc); + + var occSensor = new CenOdtCPoe(comm.IpIdInt, Global.ControlSystem); + + if (occSensor == null) + { + Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key); + return null; + } + + return new CenOdtOccupancySensorBaseController(key, name, occSensor); + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 077be4f5..4fb3510a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -13,448 +13,483 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { - [Description("Wrapper class for Single Technology GLS Occupancy Sensors")] - public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider - { - public GlsOccupancySensorBase OccSensor { get; private set; } + [Description("Wrapper class for Single Technology GLS Occupancy Sensors")] + public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider + { + public GlsOccupancySensorBase OccSensor { get; private set; } - public BoolFeedback RoomIsOccupiedFeedback { get; private set; } + public BoolFeedback RoomIsOccupiedFeedback { get; private set; } - public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; } + public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; } - public BoolFeedback RawOccupancyFeedback { get; private set; } + public BoolFeedback RawOccupancyFeedback { get; private set; } - public BoolFeedback PirSensorEnabledFeedback { get; private set; } + public BoolFeedback PirSensorEnabledFeedback { get; private set; } - public BoolFeedback LedFlashEnabledFeedback { get; private set; } + public BoolFeedback LedFlashEnabledFeedback { get; private set; } - public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; } + public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; } - public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; } + public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; } - public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; } + public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; } - public IntFeedback CurrentTimeoutFeedback { get; private set; } + public IntFeedback CurrentTimeoutFeedback { get; private set; } - public IntFeedback LocalTimoutFeedback { get; private set; } + public IntFeedback LocalTimoutFeedback { get; private set; } - public IntFeedback InternalPhotoSensorValue { get; set; } + public IntFeedback InternalPhotoSensorValue { get; set; } - public IntFeedback ExternalPhotoSensorValue { get; set; } + public IntFeedback ExternalPhotoSensorValue { get; set; } - // Debug properties - public bool InTestMode { get; private set; } + // Debug properties + public bool InTestMode { get; private set; } - public bool TestRoomIsOccupiedFeedback { get; private set; } + public bool TestRoomIsOccupiedFeedback { get; private set; } - public Func RoomIsOccupiedFeedbackFunc - { - get - { - return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue; - } - } + public Func RoomIsOccupiedFeedbackFunc + { + get + { + return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue; + } + } - public GlsOccupancySensorBaseController(string key, Func preActivationFunc, - DeviceConfig config) - : base(key, config.Name) - { + public GlsOccupancySensorBaseController(string key, Func preActivationFunc, + DeviceConfig config) + : base(key, config.Name) + { - AddPreActivationAction(() => - { - OccSensor = preActivationFunc(config); + AddPreActivationAction(() => + { + OccSensor = preActivationFunc(config); - RegisterCrestronGenericBase(OccSensor); + RegisterCrestronGenericBase(OccSensor); - RegisterGlsOdtSensorBaseController(OccSensor); + RegisterGlsOdtSensorBaseController(OccSensor); - }); - } + }); - public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {} + CrestronConsole.AddNewConsoleCommand(GetSettings, + "occsensorstatus", + "Reports current occupancy sensor settings. Requires a device key.", + ConsoleAccessLevelEnum.AccessOperator); + } - protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor) - { - OccSensor = occSensor; + public GlsOccupancySensorBaseController(string key, string name) : base(key, name) { } - RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); + protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor) + { + OccSensor = occSensor; - PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue); + RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); - LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue); + PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue); - ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue); + LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue); - PirSensitivityInVacantStateFeedback = - new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); + ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - PirSensitivityInOccupiedStateFeedback = - new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue); + PirSensitivityInVacantStateFeedback = + new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); - CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue); + PirSensitivityInOccupiedStateFeedback = + new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue); - LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue); + CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue); + + LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue); + + GraceOccupancyDetectedFeedback = + new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); + + RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue); + + InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue); + + ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue); + + OccSensor.BaseEvent += OccSensor_BaseEvent; + + OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange; + } + + + /// + /// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs. + /// + /// + /// + protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) + { + switch (args.EventId) + { + case GlsOccupancySensorBase.PirEnabledFeedbackEventId: + PirSensorEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId: + LedFlashEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId: + ShortTimeoutEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId: + PirSensitivityInOccupiedStateFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId: + PirSensitivityInVacantStateFeedback.FireUpdate(); + break; + } + } + + protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) + { + Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId); + + switch (args.EventId) + { + case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId: + case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId: + Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); + RoomIsOccupiedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.TimeoutFeedbackEventId: + CurrentTimeoutFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId: + LocalTimoutFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId: + GraceOccupancyDetectedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.RawOccupancyFeedbackEventId: + RawOccupancyFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId: + InternalPhotoSensorValue.FireUpdate(); + break; + case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId: + ExternalPhotoSensorValue.FireUpdate(); + break; + } + } + + public void SetTestMode(bool mode) + { + InTestMode = mode; + + Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode); + } + + public void SetTestOccupiedState(bool state) + { + if (!InTestMode) + Debug.Console(1, "Mock mode not enabled"); + else + { + TestRoomIsOccupiedFeedback = state; + + RoomIsOccupiedFeedback.FireUpdate(); + } + } + + /// + /// Enables or disables the PIR sensor + /// + /// + public void SetPirEnable(bool state) + { + if (state) + { + OccSensor.EnablePir.BoolValue = state; + OccSensor.DisablePir.BoolValue = !state; + } + else + { + OccSensor.EnablePir.BoolValue = state; + OccSensor.DisablePir.BoolValue = !state; + } + } + + /// + /// Enables or disables the LED Flash + /// + /// + public void SetLedFlashEnable(bool state) + { + if (state) + { + OccSensor.EnableLedFlash.BoolValue = state; + OccSensor.DisableLedFlash.BoolValue = !state; + } + else + { + OccSensor.EnableLedFlash.BoolValue = state; + OccSensor.DisableLedFlash.BoolValue = !state; + } + } + + /// + /// Enables or disables short timeout based on state + /// + /// + public void SetShortTimeoutState(bool state) + { + if (state) + { + OccSensor.EnableShortTimeout.BoolValue = state; + OccSensor.DisableShortTimeout.BoolValue = !state; + } + else + { + OccSensor.EnableShortTimeout.BoolValue = state; + OccSensor.DisableShortTimeout.BoolValue = !state; + } + } + + public void IncrementPirSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease; + } + + public void DecrementPirSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease; + } + + public void IncrementPirSensitivityInVacantState(bool pressRelease) + { + OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease; + } + + public void DecrementPirSensitivityInVacantState(bool pressRelease) + { + OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease; + } + + public void ForceOccupied() + { + OccSensor.ForceOccupied.BoolValue = true; + } + + public void ForceVacant() + { + OccSensor.ForceVacant.BoolValue = true; + } + + public void EnableRawStates(bool state) + { + OccSensor.EnableRawStates.BoolValue = state; + } + + public void SetRemoteTimeout(ushort time) + { + OccSensor.RemoteTimeout.UShortValue = time; + } + + public void SetInternalPhotoSensorMinChange(ushort value) + { + OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value; + } + + public void SetExternalPhotoSensorMinChange(ushort value) + { + OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value; + } + + private static void GetSettings(string key) + { + var dev = DeviceManager.GetDeviceForKey(key); + if (dev == null) return; + + var sensor = dev as GlsOccupancySensorBaseController; + if (sensor == null) return; + + if (!sensor.Hardware.IsOnline) + { + Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); + return; + } + + var dash = new string('*', 50); + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + + Debug.Console(0, sensor.Key, "Timeout Current: {0} | Local: {1}", + sensor.CurrentTimeoutFeedback.UShortValue, + sensor.LocalTimoutFeedback.UShortValue); + + Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", + sensor.ShortTimeoutEnabledFeedback.BoolValue); + + Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + sensor.PirSensorEnabledFeedback.BoolValue, + sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, + sensor.PirSensitivityInVacantStateFeedback.UShortValue); + + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + } + + protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist, + uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + #region Single and Dual Sensor Stuff + occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; + + trilist.OnlineStatusChange += (d, args) => + { + if (args.DeviceOnLine) + { + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; + } + }; + + // Occupied status + trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); + trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); + occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); + occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); + occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); + trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates); + + // Timouts + trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout); + occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); + occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); + + // LED Flash + trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false)); + occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); + + // Short Timeout + trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true)); + trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false)); + occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); + + // PIR Sensor + trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true)); + trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false)); + occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); + + // PIR Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState); + occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); + + // PIR Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState); + occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); + #endregion + + #region Dual Technology Sensor Stuff + var odtOccController = occController as GlsOdtOccupancySensorController; + + if (odtOccController == null) return; + // OR When Vacated + trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState); + odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); + + // AND When Vacated + trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState); + odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); + + // Ultrasonic A Sensor + trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); + + // Ultrasonic B Sensor + trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); + + // US Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState); + odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); + + // US Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState); + odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); + + //Sensor Raw States + odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); + odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); + + #endregion + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #region PreActivation + + private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory + { + public GlsOccupancySensorBaseControllerFactory() + { + TypeNames = new List() { "glsoirccn" }; + } + + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc); + } + + } + } - GraceOccupancyDetectedFeedback = - new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue); - RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue); - - InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue); - - ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue); - - OccSensor.BaseEvent += OccSensor_BaseEvent; - - OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange; - } - - - /// - /// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs. - /// - /// - /// - protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) - { - switch (args.EventId) - { - case GlsOccupancySensorBase.PirEnabledFeedbackEventId: - PirSensorEnabledFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId: - LedFlashEnabledFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId: - ShortTimeoutEnabledFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId: - PirSensitivityInOccupiedStateFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId: - PirSensitivityInVacantStateFeedback.FireUpdate(); - break; - } - } - - protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) - { - Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId); - - switch (args.EventId) - { - case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId: - case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId: - Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); - RoomIsOccupiedFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.TimeoutFeedbackEventId: - CurrentTimeoutFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId: - LocalTimoutFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId: - GraceOccupancyDetectedFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.RawOccupancyFeedbackEventId: - RawOccupancyFeedback.FireUpdate(); - break; - case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId: - InternalPhotoSensorValue.FireUpdate(); - break; - case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId: - ExternalPhotoSensorValue.FireUpdate(); - break; - } - } - - public void SetTestMode(bool mode) - { - InTestMode = mode; - - Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode); - } - - public void SetTestOccupiedState(bool state) - { - if (!InTestMode) - Debug.Console(1, "Mock mode not enabled"); - else - { - TestRoomIsOccupiedFeedback = state; - - RoomIsOccupiedFeedback.FireUpdate(); - } - } - - /// - /// Enables or disables the PIR sensor - /// - /// - public void SetPirEnable(bool state) - { - if (state) - { - OccSensor.EnablePir.BoolValue = state; - OccSensor.DisablePir.BoolValue = !state; - } - else - { - OccSensor.EnablePir.BoolValue = state; - OccSensor.DisablePir.BoolValue = !state; - } - } - - /// - /// Enables or disables the LED Flash - /// - /// - public void SetLedFlashEnable(bool state) - { - if (state) - { - OccSensor.EnableLedFlash.BoolValue = state; - OccSensor.DisableLedFlash.BoolValue = !state; - } - else - { - OccSensor.EnableLedFlash.BoolValue = state; - OccSensor.DisableLedFlash.BoolValue = !state; - } - } - - /// - /// Enables or disables short timeout based on state - /// - /// - public void SetShortTimeoutState(bool state) - { - if (state) - { - OccSensor.EnableShortTimeout.BoolValue = state; - OccSensor.DisableShortTimeout.BoolValue = !state; - } - else - { - OccSensor.EnableShortTimeout.BoolValue = state; - OccSensor.DisableShortTimeout.BoolValue = !state; - } - } - - public void IncrementPirSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease; - } - - public void DecrementPirSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease; - } - - public void IncrementPirSensitivityInVacantState(bool pressRelease) - { - OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease; - } - - public void DecrementPirSensitivityInVacantState(bool pressRelease) - { - OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease; - } - - public void ForceOccupied() - { - OccSensor.ForceOccupied.BoolValue = true; - } - - public void ForceVacant() - { - OccSensor.ForceVacant.BoolValue = true; - } - - public void EnableRawStates(bool state) - { - OccSensor.EnableRawStates.BoolValue = state; - } - - public void SetRemoteTimeout(ushort time) - { - OccSensor.RemoteTimeout.UShortValue = time; - } - - public void SetInternalPhotoSensorMinChange(ushort value) - { - OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value; - } - - public void SetExternalPhotoSensorMinChange(ushort value) - { - OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value; - } - - - - protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist, - uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - #region Single and Dual Sensor Stuff - occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; - - trilist.OnlineStatusChange += (d, args) => - { - if (args.DeviceOnLine) - { - trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; - } - }; - - // Occupied status - trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); - trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); - occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); - occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); - occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); - trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates); - - // Timouts - trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout); - occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); - occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); - - // LED Flash - trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false)); - occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); - - // Short Timeout - trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true)); - trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false)); - occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); - - // PIR Sensor - trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true)); - trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false)); - occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); - - // PIR Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState); - trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState); - occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); - - // PIR Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState); - trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState); - occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); - #endregion - - #region Dual Technology Sensor Stuff - var odtOccController = occController as GlsOdtOccupancySensorController; - - if (odtOccController == null) return; - // OR When Vacated - trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState); - odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); - - // AND When Vacated - trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState); - odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); - - // Ultrasonic A Sensor - trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false)); - odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); - - // Ultrasonic B Sensor - trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false)); - odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); - - // US Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState); - trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState); - odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); - - // US Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState); - trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState); - odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); - - //Sensor Raw States - odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); - odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); - - #endregion - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); - } - - #region PreActivation - - private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc) - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - var branchId = control.ControlPortNumber; - var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - - if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); - return new GlsOirCCn(cresnetId, Global.ControlSystem); - } - var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; - - if (cresnetBridge != null) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); - return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); - } - Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); - return null; - } - #endregion - - public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory - { - public GlsOccupancySensorBaseControllerFactory() - { - TypeNames = new List() { "glsoirccn" }; - } - - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); - - return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc); - } - - } - } - - } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 4900ca93..1d4e2781 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -13,206 +13,252 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { - [Description("Wrapper class for Dual Technology GLS Occupancy Sensors")] - public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController - { - public new GlsOdtCCn OccSensor { get; private set; } + [Description("Wrapper class for Dual Technology GLS Occupancy Sensors")] + public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController + { + public new GlsOdtCCn OccSensor { get; private set; } - public BoolFeedback OrWhenVacatedFeedback { get; private set; } + public BoolFeedback OrWhenVacatedFeedback { get; private set; } - public BoolFeedback AndWhenVacatedFeedback { get; private set; } + public BoolFeedback AndWhenVacatedFeedback { get; private set; } - public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } + public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } - public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } + public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } - public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } + public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } - public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; } + public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; } - public BoolFeedback RawOccupancyPirFeedback { get; private set; } + public BoolFeedback RawOccupancyPirFeedback { get; private set; } - public BoolFeedback RawOccupancyUsFeedback { get; private set; } + public BoolFeedback RawOccupancyUsFeedback { get; private set; } - public GlsOdtOccupancySensorController(string key, Func preActivationFunc, - DeviceConfig config) - : base(key, config.Name) - { - AddPreActivationAction(() => - { - OccSensor = preActivationFunc(config); + public GlsOdtOccupancySensorController(string key, Func preActivationFunc, + DeviceConfig config) + : base(key, config.Name) + { + AddPreActivationAction(() => + { + OccSensor = preActivationFunc(config); - RegisterCrestronGenericBase(OccSensor); + RegisterCrestronGenericBase(OccSensor); - RegisterGlsOdtSensorBaseController(OccSensor); + RegisterGlsOdtSensorBaseController(OccSensor); - AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); + AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); - OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); + OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); - UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); + UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); - UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); + UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); - RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); + RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); - RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); + RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); - UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); - UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); + UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); - }); - } + }); - /// - /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. - /// Then calls the base delegate method to ensure any common event IDs are captured. - /// - /// - /// - protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) - { - if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) - AndWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId) - OrWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId) - UltrasonicAEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) - UltrasonicBEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) - UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) - UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); + CrestronConsole.AddNewConsoleCommand(GetSettings, + "occsensorstatus", + "Reports current occupancy sensor settings. Requires a device key.", + ConsoleAccessLevelEnum.AccessOperator); + } - base.OccSensor_GlsOccupancySensorChange(device, args); - } + /// + /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. + /// Then calls the base delegate method to ensure any common event IDs are captured. + /// + /// + /// + protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) + { + if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) + AndWhenVacatedFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId) + OrWhenVacatedFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId) + UltrasonicAEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) + UltrasonicBEnabledFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) + UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) + UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); - /// - /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. - /// Then calls the base delegate method to ensure any common event IDs are captured. - /// - /// - /// - protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) - { - if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) - RawOccupancyPirFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) - RawOccupancyUsFeedback.FireUpdate(); + base.OccSensor_GlsOccupancySensorChange(device, args); + } - base.OccSensor_BaseEvent(device, args); - } + /// + /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. + /// Then calls the base delegate method to ensure any common event IDs are captured. + /// + /// + /// + protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) + { + if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) + RawOccupancyPirFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) + RawOccupancyUsFeedback.FireUpdate(); - /// - /// Sets the OrWhenVacated state - /// - /// - public void SetOrWhenVacatedState(bool state) - { - OccSensor.OrWhenVacated.BoolValue = state; - } + base.OccSensor_BaseEvent(device, args); + } - /// - /// Sets the AndWhenVacated state - /// - /// - public void SetAndWhenVacatedState(bool state) - { - OccSensor.AndWhenVacated.BoolValue = state; - } + /// + /// Sets the OrWhenVacated state + /// + /// + public void SetOrWhenVacatedState(bool state) + { + OccSensor.OrWhenVacated.BoolValue = state; + } - /// - /// Enables or disables the Ultrasonic A sensor - /// - /// - public void SetUsAEnable(bool state) - { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; - } + /// + /// Sets the AndWhenVacated state + /// + /// + public void SetAndWhenVacatedState(bool state) + { + OccSensor.AndWhenVacated.BoolValue = state; + } + + /// + /// Enables or disables the Ultrasonic A sensor + /// + /// + public void SetUsAEnable(bool state) + { + OccSensor.EnableUsA.BoolValue = state; + OccSensor.DisableUsA.BoolValue = !state; + } - /// - /// Enables or disables the Ultrasonic B sensor - /// - /// - public void SetUsBEnable(bool state) - { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; - } + /// + /// Enables or disables the Ultrasonic B sensor + /// + /// + public void SetUsBEnable(bool state) + { + OccSensor.EnableUsB.BoolValue = state; + OccSensor.DisableUsB.BoolValue = !state; + } - public void IncrementUsSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; - } + public void IncrementUsSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + } - public void DecrementUsSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; - } + public void DecrementUsSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + } - public void IncrementUsSensitivityInVacantState(bool pressRelease) - { - OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; - } + public void IncrementUsSensitivityInVacantState(bool pressRelease) + { + OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; + } - public void DecrementUsSensitivityInVacantState(bool pressRelease) - { - OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; - } + public void DecrementUsSensitivityInVacantState(bool pressRelease) + { + OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; + } - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); - } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } - #region PreActivation + private static void GetSettings(string key) + { + var dev = DeviceManager.GetDeviceForKey(key); + if (dev == null) return; - private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc) - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - var branchId = control.ControlPortNumber; - var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + var sensor = dev as GlsOdtOccupancySensorController; + if (sensor == null) return; - if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); - return new GlsOdtCCn(cresnetId, Global.ControlSystem); - } - var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + if (!sensor.Hardware.IsOnline) + { + Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); + return; + } - if (cresnetBridge != null) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); - return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); - } - Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); - return null; - } - #endregion + var dash = new string('*', 50); + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); - public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory - { - public GlsOdtOccupancySensorControllerFactory() - { - TypeNames = new List() { "glsodtccn" }; - } + Debug.Console(0, sensor.Key, "Timeout Current: {0} | Local: {1}", + sensor.CurrentTimeoutFeedback.UShortValue, + sensor.LocalTimoutFeedback.UShortValue); + + Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", + sensor.ShortTimeoutEnabledFeedback.BoolValue); + + Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + sensor.PirSensorEnabledFeedback.BoolValue, + sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, + sensor.PirSensitivityInVacantStateFeedback.UShortValue); + + Debug.Console(0, sensor.Key, "Ultrasonic Enabled A: {0} | B: {1}", + sensor.UltrasonicAEnabledFeedback.BoolValue, + sensor.UltrasonicBEnabledFeedback.BoolValue); + + Debug.Console(0, sensor.Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", + sensor.UltrasonicSensitivityInOccupiedStateFeedback.UShortValue, + sensor.UltrasonicSensitivityInVacantStateFeedback.UShortValue); + + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + } - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + #region PreActivation - return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc); - } + private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - } - } + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + #endregion + + public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory + { + public GlsOdtOccupancySensorControllerFactory() + { + TypeNames = new List() { "glsodtccn" }; + } + + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc); + } + + } + } From e0dcde5c3581d2ca46abaeff0b3390246f6bd4e3 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Mon, 1 Feb 2021 11:10:33 -0600 Subject: [PATCH 089/480] Reviewed with AW, decided best to remove console commands and create a public method that can be called using DEVJSON to print current settiings. --- .../CenOdtOccupancySensorBaseController.cs | 53 +++++++----------- .../GlsOccupancySensorBaseController.cs | 41 +++++--------- .../GlsOdtOccupancySensorController.cs | 54 +++++++------------ 3 files changed, 53 insertions(+), 95 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index acbd6a4c..6606c1e6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -119,12 +119,6 @@ namespace PepperDash.Essentials.Core OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent); OccSensor.CenOccupancySensorChange += new GenericEventHandler(OccSensor_CenOccupancySensorChange); - - CrestronConsole.AddNewConsoleCommand(GetSettings, - "occsensorstatus", - "Reports current occupancy sensor settings. Requires a device key.", - ConsoleAccessLevelEnum.AccessOperator); - } /// @@ -432,42 +426,33 @@ namespace PepperDash.Essentials.Core } } - private static void GetSettings(string key) + /// + /// Method to print current settings to console + /// + public void GetSettings() { - var dev = DeviceManager.GetDeviceForKey(key); - if (dev == null) return; - - var sensor = dev as CenOdtOccupancySensorBaseController; - if (sensor == null) return; - - if (!sensor.Hardware.IsOnline) - { - Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); - return; - } - var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); - Debug.Console(0, sensor.Key, "Timeout Current: {0} | Remote: {1}", - sensor.CurrentTimeoutFeedback.UShortValue, - sensor.RemoteTimeoutFeedback.UShortValue); + Debug.Console(0, Key, "Timeout Current: {0} | Remote: {1}", + OccSensor.CurrentTimeoutFeedback.UShortValue, + OccSensor.RemoteTimeout.UShortValue); - Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", - sensor.ShortTimeoutEnabledFeedback.BoolValue); + Debug.Console(0, Key, "Short Timeout Enabled: {0}", + OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", - sensor.PirSensorEnabledFeedback.BoolValue, - sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, - sensor.PirSensitivityInVacantStateFeedback.UShortValue); + Debug.Console(0, Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + OccSensor.PassiveInfraredSensorEnabledFeedback.BoolValue, + OccSensor.PassiveInfraredSensorSensitivityInOccupiedStateFeedback, + OccSensor.PassiveInfraredSensorSensitivityInVacantStateFeedback); - Debug.Console(0, sensor.Key, "Ultrasonic Enabled A: {0} | B: {1}", - sensor.UltrasonicAEnabledFeedback.BoolValue, - sensor.UltrasonicBEnabledFeedback.BoolValue); + Debug.Console(0, Key, "Ultrasonic Enabled A: {0} | B: {1}", + OccSensor.UltrasonicSensorSideAEnabledFeedback.BoolValue, + OccSensor.UltrasonicSensorSideBEnabledFeedback.BoolValue); - Debug.Console(0, sensor.Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", - sensor.UltrasonicSensitivityInOccupiedStateFeedback.UShortValue, - sensor.UltrasonicSensitivityInVacantStateFeedback.UShortValue); + Debug.Console(0, Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", + OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback, + OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 4fb3510a..de51527c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -70,11 +70,6 @@ namespace PepperDash.Essentials.Core RegisterGlsOdtSensorBaseController(OccSensor); }); - - CrestronConsole.AddNewConsoleCommand(GetSettings, - "occsensorstatus", - "Reports current occupancy sensor settings. Requires a device key.", - ConsoleAccessLevelEnum.AccessOperator); } public GlsOccupancySensorBaseController(string key, string name) : base(key, name) { } @@ -298,34 +293,26 @@ namespace PepperDash.Essentials.Core OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value; } - private static void GetSettings(string key) + /// + /// Method to print current occ settings to console. + /// + /// + public void GetSettings() { - var dev = DeviceManager.GetDeviceForKey(key); - if (dev == null) return; - - var sensor = dev as GlsOccupancySensorBaseController; - if (sensor == null) return; - - if (!sensor.Hardware.IsOnline) - { - Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); - return; - } - var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); - Debug.Console(0, sensor.Key, "Timeout Current: {0} | Local: {1}", - sensor.CurrentTimeoutFeedback.UShortValue, - sensor.LocalTimoutFeedback.UShortValue); + Debug.Console(0, Key, "Timeout Current: {0} | Local: {1}", + OccSensor.CurrentTimeoutFeedback.UShortValue, + OccSensor.LocalTimeoutFeedback.UShortValue); - Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", - sensor.ShortTimeoutEnabledFeedback.BoolValue); + Debug.Console(0, Key, "Short Timeout Enabled: {0}", + OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", - sensor.PirSensorEnabledFeedback.BoolValue, - sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, - sensor.PirSensitivityInVacantStateFeedback.UShortValue); + Debug.Console(0, Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + OccSensor.PirEnabledFeedback.BoolValue, + OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue, + OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 1d4e2781..68d4dcb0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -63,12 +63,7 @@ namespace PepperDash.Essentials.Core UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); - }); - - CrestronConsole.AddNewConsoleCommand(GetSettings, - "occsensorstatus", - "Reports current occupancy sensor settings. Requires a device key.", - ConsoleAccessLevelEnum.AccessOperator); + }); } /// @@ -175,42 +170,33 @@ namespace PepperDash.Essentials.Core LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); } - private static void GetSettings(string key) + /// + /// Method to print occ sensor settings to console. + /// + public void GetSettings() { - var dev = DeviceManager.GetDeviceForKey(key); - if (dev == null) return; - - var sensor = dev as GlsOdtOccupancySensorController; - if (sensor == null) return; - - if (!sensor.Hardware.IsOnline) - { - Debug.Console(0, sensor.Key, "Sensor IsOnline: {0}", sensor.Hardware.IsOnline); - return; - } - var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); - Debug.Console(0, sensor.Key, "Timeout Current: {0} | Local: {1}", - sensor.CurrentTimeoutFeedback.UShortValue, - sensor.LocalTimoutFeedback.UShortValue); + Debug.Console(0, Key, "Timeout Current: {0} | Local: {1}", + OccSensor.CurrentTimeoutFeedback.UShortValue, + OccSensor.LocalTimeoutFeedback.UShortValue); - Debug.Console(0, sensor.Key, "Short Timeout Enabled: {0}", - sensor.ShortTimeoutEnabledFeedback.BoolValue); + Debug.Console(0, Key, "Short Timeout Enabled: {0}", + OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - Debug.Console(0, sensor.Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", - sensor.PirSensorEnabledFeedback.BoolValue, - sensor.PirSensitivityInOccupiedStateFeedback.UShortValue, - sensor.PirSensitivityInVacantStateFeedback.UShortValue); + Debug.Console(0, Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + OccSensor.PirEnabledFeedback.BoolValue, + OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue, + OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); - Debug.Console(0, sensor.Key, "Ultrasonic Enabled A: {0} | B: {1}", - sensor.UltrasonicAEnabledFeedback.BoolValue, - sensor.UltrasonicBEnabledFeedback.BoolValue); + Debug.Console(0, Key, "Ultrasonic Enabled A: {0} | B: {1}", + OccSensor.UsAEnabledFeedback.BoolValue, + OccSensor.UsBEnabledFeedback.BoolValue); - Debug.Console(0, sensor.Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", - sensor.UltrasonicSensitivityInOccupiedStateFeedback.UShortValue, - sensor.UltrasonicSensitivityInVacantStateFeedback.UShortValue); + Debug.Console(0, Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", + OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue, + OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); } From 5eb65fd72396eee4adb7a511ba9eb07694c8dff3 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 2 Feb 2021 15:30:43 -0700 Subject: [PATCH 090/480] Update RoutingInterfaces.cs --- .../Routing/RoutingInterfaces.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs index c7f2e533..467bf045 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs @@ -92,6 +92,16 @@ namespace PepperDash.Essentials.Core void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType); } + public interface IRoutingWithClear : IRouting + { + /// + /// Clears a route to an output, however a device needs to do that + /// + /// Output to clear + /// signal type to clear + void ClearRoute(object outputSelector, eRoutingSignalType signalType); + } + public interface IRoutingNumeric : IRouting { void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type); From 355df1341e3d4d0f8bb3158a210293ae5aea1d1c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 3 Feb 2021 16:01:24 -0700 Subject: [PATCH 091/480] #592 Adds properties config class for occ sensors --- .../CenOdtOccupancySensorBaseController.cs | 66 ++++++++++++++++++- .../GlsOccupancySensorBaseController.cs | 46 +++++++++++++ .../GlsOccupancySensorPropertiesConfig.cs | 51 ++++++++++++++ .../GlsOdtOccupancySensorController.cs | 25 +++++++ .../PepperDash_Essentials_Core.csproj | 1 + 5 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index 6606c1e6..1944d880 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -18,6 +18,8 @@ namespace PepperDash.Essentials.Core { public CenOdtCPoe OccSensor { get; private set; } + public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; } + public BoolFeedback RoomIsOccupiedFeedback { get; private set; } public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; } @@ -71,9 +73,11 @@ namespace PepperDash.Essentials.Core } } - public CenOdtOccupancySensorBaseController(string key, string name, CenOdtCPoe sensor) + public CenOdtOccupancySensorBaseController(string key, string name, CenOdtCPoe sensor, GlsOccupancySensorPropertiesConfig config) : base(key, name, sensor) { + PropertiesConfig = config; + OccSensor = sensor; RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); @@ -119,8 +123,64 @@ namespace PepperDash.Essentials.Core OccSensor.BaseEvent += new Crestron.SimplSharpPro.BaseEventHandler(OccSensor_BaseEvent); OccSensor.CenOccupancySensorChange += new GenericEventHandler(OccSensor_CenOccupancySensorChange); + + AddPostActivationAction(() => + { + ApplySettingsToSensorFromConfig(); + }); } + /// + /// Applies any sensor settings defined in config + /// + protected virtual void ApplySettingsToSensorFromConfig() + { + if (PropertiesConfig.EnablePir != null) + { + SetPirEnable((bool)PropertiesConfig.EnablePir); + } + + if (PropertiesConfig.EnableLedFlash != null) + { + SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash); + } + + if (PropertiesConfig.ShortTimeoutState != null) + { + SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState); + } + + if (PropertiesConfig.EnableRawStates != null) + { + EnableRawStates((bool)PropertiesConfig.EnableRawStates); + } + + if (PropertiesConfig.InternalPhotoSensorMinChange != null) + { + SetInternalPhotoSensorMinChange((ushort)PropertiesConfig.InternalPhotoSensorMinChange); + } + + if (PropertiesConfig.EnableUsA != null) + { + SetUsAEnable((bool)PropertiesConfig.EnableUsA); + } + + if (PropertiesConfig.EnableUsB != null) + { + SetUsBEnable((bool)PropertiesConfig.EnableUsB); + } + + if (PropertiesConfig.OrWhenVacatedState != null) + { + SetOrWhenVacatedState((bool)PropertiesConfig.OrWhenVacatedState); + } + + if (PropertiesConfig.AndWhenVacatedState != null) + { + SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState); + } + } + /// /// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs. /// @@ -584,6 +644,8 @@ namespace PepperDash.Essentials.Core var name = dc.Name; var comm = CommFactory.GetControlPropertiesConfig(dc); + var props = dc.Properties.ToObject(); + var occSensor = new CenOdtCPoe(comm.IpIdInt, Global.ControlSystem); if (occSensor == null) @@ -592,7 +654,7 @@ namespace PepperDash.Essentials.Core return null; } - return new CenOdtOccupancySensorBaseController(key, name, occSensor); + return new CenOdtOccupancySensorBaseController(key, name, occSensor, props); } } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index de51527c..92223249 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -16,6 +16,8 @@ namespace PepperDash.Essentials.Core [Description("Wrapper class for Single Technology GLS Occupancy Sensors")] public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider { + public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; } + public GlsOccupancySensorBase OccSensor { get; private set; } public BoolFeedback RoomIsOccupiedFeedback { get; private set; } @@ -60,6 +62,7 @@ namespace PepperDash.Essentials.Core : base(key, config.Name) { + PropertiesConfig = config.Properties.ToObject(); AddPreActivationAction(() => { @@ -70,10 +73,53 @@ namespace PepperDash.Essentials.Core RegisterGlsOdtSensorBaseController(OccSensor); }); + + AddPostActivationAction(() => + { + ApplySettingsToSensorFromConfig(); + }); + } public GlsOccupancySensorBaseController(string key, string name) : base(key, name) { } + + /// + /// Applies any sensor settings defined in config + /// + protected virtual void ApplySettingsToSensorFromConfig() + { + if (PropertiesConfig.EnablePir != null) + { + SetPirEnable((bool)PropertiesConfig.EnablePir); + } + + if (PropertiesConfig.EnableLedFlash != null) + { + SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash); + } + + if (PropertiesConfig.ShortTimeoutState != null) + { + SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState); + } + + if (PropertiesConfig.EnableRawStates != null) + { + EnableRawStates((bool)PropertiesConfig.EnableRawStates); + } + + if (PropertiesConfig.InternalPhotoSensorMinChange != null) + { + SetInternalPhotoSensorMinChange((ushort)PropertiesConfig.InternalPhotoSensorMinChange); + } + + if (PropertiesConfig.ExternalPhotoSensorMinChange != null) + { + SetExternalPhotoSensorMinChange((ushort)PropertiesConfig.ExternalPhotoSensorMinChange); + } + } + protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor) { OccSensor = occSensor; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs new file mode 100644 index 00000000..1f21b2a8 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core +{ + /// + /// Defines configuration properties for Crestron GLS series occupancy sensors + /// + public class GlsOccupancySensorPropertiesConfig + { + // Single Technology Sensors (PIR): GlsOccupancySensorBase + [JsonProperty("enablePir")] + public bool? EnablePir { get; set; } + + [JsonProperty("enableLedFlash")] + public bool? EnableLedFlash { get; set; } + + [JsonProperty("shortTimeoutState")] + public bool? ShortTimeoutState { get; set; } + + [JsonProperty("enableRawStates")] + public bool? EnableRawStates { get; set; } + + [JsonProperty("remoteTimeout")] + public ushort? RemoteTimeout { get; set; } + + [JsonProperty("internalPhotoSensorMinChange")] + public ushort? InternalPhotoSensorMinChange { get; set; } + + [JsonProperty("externalPhotoSensorMinChange")] + public ushort? ExternalPhotoSensorMinChange { get; set; } + + // Dual Technology Sensors: GlsOdtCCn + [JsonProperty("enableUsA")] + public bool? EnableUsA { get; set; } + + [JsonProperty("enableUsB")] + public bool? EnableUsB { get; set; } + + [JsonProperty("orWhenVacatedState")] + public bool? OrWhenVacatedState { get; set; } + + [JsonProperty("andWhenVacatedState")] + public bool? AndWhenVacatedState { get; set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 68d4dcb0..03ddb1db 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -66,6 +66,31 @@ namespace PepperDash.Essentials.Core }); } + protected override void ApplySettingsToSensorFromConfig() + { + base.ApplySettingsToSensorFromConfig(); + + if (PropertiesConfig.EnableUsA != null) + { + SetUsAEnable((bool)PropertiesConfig.EnableUsA); + } + + if (PropertiesConfig.EnableUsB != null) + { + SetUsBEnable((bool)PropertiesConfig.EnableUsB); + } + + if (PropertiesConfig.OrWhenVacatedState != null) + { + SetOrWhenVacatedState((bool)PropertiesConfig.OrWhenVacatedState); + } + + if (PropertiesConfig.AndWhenVacatedState != null) + { + SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState); + } + } + /// /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. /// Then calls the base delegate method to ensure any common event IDs are captured. diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 6a15ce84..8e688858 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -227,6 +227,7 @@ + From 89ca614d3d92a4f85a08b260b620a4831423bc4e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 3 Feb 2021 21:17:27 -0700 Subject: [PATCH 092/480] Minor updates after testing at runtime. --- .../CenOdtOccupancySensorBaseController.cs | 6 +++++ .../GlsOccupancySensorBaseController.cs | 12 ++++++--- .../GlsOdtOccupancySensorController.cs | 25 ++++++------------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index 1944d880..cd4c2c8f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -14,6 +14,7 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { [Description("Wrapper class for CEN-ODT-C-POE")] + [ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0,\"enableUsA\": true,\"enableUsB\": true,\"orWhenVacatedState\": true}")] public class CenOdtOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider { public CenOdtCPoe OccSensor { get; private set; } @@ -135,6 +136,8 @@ namespace PepperDash.Essentials.Core /// protected virtual void ApplySettingsToSensorFromConfig() { + Debug.Console(1, this, "Checking config for settings to apply"); + if (PropertiesConfig.EnablePir != null) { SetPirEnable((bool)PropertiesConfig.EnablePir); @@ -494,6 +497,9 @@ namespace PepperDash.Essentials.Core var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + Debug.Console(0, this, "Vacancy Detected: {0}", + OccSensor.VacancyDetectedFeedback.BoolValue); + Debug.Console(0, Key, "Timeout Current: {0} | Remote: {1}", OccSensor.CurrentTimeoutFeedback.UShortValue, OccSensor.RemoteTimeout.UShortValue); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 92223249..b409eddc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -14,6 +14,7 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { [Description("Wrapper class for Single Technology GLS Occupancy Sensors")] + [ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0}")] public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider { public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; } @@ -343,19 +344,22 @@ namespace PepperDash.Essentials.Core /// Method to print current occ settings to console. /// /// - public void GetSettings() + public virtual void GetSettings() { var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); - Debug.Console(0, Key, "Timeout Current: {0} | Local: {1}", + Debug.Console(0, this, "Vacancy Detected: {0}", + OccSensor.VacancyDetectedFeedback.BoolValue); + + Debug.Console(0, this, "Timeout Current: {0} | Local: {1}", OccSensor.CurrentTimeoutFeedback.UShortValue, OccSensor.LocalTimeoutFeedback.UShortValue); - Debug.Console(0, Key, "Short Timeout Enabled: {0}", + Debug.Console(0, this, "Short Timeout Enabled: {0}", OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - Debug.Console(0, Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", + Debug.Console(0, this, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", OccSensor.PirEnabledFeedback.BoolValue, OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue, OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 03ddb1db..649923f9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -14,7 +14,8 @@ using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Core { [Description("Wrapper class for Dual Technology GLS Occupancy Sensors")] - public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController + [ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0,\"enableUsA\": true,\"enableUsB\": true,\"orWhenVacatedState\": true}")] + public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController { public new GlsOdtCCn OccSensor { get; private set; } @@ -198,31 +199,19 @@ namespace PepperDash.Essentials.Core /// /// Method to print occ sensor settings to console. /// - public void GetSettings() + public override void GetSettings() { - var dash = new string('*', 50); - CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + base.GetSettings(); - Debug.Console(0, Key, "Timeout Current: {0} | Local: {1}", - OccSensor.CurrentTimeoutFeedback.UShortValue, - OccSensor.LocalTimeoutFeedback.UShortValue); - - Debug.Console(0, Key, "Short Timeout Enabled: {0}", - OccSensor.ShortTimeoutEnabledFeedback.BoolValue); - - Debug.Console(0, Key, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}", - OccSensor.PirEnabledFeedback.BoolValue, - OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue, - OccSensor.PirSensitivityInVacantStateFeedback.UShortValue); - - Debug.Console(0, Key, "Ultrasonic Enabled A: {0} | B: {1}", + Debug.Console(0, this, "Ultrasonic Enabled A: {0} | B: {1}", OccSensor.UsAEnabledFeedback.BoolValue, OccSensor.UsBEnabledFeedback.BoolValue); - Debug.Console(0, Key, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", + Debug.Console(0, this, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue, OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); } From 2967a0f968aa49e5f29da9da2ff3d1478ca0e1c0 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 4 Feb 2021 08:50:50 -0700 Subject: [PATCH 093/480] turn on dev info and stream debugging for temp client --- .../Essentials_DM/Endpoints/DGEs/Dge100Controller.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs index 39e549cc..db7fa159 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs @@ -44,7 +44,7 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs DeviceInfo = new DeviceInfo(); - //_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; + _dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; _dc = dc; @@ -109,6 +109,8 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs var tcpClient = new GenericTcpIpClient("", _dgeEthernetInfo.IpAddressFeedback.StringValue, CtpPort, 1024){AutoReconnect = false}; + tcpClient.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Rx); + var gather = new CommunicationGather(tcpClient, "\r\n\r\n"); tcpClient.ConnectionChange += (sender, args) => From eb90fb343dbe2780863a30c6387bb52d663da342 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Feb 2021 09:30:45 -0700 Subject: [PATCH 094/480] adds missing condition to set remoteTimeout from config value --- .../Occupancy/CenOdtOccupancySensorBaseController.cs | 5 +++++ .../Occupancy/GlsOccupancySensorBaseController.cs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index cd4c2c8f..68f3f0e9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -148,6 +148,11 @@ namespace PepperDash.Essentials.Core SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash); } + if (PropertiesConfig.RemoteTimeout != null) + { + SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout); + } + if (PropertiesConfig.ShortTimeoutState != null) { SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index b409eddc..9a9585b6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -100,6 +100,11 @@ namespace PepperDash.Essentials.Core SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash); } + if (PropertiesConfig.RemoteTimeout != null) + { + SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout); + } + if (PropertiesConfig.ShortTimeoutState != null) { SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState); From 4c16dd07b52186097c57f592f5ef181ea14fd33c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Feb 2021 10:39:29 -0700 Subject: [PATCH 095/480] fixes #594 with standby state in CiscoSparkCodec --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 9 +++++++++ .../VideoCodec/CiscoCodec/xStatus.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index efb0ad7b..06079082 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -597,12 +597,21 @@ namespace PepperDash.Essentials if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue) { Debug.Console(1, this, "Video Codec in use, deactivating standby on codec"); + VideoCodec.StandbyDeactivate(); } if (VideoCodec.StandbyIsOnFeedback.BoolValue) { VideoCodec.StandbyDeactivate(); } + else + { + Debug.Console(1, this, "Video codec not in standby. No need to wake."); + } + } + else + { + Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue); } // report back when done diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 9ec4fa44..e3fd4dcb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -1369,7 +1369,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco set { // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false - BoolValue = value == "On"; + BoolValue = value == "On" || value == "Standby"; OnValueChanged(); } } From 2e4202ccce1f232e96638aede3c855dcd71a43cc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Feb 2021 10:52:02 -0700 Subject: [PATCH 096/480] adjustments made based on testing with hardware --- .../CenOdtOccupancySensorBaseController.cs | 16 ++++- .../GlsOccupancySensorBaseController.cs | 59 +++++++++++++++++-- .../GlsOdtOccupancySensorController.cs | 14 +++++ 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index 68f3f0e9..dcf0b193 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -127,8 +127,20 @@ namespace PepperDash.Essentials.Core AddPostActivationAction(() => { - ApplySettingsToSensorFromConfig(); - }); + OccSensor.OnlineStatusChange += (o, a) => + { + if (a.DeviceOnLine) + { + ApplySettingsToSensorFromConfig(); + } + }; + + if (OccSensor.IsOnline) + { + ApplySettingsToSensorFromConfig(); + + } + }); } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 9a9585b6..711197a5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -62,8 +62,16 @@ namespace PepperDash.Essentials.Core DeviceConfig config) : base(key, config.Name) { + var props = config.Properties.ToObject(); - PropertiesConfig = config.Properties.ToObject(); + if (props != null) + { + PropertiesConfig = props; + } + else + { + Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig"); + } AddPreActivationAction(() => { @@ -77,12 +85,36 @@ namespace PepperDash.Essentials.Core AddPostActivationAction(() => { - ApplySettingsToSensorFromConfig(); - }); - + OccSensor.OnlineStatusChange += (o, a) => + { + if (a.DeviceOnLine) + { + ApplySettingsToSensorFromConfig(); + } + }; + }); } - public GlsOccupancySensorBaseController(string key, string name) : base(key, name) { } + public GlsOccupancySensorBaseController(string key, string name) + : base(key, name) + { + AddPostActivationAction(() => + { + OccSensor.OnlineStatusChange += (o, a) => + { + if (a.DeviceOnLine) + { + ApplySettingsToSensorFromConfig(); + } + }; + + if (OccSensor.IsOnline) + { + ApplySettingsToSensorFromConfig(); + + } + }); + } /// @@ -90,20 +122,33 @@ namespace PepperDash.Essentials.Core /// protected virtual void ApplySettingsToSensorFromConfig() { + Debug.Console(1, this, "Attempting to apply settings to sensor from config"); + if (PropertiesConfig.EnablePir != null) { + Debug.Console(1, this, "EnablePir found, attempting to set value from config"); SetPirEnable((bool)PropertiesConfig.EnablePir); } + else + { + Debug.Console(1, this, "EnablePir null, no value specified in config"); + } if (PropertiesConfig.EnableLedFlash != null) { + Debug.Console(1, this, "EnableLedFlash found, attempting to set value from config"); SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash); } if (PropertiesConfig.RemoteTimeout != null) { + Debug.Console(1, this, "RemoteTimeout found, attempting to set value from config"); SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout); } + else + { + Debug.Console(1, this, "RemoteTimeout null, no value specified in config"); + } if (PropertiesConfig.ShortTimeoutState != null) { @@ -247,6 +292,8 @@ namespace PepperDash.Essentials.Core /// public void SetPirEnable(bool state) { + Debug.Console(1, this, "Setting EnablePir to: {0}", state); + if (state) { OccSensor.EnablePir.BoolValue = state; @@ -332,6 +379,8 @@ namespace PepperDash.Essentials.Core public void SetRemoteTimeout(ushort time) { + Debug.Console(1, this, "Setting RemoteTimout to: {0}", time); + OccSensor.RemoteTimeout.UShortValue = time; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 649923f9..e1b82bac 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -65,6 +65,8 @@ namespace PepperDash.Essentials.Core UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); }); + + } protected override void ApplySettingsToSensorFromConfig() @@ -73,13 +75,25 @@ namespace PepperDash.Essentials.Core if (PropertiesConfig.EnableUsA != null) { + Debug.Console(1, this, "EnableUsA found, attempting to set value from config"); SetUsAEnable((bool)PropertiesConfig.EnableUsA); } + else + { + Debug.Console(1, this, "EnableUsA null, no value specified in config"); + } + if (PropertiesConfig.EnableUsB != null) { + Debug.Console(1, this, "EnableUsB found, attempting to set value from config"); SetUsBEnable((bool)PropertiesConfig.EnableUsB); } + else + { + Debug.Console(1, this, "EnablePir null, no value specified in config"); + } + if (PropertiesConfig.OrWhenVacatedState != null) { From ec43749ba42574ec9baa995f8b53eab254cf898c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Feb 2021 11:01:21 -0700 Subject: [PATCH 097/480] Tested working with GLS-ODT-C-CN hardware --- .../Occupancy/GlsOccupancySensorBaseController.cs | 14 +++++++++++++- .../Occupancy/GlsOdtOccupancySensorController.cs | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 711197a5..c788f293 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -95,9 +95,21 @@ namespace PepperDash.Essentials.Core }); } - public GlsOccupancySensorBaseController(string key, string name) + public GlsOccupancySensorBaseController(string key, string name, DeviceConfig config) : base(key, name) { + + var props = config.Properties.ToObject(); + + if (props != null) + { + PropertiesConfig = props; + } + else + { + Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig"); + } + AddPostActivationAction(() => { OccSensor.OnlineStatusChange += (o, a) => diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index e1b82bac..e19c9ba7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core public GlsOdtOccupancySensorController(string key, Func preActivationFunc, DeviceConfig config) - : base(key, config.Name) + : base(key, config.Name, config) { AddPreActivationAction(() => { From 4dfab9a287973e6b4ef9983684dea5a7955363d9 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 4 Feb 2021 11:17:49 -0700 Subject: [PATCH 098/480] got DeviceInfo Parsing working correctly --- .../Endpoints/DGEs/Dge100Controller.cs | 65 +++++++++++++------ 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs index db7fa159..ea220a13 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs @@ -109,8 +109,6 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs var tcpClient = new GenericTcpIpClient("", _dgeEthernetInfo.IpAddressFeedback.StringValue, CtpPort, 1024){AutoReconnect = false}; - tcpClient.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Rx); - var gather = new CommunicationGather(tcpClient, "\r\n\r\n"); tcpClient.ConnectionChange += (sender, args) => @@ -125,29 +123,56 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs gather.LineReceived += (sender, args) => { - if (args.Text.ToLower().Contains("host")) + try { - DeviceInfo.HostName = args.Text.Split(';')[1].Trim(); + Debug.Console(1, this, "{0}", args.Text); - tcpClient.Disconnect(); - return; + if (args.Text.ToLower().Contains("host")) + { + DeviceInfo.HostName = args.Text.Split(':')[1].Trim(); + + Debug.Console(1, this, "hostname: {0}", DeviceInfo.HostName); + tcpClient.Disconnect(); + return; + } + + //ignore console prompt + /*if (args.Text.ToLower().Contains(">")) + { + Debug.Console(1, this, "Ignoring console"); + return; + } + + if (args.Text.ToLower().Contains("dge")) + { + Debug.Console(1, this, "Ignoring DGE"); + return; + }*/ + + if (!args.Text.Contains('[')) + { + return; + } + var splitResponse = args.Text.Split('['); + + foreach (string t in splitResponse) + { + Debug.Console(1, this, "{0}", t); + } + + DeviceInfo.SerialNumber = splitResponse[1].Split(' ')[4].Replace("#", ""); + DeviceInfo.FirmwareVersion = splitResponse[1].Split(' ')[0]; + + Debug.Console(1, this, "Firmware: {0} SerialNumber: {1}", DeviceInfo.FirmwareVersion, + DeviceInfo.SerialNumber); + + tcpClient.SendText("host\r\n"); } - - //ignore console prompt - if (args.Text.ToLower().Contains(">")) + catch (Exception ex) { - return; + Debug.Console(0, this, "Exception getting data: {0}", ex.Message); + Debug.Console(0, this, "response: {0}", args.Text); } - - if (!args.Text.ToLower().Contains("dge")) - { - return; - } - - DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", ""); - DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1]; - - tcpClient.SendText("host\r\n"); }; tcpClient.Connect(); From e03b0dc1bb6076c5f3a8ff61cda3739a79186495 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 15:06:05 -0700 Subject: [PATCH 099/480] #600 Adds additional properties and constructors to GenericQueue --- .../Queues/GenericQueue.cs | 111 ++++++++++++++---- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index b4c6befa..46deddf7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -18,42 +18,52 @@ namespace PepperDash_Essentials_Core.Queues private bool _delayEnabled; private int _delayTime; + private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority; + /// /// If the instance has been disposed. /// public bool Disposed { get; private set; } + /// + /// Returns the capacity of the CrestronQueue (fixed Size property) + /// + public int QueueCapacity + { + get + { + return _queue.Size; + } + } + + /// + /// Returns the number of elements currently in the CrestronQueue + /// + public int QueueCount + { + get + { + return _queue.Count; + } + } + /// /// Constructor with no thread priority /// /// public GenericQueue(string key) - : this(key, Thread.eThreadPriority.MediumPriority) + : this(key, _defaultPriority, 0, 0) { - } /// - /// Constructor for generic queue with no pacing + /// Constructor with queue size /// - /// Key - /// - public GenericQueue(string key, Thread.eThreadPriority priority) + /// + /// Fixed size for the queue to hold + public GenericQueue(string key, int capacity) + : this(key, _defaultPriority, capacity, 0) { - _key = key; - _queue = new CrestronQueue(25); - _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) - { - Priority = priority - }; - - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; - - Dispose(); - }; } /// @@ -61,12 +71,13 @@ namespace PepperDash_Essentials_Core.Queues /// /// Key /// Pacing in ms between actions - public GenericQueue(string key, int pacing) - : this(key) + public GenericQueue(int pacing, string key) + : this(key, _defaultPriority, 0, pacing) { - SetDelayValues(pacing); } + + /// /// Constructor with pacing and priority /// @@ -74,8 +85,52 @@ namespace PepperDash_Essentials_Core.Queues /// /// public GenericQueue(string key, int pacing, Thread.eThreadPriority priority) - : this(key, priority) + : this(key, priority, 0, pacing) { + } + + /// + /// Constructor with pacing, priority and capacity + /// + /// + /// + /// + public GenericQueue(string key, Thread.eThreadPriority priority, int capacity) + : this(key, priority, capacity, 0) + { + } + + /// + /// Constructor with pacing, priority and capacity + /// + /// + /// + /// + /// + public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity) + : this(key, priority, capacity, pacing) + { + } + + /// + /// Constructor for generic queue with no pacing + /// + /// Key + /// + private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) + { + _key = key; + int cap = 25; // sets default + if (capacity > 0) + { + cap = capacity; // overrides default + } + _queue = new CrestronQueue(cap); + _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) + { + Priority = priority + }; + SetDelayValues(pacing); } @@ -83,6 +138,14 @@ namespace PepperDash_Essentials_Core.Queues { _delayEnabled = pacing > 0; _delayTime = pacing; + + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; + + Dispose(); + }; } /// From 4f7ad4ccb9eacae75d692d26329ba54129a943ef Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 15:43:04 -0700 Subject: [PATCH 100/480] fixes #599 by checking for registration status before updating feedbacks --- .../Crestron/CrestronGenericBaseDevice.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs index 56b36791..df2c3c56 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs @@ -130,6 +130,12 @@ namespace PepperDash.Essentials.Core void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) { Debug.Console(2, this, "OnlineStatusChange Event. Online = {0}", args.DeviceOnLine); + + if (!Hardware.Registered) + { + return; // protects in cases where device has been unregistered and feedbacks would attempt to access null sigs. + } + foreach (var feedback in Feedbacks) { if (feedback != null) From 6ef8ba36395402bb4d41f29345277460aa5bab05 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:09:50 -0700 Subject: [PATCH 101/480] Removes redundant .FireUpdate() calls in Tx_OnlineStatusChange --- .../Transmitters/DmTx401CController.cs | 651 +++++++++--------- 1 file changed, 327 insertions(+), 324 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs index f40da022..1289d1a7 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs @@ -1,46 +1,46 @@ -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.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.DM.Config; - -namespace PepperDash.Essentials.DM -{ +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.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.DM.Config; + +namespace PepperDash.Essentials.DM +{ using eVst = DmTx401C.eSourceSelection; [Description("Wrapper class for DM-TX-401-C")] - public class DmTx401CController : DmTxControllerBase, ITxRoutingWithFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls - { - public DmTx401C Tx { get; private set; } - - public RoutingInputPortWithVideoStatuses HdmiIn { get; private set; } - public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } - public RoutingInputPortWithVideoStatuses VgaIn { get; private set; } - public RoutingInputPortWithVideoStatuses CompositeIn { get; private set; } - public RoutingOutputPort DmOut { get; private set; } - - public override StringFeedback ActiveVideoInputFeedback { get; protected set; } - public IntFeedback VideoSourceNumericFeedback { get; protected set; } - public IntFeedback AudioSourceNumericFeedback { get; protected set; } - public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; } - public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } - public BoolFeedback HdmiVideoSyncFeedback { get; protected set; } - public BoolFeedback VgaVideoSyncFeedback { get; protected set; } - - public BoolFeedback FreeRunEnabledFeedback { get; protected set; } - - public IntFeedback VgaBrightnessFeedback { get; protected set; } + public class DmTx401CController : DmTxControllerBase, ITxRoutingWithFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls + { + public DmTx401C Tx { get; private set; } + + public RoutingInputPortWithVideoStatuses HdmiIn { get; private set; } + public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } + public RoutingInputPortWithVideoStatuses VgaIn { get; private set; } + public RoutingInputPortWithVideoStatuses CompositeIn { get; private set; } + public RoutingOutputPort DmOut { get; private set; } + + public override StringFeedback ActiveVideoInputFeedback { get; protected set; } + public IntFeedback VideoSourceNumericFeedback { get; protected set; } + public IntFeedback AudioSourceNumericFeedback { get; protected set; } + public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; } + public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } + public BoolFeedback HdmiVideoSyncFeedback { get; protected set; } + public BoolFeedback VgaVideoSyncFeedback { get; protected set; } + + public BoolFeedback FreeRunEnabledFeedback { get; protected set; } + + public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; } //IroutingNumericEvent @@ -54,88 +54,88 @@ namespace PepperDash.Essentials.DM { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } - - - /// - /// Helps get the "real" inputs, including when in Auto - /// - public BaseDmTx401.eSourceSelection ActualVideoInput - { - get - { - if (Tx.VideoSourceFeedback != BaseDmTx401.eSourceSelection.Auto) - return Tx.VideoSourceFeedback; - else // auto - { - if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue) - return BaseDmTx401.eSourceSelection.HDMI; - else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue) - return BaseDmTx401.eSourceSelection.VGA; - else if (Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) - return BaseDmTx401.eSourceSelection.DisplayPort; - else if (Tx.CvbsInput.SyncDetectedFeedback.BoolValue) - return BaseDmTx401.eSourceSelection.Composite; - else - return BaseDmTx401.eSourceSelection.Disabled; - } - } - } - - public RoutingPortCollection InputPorts - { - get - { - return new RoutingPortCollection - { - HdmiIn, - DisplayPortIn, - VgaIn, - CompositeIn, - AnyVideoInput - }; - } - } - - public RoutingPortCollection OutputPorts - { - get - { - return new RoutingPortCollection { DmOut }; - } - } - - /// - /// - /// - /// - /// - /// - public DmTx401CController(string key, string name, DmTx401C tx) - : base(key, name, tx) - { - Tx = tx; - - HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this, + } + + + /// + /// Helps get the "real" inputs, including when in Auto + /// + public BaseDmTx401.eSourceSelection ActualVideoInput + { + get + { + if (Tx.VideoSourceFeedback != BaseDmTx401.eSourceSelection.Auto) + return Tx.VideoSourceFeedback; + else // auto + { + if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue) + return BaseDmTx401.eSourceSelection.HDMI; + else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue) + return BaseDmTx401.eSourceSelection.VGA; + else if (Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) + return BaseDmTx401.eSourceSelection.DisplayPort; + else if (Tx.CvbsInput.SyncDetectedFeedback.BoolValue) + return BaseDmTx401.eSourceSelection.Composite; + else + return BaseDmTx401.eSourceSelection.Disabled; + } + } + } + + public RoutingPortCollection InputPorts + { + get + { + return new RoutingPortCollection + { + HdmiIn, + DisplayPortIn, + VgaIn, + CompositeIn, + AnyVideoInput + }; + } + } + + public RoutingPortCollection OutputPorts + { + get + { + return new RoutingPortCollection { DmOut }; + } + } + + /// + /// + /// + /// + /// + /// + public DmTx401CController(string key, string name, DmTx401C tx) + : base(key, name, tx) + { + Tx = tx; + + HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput)) { FeedbackMatchObject = eVst.HDMI - }; - DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this, + }; + DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this, VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput)) { FeedbackMatchObject = eVst.DisplayPort - }; - VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, - eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this, + }; + VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, + eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this, VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)) { FeedbackMatchObject = eVst.VGA - }; - CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn, - eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this, + }; + CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn, + eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this, VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)) { FeedbackMatchObject = eVst.Composite @@ -146,185 +146,188 @@ namespace PepperDash.Essentials.DM Tx.BaseEvent += Tx_BaseEvent; Tx.OnlineStatusChange += Tx_OnlineStatusChange; Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange; - tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange; - - - ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", + tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange; + + + ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", () => ActualVideoInput.ToString()); - VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - + VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback); HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () => tx.HdmiInput.HdcpSupportOnFeedback.BoolValue ? 1 : 0); - HdcpStateFeedback = HdmiInHdcpCapabilityFeedback; - + HdcpStateFeedback = HdmiInHdcpCapabilityFeedback; + HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport; DisplayPortVideoSyncFeedback = new BoolFeedback("DisplayPortVideoSync", () => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue); HdmiVideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInput.SyncDetectedFeedback.BoolValue); - VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue); - - FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled); - - VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue); - - VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue); - - - var combinedFuncs = new VideoStatusFuncsWrapper - { - HdcpActiveFeedbackFunc = () => - (ActualVideoInput == eVst.HDMI - && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue) - || (ActualVideoInput == eVst.DisplayPort - && tx.DisplayPortInput.VideoAttributes.HdcpActiveFeedback.BoolValue), - - HdcpStateFeedbackFunc = () => - { - if (ActualVideoInput == eVst.HDMI) - return tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString(); - if (ActualVideoInput == eVst.DisplayPort) - return tx.DisplayPortInput.VideoAttributes.HdcpStateFeedback.ToString(); - return ""; - }, - - VideoResolutionFeedbackFunc = () => - { - if (ActualVideoInput == eVst.HDMI) - return tx.HdmiInput.VideoAttributes.GetVideoResolutionString(); - if (ActualVideoInput == eVst.DisplayPort) - return tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString(); - if (ActualVideoInput == eVst.VGA) - return tx.VgaInput.VideoAttributes.GetVideoResolutionString(); - if (ActualVideoInput == eVst.Composite) - return tx.CvbsInput.VideoAttributes.GetVideoResolutionString(); - return ""; - }, - VideoSyncFeedbackFunc = () => - (ActualVideoInput == eVst.HDMI - && tx.HdmiInput.SyncDetectedFeedback.BoolValue) - || (ActualVideoInput == eVst.DisplayPort - && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) - || (ActualVideoInput == eVst.VGA - && tx.VgaInput.SyncDetectedFeedback.BoolValue) - || (ActualVideoInput == eVst.Composite - && tx.CvbsInput.SyncDetectedFeedback.BoolValue) - }; - - AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); - - DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, null, this); - - AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, - AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, - AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, - AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, DisplayPortVideoSyncFeedback, - HdmiVideoSyncFeedback, VgaVideoSyncFeedback); - - // Set Ports for CEC - DisplayPortIn.Port = Tx.DisplayPortInput; - HdmiIn.Port = Tx.HdmiInput; - DmOut.Port = Tx.DmOutput; - } - - public override bool CustomActivate() - { - // Link up all of these damned events to the various RoutingPorts via a helper handler - Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn, a.EventId); - Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn, a.EventId); - - Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); - Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); - - Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId); - Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId); - - // Base does register and sets up comm monitoring. - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); - - if (HdmiVideoSyncFeedback != null) - { - HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); - } - if (VgaVideoSyncFeedback != null) + VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue); + + FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled); + + VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue); + + VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue); + + + var combinedFuncs = new VideoStatusFuncsWrapper + { + HdcpActiveFeedbackFunc = () => + (ActualVideoInput == eVst.HDMI + && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue) + || (ActualVideoInput == eVst.DisplayPort + && tx.DisplayPortInput.VideoAttributes.HdcpActiveFeedback.BoolValue), + + HdcpStateFeedbackFunc = () => + { + if (ActualVideoInput == eVst.HDMI) + return tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString(); + if (ActualVideoInput == eVst.DisplayPort) + return tx.DisplayPortInput.VideoAttributes.HdcpStateFeedback.ToString(); + return ""; + }, + + VideoResolutionFeedbackFunc = () => + { + if (ActualVideoInput == eVst.HDMI) + return tx.HdmiInput.VideoAttributes.GetVideoResolutionString(); + if (ActualVideoInput == eVst.DisplayPort) + return tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString(); + if (ActualVideoInput == eVst.VGA) + return tx.VgaInput.VideoAttributes.GetVideoResolutionString(); + if (ActualVideoInput == eVst.Composite) + return tx.CvbsInput.VideoAttributes.GetVideoResolutionString(); + return ""; + }, + VideoSyncFeedbackFunc = () => + (ActualVideoInput == eVst.HDMI + && tx.HdmiInput.SyncDetectedFeedback.BoolValue) + || (ActualVideoInput == eVst.DisplayPort + && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) + || (ActualVideoInput == eVst.VGA + && tx.VgaInput.SyncDetectedFeedback.BoolValue) + || (ActualVideoInput == eVst.Composite + && tx.CvbsInput.SyncDetectedFeedback.BoolValue) + }; + + AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); + + DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, null, this); + + AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, + AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, + AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, + AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, DisplayPortVideoSyncFeedback, + HdmiVideoSyncFeedback, VgaVideoSyncFeedback); + + // Set Ports for CEC + DisplayPortIn.Port = Tx.DisplayPortInput; + HdmiIn.Port = Tx.HdmiInput; + DmOut.Port = Tx.DmOutput; + } + + public override bool CustomActivate() + { + // Link up all of these damned events to the various RoutingPorts via a helper handler + Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn, a.EventId); + Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn, a.EventId); + + Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); + Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); + + Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId); + Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId); + + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); + + if (HdmiVideoSyncFeedback != null) { - VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); - } - - LinkDmTxToApi(this, trilist, joinMap, bridge); - } - - public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) - { - Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); - - switch (input) - { - case 0: - { - ExecuteSwitch(eVst.Auto, null, type); - break; - } - case 1: - { - ExecuteSwitch(DisplayPortIn.Selector, null, type); - break; - } - case 2: - { - ExecuteSwitch(HdmiIn.Selector, null, type); - break; - } - case 3: - { - ExecuteSwitch(VgaIn.Selector, null, type); - break; - } - case 4: - { - ExecuteSwitch(CompositeIn.Selector, null, type); - break; - } - case 5: - { - ExecuteSwitch(eVst.Disabled, null, type); - break; - } - } - - } - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) - Tx.VideoSource = (eVst)inputSelector; - if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - Tx.AudioSource = (eVst)inputSelector; + HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); + } + if (VgaVideoSyncFeedback != null) + { + VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); + } + + LinkDmTxToApi(this, trilist, joinMap, bridge); + } + + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) + { + Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); + + switch (input) + { + case 0: + { + ExecuteSwitch(eVst.Auto, null, type); + break; + } + case 1: + { + ExecuteSwitch(DisplayPortIn.Selector, null, type); + break; + } + case 2: + { + ExecuteSwitch(HdmiIn.Selector, null, type); + break; + } + case 3: + { + ExecuteSwitch(VgaIn.Selector, null, type); + break; + } + case 4: + { + ExecuteSwitch(CompositeIn.Selector, null, type); + break; + } + case 5: + { + ExecuteSwitch(eVst.Disabled, null, type); + break; + } + } + + } + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) + Tx.VideoSource = (eVst)inputSelector; + if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + Tx.AudioSource = (eVst)inputSelector; } void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) { - var localVideoInputPort = - InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); - var localAudioInputPort = - InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback); + if (args.DeviceOnLine) + { + var localVideoInputPort = + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); + var localAudioInputPort = + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback); - ActiveVideoInputFeedback.FireUpdate(); - VideoSourceNumericFeedback.FireUpdate(); - AudioSourceNumericFeedback.FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); - OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio)); + ActiveVideoInputFeedback.FireUpdate(); + VideoSourceNumericFeedback.FireUpdate(); + AudioSourceNumericFeedback.FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); + OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio)); + } } void Tx_BaseEvent(GenericBase device, BaseEventArgs args) @@ -348,7 +351,7 @@ namespace PepperDash.Essentials.DM OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio)); break; } - } + } void VideoControls_ControlChange(object sender, GenericEventArgs args) { @@ -364,7 +367,7 @@ namespace PepperDash.Essentials.DM VgaContrastFeedback.FireUpdate(); break; } - } + } /// /// Enables or disables free run @@ -391,10 +394,10 @@ namespace PepperDash.Essentials.DM public void SetVgaContrast(ushort level) { Tx.VgaInput.VideoControls.Contrast.UShortValue = level; - } - - /// - /// Relays the input stream change to the appropriate RoutingInputPort. + } + + /// + /// Relays the input stream change to the appropriate RoutingInputPort. /// void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) { @@ -404,36 +407,36 @@ namespace PepperDash.Essentials.DM } inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); - } - - /// - /// Relays the VideoAttributes change to a RoutingInputPort - /// - void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds - //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", - // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); - switch (eventId) - { - case VideoAttributeEventIds.HdcpActiveFeedbackEventId: - inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HdcpStateFeedbackEventId: - inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: - case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - } + } + + /// + /// Relays the VideoAttributes change to a RoutingInputPort + /// + void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds + //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", + // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); + switch (eventId) + { + case VideoAttributeEventIds.HdcpActiveFeedbackEventId: + inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HdcpStateFeedbackEventId: + inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: + case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + } } void HdmiInputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) @@ -477,18 +480,18 @@ namespace PepperDash.Essentials.DM VgaVideoSyncFeedback.FireUpdate(); break; } - } - - - - #region IIROutputPorts Members - public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } - public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } - #endregion - - #region IComPorts Members - public CrestronCollection ComPorts { get { return Tx.ComPorts; } } - public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } - #endregion - } + } + + + + #region IIROutputPorts Members + public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } + public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } + #endregion + + #region IComPorts Members + public CrestronCollection ComPorts { get { return Tx.ComPorts; } } + public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } + #endregion + } } \ No newline at end of file From 5c23aeca48062e071a4907b33b59d13d34a20f3b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:10:08 -0700 Subject: [PATCH 102/480] Adds missing constructor to take both pacing and capacity arguments --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 46deddf7..e1b175a6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -76,7 +76,16 @@ namespace PepperDash_Essentials_Core.Queues { } - + /// + /// Constructor with pacing and capacity + /// + /// + /// + /// + public GenericQueue(string key, int pacing, int capacity) + : this(key, _defaultPriority, capacity, pacing) + { + } /// /// Constructor with pacing and priority From 2987f600bb8e6eebd56bb5d6063a1e1b65700234 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:10:39 -0700 Subject: [PATCH 103/480] #588 Update to how SourceListKey gets set in EssentialsRoomBase --- .../Room/EssentialsRoomBase.cs | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 0043e3b4..cae027f5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -53,18 +53,22 @@ namespace PepperDash.Essentials.Core /// /// protected string _SourceListKey; - public virtual string SourceListKey { + public string SourceListKey { get { return _SourceListKey; } - set + private set { - _SourceListKey = value; - + if (value != _SourceListKey) + { + _SourceListKey = value; + } } } + protected const string _defaultSourceListKey = "default"; + /// /// Timer used for informing the UIs of a shutdown /// @@ -160,6 +164,22 @@ namespace PepperDash.Essentials.Core return base.CustomActivate(); } + /// + /// Sets the SourceListKey property to the passed in value or the default if no value passed in + /// + /// + protected void SetSourceListKey(string sourceListKey) + { + if (!string.IsNullOrEmpty(sourceListKey)) + { + SourceListKey = sourceListKey; + } + else + { + sourceListKey = _defaultSourceListKey; + } + } + /// /// If mobile control is enabled, sets the appropriate properties /// From 29d5ecb13fb96e37938ad7e4b084aacb73eac16a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:11:04 -0700 Subject: [PATCH 104/480] #588 Updates how EssentialsHuddleVtc1Room sets SourceListKey --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 06079082..50c8a475 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -51,20 +51,6 @@ namespace PepperDash.Essentials //************************ - public override string SourceListKey - { - get - { - return _SourceListKey; - } - set - { - _SourceListKey = value; - SetCodecExternalSources(); - - } - } - protected override Func OnFeedbackFunc { get @@ -338,7 +324,8 @@ namespace PepperDash.Essentials CallTypeFeedback = new IntFeedback(() => 0); - SourceListKey = "default"; + SetSourceListKey(); + EnablePowerOnToLastSource = true; } catch (Exception e) @@ -347,6 +334,21 @@ namespace PepperDash.Essentials } } + + private void SetSourceListKey() + { + if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) + { + SetSourceListKey(PropertiesConfig.SourceListKey); + } + else + { + SetSourceListKey(Key); + } + + SetCodecExternalSources(); + } + protected override void CustomSetConfig(DeviceConfig config) { var newPropertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString()); @@ -377,6 +379,8 @@ namespace PepperDash.Essentials return base.CustomActivate(); } + + /// /// /// From cd0e3f7001626cbe0af86f1bedbf2db8531ddd2d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:11:49 -0700 Subject: [PATCH 105/480] #599 Updates how feedbacks are fired in Tx_OnlineStatusChange --- .../Transmitters/DmTx401CController.cs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs index 1289d1a7..1407b70e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx401CController.cs @@ -315,19 +315,15 @@ namespace PepperDash.Essentials.DM void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) { - if (args.DeviceOnLine) - { - var localVideoInputPort = - InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); - var localAudioInputPort = - InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback); - ActiveVideoInputFeedback.FireUpdate(); - VideoSourceNumericFeedback.FireUpdate(); - AudioSourceNumericFeedback.FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); - OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio)); - } + var localVideoInputPort = + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); + var localAudioInputPort = + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback); + + OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); + OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio)); + } void Tx_BaseEvent(GenericBase device, BaseEventArgs args) From 766ed3ab517bf939ef70f41d716e988046260270 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 8 Feb 2021 16:15:17 -0700 Subject: [PATCH 106/480] #588 Updates all room classes to properly set SourceListKey based on precedence --- .../Room/Types/EssentialsDualDisplayRoom.cs | 16 ++++++++++++++-- .../Room/Types/EssentialsHuddleSpaceRoom.cs | 17 +++++++++++++++-- .../Room/Types/EssentialsHuddleVtc1Room.cs | 1 - 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index 2cfb33f7..ccce0af5 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -274,10 +274,23 @@ namespace PepperDash.Essentials CallTypeFeedback = new IntFeedback(() => 0); - SourceListKey = "default"; + SetSourceListKey(); EnablePowerOnToLastSource = true; } + private void SetSourceListKey() + { + if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) + { + SetSourceListKey(PropertiesConfig.SourceListKey); + } + else + { + SetSourceListKey(Key); + } + + } + void InitializeDisplay(DisplayBase disp) { if (disp != null) @@ -333,7 +346,6 @@ namespace PepperDash.Essentials this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); - this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 4af7697a..9f388252 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -201,11 +201,25 @@ namespace PepperDash.Essentials IsCoolingDownFeedback.FireUpdate(); }; } + + SetSourceListKey(); - SourceListKey = "default"; EnablePowerOnToLastSource = true; } + private void SetSourceListKey() + { + if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) + { + SetSourceListKey(PropertiesConfig.SourceListKey); + } + else + { + SetSourceListKey(Key); + } + + } + protected override void CustomSetConfig(DeviceConfig config) { var newPropertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString()); @@ -256,7 +270,6 @@ namespace PepperDash.Essentials this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); - this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 50c8a475..48ee7285 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -372,7 +372,6 @@ namespace PepperDash.Essentials this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); - this.SourceListKey = PropertiesConfig.SourceListKey; this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); From 7f8215199d8a100565e58c5cf1c82f1d25e9c694 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 8 Feb 2021 17:29:35 -0700 Subject: [PATCH 107/480] update processor type comparisons --- PepperDashEssentials/ControlSystem.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 74f3c617..8435209b 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -323,7 +323,12 @@ namespace PepperDash.Essentials // Skip this to prevent unnecessary warnings if (devConf.Key == "processor") { - if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower()) + var prompt = Global.ControlSystem.ControllerPrompt; + + var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) && + String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase); + + if (!typeMatch) Debug.Console(0, "WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available", devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper()); From b19b4ae26ebf02838af3e384d82fc75c325c206b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 9 Feb 2021 15:27:32 -0700 Subject: [PATCH 108/480] Updated to latest DBs to expose new eCrestronSeries property and adds new property to Global to reflect. Updates startup message to print series --- PepperDashEssentials/ControlSystem.cs | 2 +- .../Essentials Core/PepperDashEssentialsBase/Global/Global.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 8435209b..3e3798a4 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -130,7 +130,7 @@ namespace PepperDash.Essentials if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString()); // Check if User/ProgramX exists if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 4a846df7..aa71c1f7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -26,6 +26,8 @@ namespace PepperDash.Essentials.Core public static LicenseManager LicenseManager { get; set; } + public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } } + /// /// The file path prefix to the folder containing configuration files /// From f1fa3c07fdcf9b4b8a3c4e39aefdcc55064755b4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 10 Feb 2021 14:15:00 -0700 Subject: [PATCH 109/480] #605 Adds try/catch and more meaningful messages when adding static assets fails --- ...ssentialsTechRoomFusionSystemController.cs | 26 ++++++------ ...lsHuddleSpaceFusionSystemControllerBase.cs | 40 +++++++++++++++---- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs index 7e465b4d..b4cfbf3e 100644 --- a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs +++ b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs @@ -30,27 +30,29 @@ namespace PepperDash.Essentials.Fusion foreach (var display in displays.Values.Cast()) { - Debug.Console(2, this, "Setting up Static Asset for {0}", display.Key); + var disp = display; // Local scope variable - display.UsageTracker = new UsageTracking(display) { UsageIsTracked = true }; - display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; + Debug.Console(2, this, "Setting up Static Asset for {0}", disp.Key); + + disp.UsageTracker = new UsageTracking(disp) { UsageIsTracked = true }; + disp.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; var dispPowerOnAction = new Action(b => { if (!b) { - display.PowerOn(); + disp.PowerOn(); } }); var dispPowerOffAction = new Action(b => { if (!b) { - display.PowerOff(); + disp.PowerOff(); } }); - var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(display.Key); + var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(disp.Key); FusionAsset tempAsset; @@ -63,7 +65,7 @@ namespace PepperDash.Essentials.Fusion { // Create a new asset tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), - display.Name, "Display", ""); + disp.Name, "Display", ""); FusionStaticAssets.Add(deviceConfig.Uid, tempAsset); } @@ -72,21 +74,21 @@ namespace PepperDash.Essentials.Fusion dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; - var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback; + var defaultTwoWayDisplay = disp as IHasPowerControlWithFeedback; if (defaultTwoWayDisplay != null) { defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); - if (display is IDisplayUsage) + if (disp is IDisplayUsage) { - (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + (disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); } defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); } // Use extension methods - dispAsset.TrySetMakeModel(display); - dispAsset.TryLinkAssetErrorToCommunication(display); + dispAsset.TrySetMakeModel(disp); + dispAsset.TryLinkAssetErrorToCommunication(disp); } } catch (Exception e) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 9574743e..ff0c53ed 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -1676,20 +1676,46 @@ namespace PepperDash.Essentials.Core.Fusion public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) { - Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId); + try + { + Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId); - fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); - return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; + fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId); + return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset; + } + catch (InvalidOperationException ex) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. Error: {1}", name, ex); + return null; + } + catch (Exception e) + { + Debug.Console(2, "Error creating Static Asset: {0}", e); + return null; + } } public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name, string type, string instanceId) { - Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number, - instanceId); + try + { + Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number, + instanceId); - fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId); - return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor; + fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId); + return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor; + } + catch (InvalidOperationException ex) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. Error: {1}", name, ex); + return null; + } + catch (Exception e) + { + Debug.Console(2, "Error creating Static Asset: {0}", e); + return null; + } } } From 08491bdf2a0ff76ecc41e1d1c8363f65f818839e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 10 Feb 2021 15:01:40 -0700 Subject: [PATCH 110/480] Adds null checks if asset creation fails and returns null --- ...EssentialsTechRoomFusionSystemController.cs | 18 ++++++++++++------ ...alsHuddleSpaceFusionSystemControllerBase.cs | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs index b4cfbf3e..0630c53a 100644 --- a/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs +++ b/PepperDashEssentials/Fusion/EssentialsTechRoomFusionSystemController.cs @@ -71,8 +71,16 @@ namespace PepperDash.Essentials.Fusion var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); - dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; - dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; + + if (dispAsset != null) + { + dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; + dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; + + // Use extension methods + dispAsset.TrySetMakeModel(disp); + dispAsset.TryLinkAssetErrorToCommunication(disp); + } var defaultTwoWayDisplay = disp as IHasPowerControlWithFeedback; if (defaultTwoWayDisplay != null) @@ -83,12 +91,10 @@ namespace PepperDash.Essentials.Fusion (disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); } - defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); + if(dispAsset != null) + defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig); } - // Use extension methods - dispAsset.TrySetMakeModel(disp); - dispAsset.TryLinkAssetErrorToCommunication(disp); } } catch (Exception e) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index ff0c53ed..784392b1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -1685,7 +1685,7 @@ namespace PepperDash.Essentials.Core.Fusion } catch (InvalidOperationException ex) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. Error: {1}", name, ex); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. /r/nError: {1}", name, ex); return null; } catch (Exception e) From e7b322c3035b58f207b95514b4296ae8e87ce1ce Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 10 Feb 2021 15:39:37 -0700 Subject: [PATCH 111/480] add error log for some exceptions --- .../Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 784392b1..b26b1980 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -1690,7 +1690,7 @@ namespace PepperDash.Essentials.Core.Fusion } catch (Exception e) { - Debug.Console(2, "Error creating Static Asset: {0}", e); + Debug.Console(2, Debug.ErrorLogLevel.Error, "Error creating Static Asset: {0}", e); return null; } } @@ -1713,7 +1713,7 @@ namespace PepperDash.Essentials.Core.Fusion } catch (Exception e) { - Debug.Console(2, "Error creating Static Asset: {0}", e); + Debug.Console(2, Debug.ErrorLogLevel.Error, "Error creating Static Asset: {0}", e); return null; } } From ef7eae50e4931f77444af1dfdd5183598efcb00d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 11 Feb 2021 15:43:22 -0700 Subject: [PATCH 112/480] #609 #610 Adds new RetriggerableTimer and ActionSequence devices --- .../PepperDash_Essentials_Core.csproj | 2 + .../Timers/RetriggerableTimer.cs | 175 ++++++++++++++++++ .../Utilities/ActionSequence.cs | 153 +++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 8e688858..81f3774a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -327,6 +327,7 @@ + @@ -337,6 +338,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs new file mode 100644 index 00000000..b31c9da0 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; + +using Newtonsoft.Json; + + +namespace PepperDash.Essentials.Core.Timers +{ + /// + /// A device that runs a retriggerable timer and can execute actions specified in config + /// + [Description("A retriggerable timer device")] + public class RetriggerableTimer : EssentialsDevice + { + private RetriggerableTimerPropertiesConfig _propertiesConfig; + + private CTimer _timer; + private long _timerIntervalMs; + + public RetriggerableTimer(string key, DeviceConfig config) + : base(key, config.Name) + { + var props = config.Properties.ToObject(); + _propertiesConfig = props; + + if (_propertiesConfig != null) + { + _timerIntervalMs = _propertiesConfig.TimerIntervalMs; + } + } + + public override bool CustomActivate() + { + if (_propertiesConfig.StartTimerOnActivation) + { + StartTimer(); + } + + return base.CustomActivate(); + } + + private void CleanUpTimer() + { + if (_timer != null) + { + _timer.Stop(); + _timer.Dispose(); + } + + _timer = null; + } + + public void StartTimer() + { + CleanUpTimer(); + + _timer = new CTimer(TimerElapsedCallback, GetActionFromConfig(eRetriggerableTimerEvents.Elapsed), 0, _timerIntervalMs); + } + + public void StopTimer() + { + _timer.Stop(); + + ExecuteAction(GetActionFromConfig(eRetriggerableTimerEvents.Stopped)); + } + + private DeviceActionWrapper GetActionFromConfig(eRetriggerableTimerEvents eventType) + { + var action = _propertiesConfig.Events[eRetriggerableTimerEvents.Elapsed]; + + if (action != null) + return action; + else return null; + } + + /// + /// Executes the Elapsed action from confing when the timer elapses + /// + /// + private void TimerElapsedCallback(object action) + { + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Timer Elapsed. Executing Action"); + + if (action == null) + { + Debug.Console(1, this, "Timer elapsed but unable to execute action. Action is null."); + return; + } + + var devAction = action as DeviceActionWrapper; + if (devAction != null) + ExecuteAction(devAction); + else + { + Debug.Console(2, this, "Unable to cast action as DeviceActionWrapper. Cannot Execute"); + } + + } + + private void ExecuteAction(DeviceActionWrapper action) + { + if (action == null) + return; + + try + { + DeviceJsonApi.DoDeviceAction(action); + } + catch (Exception e) + { + Debug.Console(2, this, "Error Executing Action: {0}", e); + } + //finally // Not sure this is needed + //{ + // _Timer.Reset(0, _TimerIntervalMs); + //} + } + } + + /// + /// Configuration Properties for RetriggerableTimer + /// + public class RetriggerableTimerPropertiesConfig + { + [JsonProperty("startTimerOnActivation")] + public bool StartTimerOnActivation { get; set; } + + [JsonProperty("timerIntervalMs")] + public long TimerIntervalMs { get; set; } + + [JsonProperty("events")] + public Dictionary Events { get; set; } + + public RetriggerableTimerPropertiesConfig() + { + Events = new Dictionary(); + } + } + + /// + /// The set of values describing events on the timer + /// + public enum eRetriggerableTimerEvents + { + Elapsed, + Stopped, + } + + /// + /// Factory class + /// + public class RetriggerableTimerFactory : EssentialsDeviceFactory + { + public RetriggerableTimerFactory() + { + TypeNames = new List() { "retriggerabletimer" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new RetriggerableTimer Device"); + + return new RetriggerableTimer(dc.Key, dc); + } + } + + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs new file mode 100644 index 00000000..c62b6e47 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.CrestronThread; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core.Utilities +{ + /// + /// A device that executes a sequence of actions with optional delays between actions + /// + [Description("A device that exectues a sequence of actions with optional delays between actions")] + public class ActionSequence : EssentialsDevice + { + private ActionSequencePropertiesConfig _propertiesConfig; + + private CrestronQueue _actionQueue; + + private Thread _worker; + + private bool _allowActionsToExecute; + + public ActionSequence(string key, DeviceConfig config) + : base(key, config.Name) + { + var props = config.Properties.ToObject(); + _propertiesConfig = props; + + if (_propertiesConfig != null) + { + if (_propertiesConfig.ActionSequence.Count > 0) + { + _actionQueue = new CrestronQueue(_propertiesConfig.ActionSequence.Count); + } + } + } + + /// + /// Starts executing the sequenced actions + /// + public void StartSequence() + { + Debug.Console(1, this, "Starting Action Sequence"); + _allowActionsToExecute = true; + AddActionsToQueue(); + _worker = new Thread(ProcessActions, null, Thread.eThreadStartOptions.Running); + } + + /// + /// Stops executing the sequenced actions + /// + public void StopSequence() + { + Debug.Console(1, this, "Stopping Action Sequence"); + _allowActionsToExecute = false; + _worker.Abort(); + } + + /// + /// Populates the queue from the configuration information + /// + private void AddActionsToQueue() + { + Debug.Console(1, this, "Adding {0} actions to queue", _propertiesConfig.ActionSequence.Count); + + for (int i = 0; i < _propertiesConfig.ActionSequence.Count; i++) + { + _actionQueue.Enqueue(_propertiesConfig.ActionSequence[i]); + } + } + + private object ProcessActions(object obj) + { + while (_allowActionsToExecute && _actionQueue.Count > 0) + { + SequencedDeviceActionWrapper action = null; + + action = _actionQueue.Dequeue(); + if (action == null) + break; + + // Delay before executing + if (action.DelayMs > 0) + Thread.Sleep(action.DelayMs); + + ExecuteAction(action); + } + + return null; + } + + private void ExecuteAction(DeviceActionWrapper action) + { + if (action == null) + return; + + try + { + DeviceJsonApi.DoDeviceAction(action); + } + catch (Exception e) + { + Debug.Console(2, this, "Error Executing Action: {0}", e); + } + } + } + + /// + /// Configuration Properties for ActionSequence + /// + public class ActionSequencePropertiesConfig + { + [JsonProperty("actionSequence")] + public List ActionSequence { get; set; } + + public ActionSequencePropertiesConfig() + { + ActionSequence = new List(); + } + } + + public class SequencedDeviceActionWrapper : DeviceActionWrapper + { + [JsonProperty("delayMs")] + public int DelayMs { get; set; } + } + + /// + /// Factory class + /// + public class ActionSequenceFactory : EssentialsDeviceFactory + { + public ActionSequenceFactory() + { + TypeNames = new List() { "actionsequence" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new ActionSequence Device"); + + return new ActionSequence(dc.Key, dc); + } + } + +} \ No newline at end of file From 2fc1f45161920f4565c4c22d8fbd355efab6c4db Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 11 Feb 2021 15:56:43 -0700 Subject: [PATCH 113/480] Fixes timer from executing immediately on construction. Adds some helpful debug statements --- .../PepperDashEssentialsBase/Timers/RetriggerableTimer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs index b31c9da0..67222e43 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/RetriggerableTimer.cs @@ -60,12 +60,14 @@ namespace PepperDash.Essentials.Core.Timers public void StartTimer() { CleanUpTimer(); + Debug.Console(0, this, "Starting Timer"); - _timer = new CTimer(TimerElapsedCallback, GetActionFromConfig(eRetriggerableTimerEvents.Elapsed), 0, _timerIntervalMs); + _timer = new CTimer(TimerElapsedCallback, GetActionFromConfig(eRetriggerableTimerEvents.Elapsed), _timerIntervalMs, _timerIntervalMs); } public void StopTimer() { + Debug.Console(0, this, "Stopping Timer"); _timer.Stop(); ExecuteAction(GetActionFromConfig(eRetriggerableTimerEvents.Stopped)); From 16bc2ca381ca5083bbe96161529832521e53ae9e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 11 Feb 2021 16:44:18 -0700 Subject: [PATCH 114/480] Corrects spelling mistake and adds check to see if thread is already running before allowing sequence to start --- .../PepperDashEssentialsBase/Utilities/ActionSequence.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs index c62b6e47..bc1e8a4e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs @@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core.Utilities /// /// A device that executes a sequence of actions with optional delays between actions /// - [Description("A device that exectues a sequence of actions with optional delays between actions")] + [Description("A device that executes a sequence of actions with optional delays between actions")] public class ActionSequence : EssentialsDevice { private ActionSequencePropertiesConfig _propertiesConfig; @@ -47,6 +47,12 @@ namespace PepperDash.Essentials.Core.Utilities /// public void StartSequence() { + if (_worker.ThreadState == Thread.eThreadStates.ThreadRunning) + { + Debug.Console(1, this, "Thread already running. Cannot Start Sequence"); + return; + } + Debug.Console(1, this, "Starting Action Sequence"); _allowActionsToExecute = true; AddActionsToQueue(); From 88c332729ff8cb7eea4bb7744b16d85aa9a8f2b9 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 15 Feb 2021 16:11:47 -0700 Subject: [PATCH 115/480] #584 Implements GenericQueue in place of queue and thread in CiscoSparkCodec --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 41 ++----------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 2501bf22..b885674c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -18,6 +18,7 @@ using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash_Essentials_Core.Queues; using PepperDash_Essentials_Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco @@ -38,9 +39,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public StatusMonitorBase CommunicationMonitor { get; private set; } - private CrestronQueue ReceiveQueue; - - private Thread ReceiveThread; + private GenericQueue ReceiveQueue; public BoolFeedback PresentationViewMaximizedFeedback { get; private set; } @@ -302,12 +301,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } // The queue that will collect the repsonses in the order they are received - ReceiveQueue = new CrestronQueue(25); - - // The thread responsible for dequeuing and processing the messages - ReceiveThread = new Thread((o) => ProcessQueue(), null); - ReceiveThread.Priority = Thread.eThreadPriority.MediumPriority; - + ReceiveQueue = new GenericQueue(this.Key + "-rxQueue", 25); RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc); @@ -421,29 +415,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco _brandingUrl = props.UiBranding.BrandingUrl; } - /// Runs in it's own thread to dequeue messages in the order they were received to be processed - /// - /// - object ProcessQueue() - { - try - { - while (true) - { - var message = ReceiveQueue.Dequeue(); - - DeserializeResponse(message); - } - } - catch (Exception e) - { - Debug.Console(1, this, "Error Processing Queue: {0}", e); - } - - return null; - } - - /// /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input /// to enable routing @@ -687,11 +658,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco // Enqueue the complete message to be deserialized - ReceiveQueue.Enqueue(JsonMessage.ToString()); - //DeserializeResponse(JsonMessage.ToString()); - - if (ReceiveThread.ThreadState != Thread.eThreadStates.ThreadRunning) - ReceiveThread.Start(); + ReceiveQueue.Enqueue(new ProcessStringMessage(JsonMessage.ToString(), DeserializeResponse)); return; } From 382c35924c0514371d491645e4556780e9010011 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 16 Feb 2021 13:28:52 -0700 Subject: [PATCH 116/480] #612 Implements VideoCodecBase.LinkVideoCodecToApi() on CiscoSparkCodec --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index b885674c..208dd03e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -1448,7 +1448,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { - throw new NotImplementedException(); + LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge); } /// From f075412a8642d8215358e8d504b537251047ef86 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 16 Feb 2021 16:33:03 -0700 Subject: [PATCH 117/480] #548 Implments IBridgeAdvanced on IRBlurayBase and adds IRBlurayBaseJoinMap --- .../Bridges/JoinMaps/IRBlurayBaseJoinMap.cs | 222 ++++++++++++++++++ .../JoinMaps/SetTopBoxControllerJoinMap.cs | 10 +- .../PepperDash_Essentials_Core.csproj | 1 + .../DiscPlayer/IRDiscPlayerBase.cs | 112 ++++++++- .../SetTopBox/IRSetTopBoxBase.cs | 11 +- 5 files changed, 347 insertions(+), 9 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IRBlurayBaseJoinMap.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IRBlurayBaseJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IRBlurayBaseJoinMap.cs new file mode 100644 index 00000000..991489e9 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IRBlurayBaseJoinMap.cs @@ -0,0 +1,222 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core.Bridges +{ + /// + /// Join map for IRBlurayBase devices + /// + public class IRBlurayBaseJoinMap : JoinMapBaseAdvanced + { + [JoinName("PowerOn")] + public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("PowerOff")] + public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata { Description = "Power Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("PowerToggle")] + public JoinDataComplete PowerToggle = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, + new JoinMetadata { Description = "Power Toggle", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Up")] + public JoinDataComplete Up = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 }, + new JoinMetadata { Description = "Nav Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Down")] + public JoinDataComplete Down = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 }, + new JoinMetadata { Description = "Nav Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Left")] + public JoinDataComplete Left = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 }, + new JoinMetadata { Description = "Nav Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Right")] + public JoinDataComplete Right = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 }, + new JoinMetadata { Description = "Nav Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Select")] + public JoinDataComplete Select = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 }, + new JoinMetadata { Description = "Select", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Menu")] + public JoinDataComplete Menu = new JoinDataComplete(new JoinData { JoinNumber = 9, JoinSpan = 1 }, + new JoinMetadata { Description = "Menu", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Exit")] + public JoinDataComplete Exit = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 }, + new JoinMetadata { Description = "Exit", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit0")] + public JoinDataComplete Digit0 = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 0", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit1")] + public JoinDataComplete Digit1 = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 1", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit2")] + public JoinDataComplete Digit2 = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 2", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit3")] + public JoinDataComplete Digit3 = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 3", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit4")] + public JoinDataComplete Digit4 = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 4", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit5")] + public JoinDataComplete Digit5 = new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 5", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit6")] + public JoinDataComplete Digit6 = new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 6", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit7")] + public JoinDataComplete Digit7 = new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 7", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit8")] + public JoinDataComplete Digit8 = new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 8", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Digit9")] + public JoinDataComplete Digit9 = new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, + new JoinMetadata { Description = "Digit 9", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("KeypadClear")] + public JoinDataComplete KeypadClear = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, + new JoinMetadata { Description = "Keypad Clear", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("KeypadEnter")] + public JoinDataComplete KeypadEnter = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata { Description = "Keypad Enter", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("ChannelUp")] + public JoinDataComplete ChannelUp = new JoinDataComplete(new JoinData { JoinNumber = 23, JoinSpan = 1 }, + new JoinMetadata { Description = "STB Channel Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("ChannelDown")] + public JoinDataComplete ChannelDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, + new JoinMetadata { Description = "STB Channel Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("LastChannel")] + public JoinDataComplete LastChannel = new JoinDataComplete(new JoinData { JoinNumber = 25, JoinSpan = 1 }, + new JoinMetadata { Description = "Last Channel", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Guide")] + public JoinDataComplete Guide = new JoinDataComplete(new JoinData { JoinNumber = 26, JoinSpan = 1 }, + new JoinMetadata { Description = "Guide", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Info")] + public JoinDataComplete Info = new JoinDataComplete(new JoinData { JoinNumber = 27, JoinSpan = 1 }, + new JoinMetadata { Description = "Info", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Red")] + public JoinDataComplete Red = new JoinDataComplete(new JoinData { JoinNumber = 28, JoinSpan = 1 }, + new JoinMetadata { Description = "Red", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Green")] + public JoinDataComplete Green = new JoinDataComplete(new JoinData { JoinNumber = 29, JoinSpan = 1 }, + new JoinMetadata { Description = "Green", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Yellow")] + public JoinDataComplete Yellow = new JoinDataComplete(new JoinData { JoinNumber = 30, JoinSpan = 1 }, + new JoinMetadata { Description = "Yellow", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Blue")] + public JoinDataComplete Blue = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, + new JoinMetadata { Description = "Blue", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + + [JoinName("Play")] + public JoinDataComplete Play = new JoinDataComplete(new JoinData { JoinNumber = 33, JoinSpan = 1 }, + new JoinMetadata { Description = "Play", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Pause")] + public JoinDataComplete Pause = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 }, + new JoinMetadata { Description = "Pause", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Stop")] + public JoinDataComplete Stop = new JoinDataComplete(new JoinData { JoinNumber = 35, JoinSpan = 1 }, + new JoinMetadata { Description = "Stop", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("FFwd")] + public JoinDataComplete FFwd = new JoinDataComplete(new JoinData { JoinNumber = 36, JoinSpan = 1 }, + new JoinMetadata { Description = "FFwd", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Rewind")] + public JoinDataComplete Rewind = new JoinDataComplete(new JoinData { JoinNumber = 37, JoinSpan = 1 }, + new JoinMetadata { Description = "Rewind", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("ChapPlus")] + public JoinDataComplete ChapPlus = new JoinDataComplete(new JoinData { JoinNumber = 38, JoinSpan = 1 }, + new JoinMetadata { Description = "Chapter Plus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("ChapMinus")] + public JoinDataComplete ChapMinus = new JoinDataComplete(new JoinData { JoinNumber = 39, JoinSpan = 1 }, + new JoinMetadata { Description = "Chapter Minus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Replay")] + public JoinDataComplete Replay = new JoinDataComplete(new JoinData { JoinNumber = 40, JoinSpan = 1 }, + new JoinMetadata { Description = "Replay", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Record")] + public JoinDataComplete Record = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata { Description = "Record", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("HasKeypadAccessoryButton1")] + public JoinDataComplete HasKeypadAccessoryButton1 = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 }, + new JoinMetadata { Description = "Has Keypad Accessory Button 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("HasKeypadAccessoryButton2")] + public JoinDataComplete HasKeypadAccessoryButton2 = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 }, + new JoinMetadata { Description = "Has Keypad Accessory Button 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("KeypadAccessoryButton1Press")] + public JoinDataComplete KeypadAccessoryButton1Press = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 2 }, + new JoinMetadata { Description = "Keypad Accessory Button 1 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("KeypadAccessoryButton2Press")] + public JoinDataComplete KeypadAccessoryButton2Press = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 2 }, + new JoinMetadata { Description = "Keypad Accessory Button 2 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("KeypadAccessoryButton1Label")] + public JoinDataComplete KeypadAccessoryButton1Label = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 }, + new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + + [JoinName("KeypadAccessoryButton2Label")] + public JoinDataComplete KeypadAccessoryButton2Label = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 }, + new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + + /// + /// Constructor to use when instantiating this Join Map without inheriting from it + /// + /// Join this join map will start at + public IRBlurayBaseJoinMap(uint joinStart) + : this(joinStart, typeof(IRBlurayBaseJoinMap)) + { + } + + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + protected IRBlurayBaseJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs index 0eddc9f3..a65c537c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs @@ -1,10 +1,10 @@ using System; -namespace PepperDash.Essentials.Core.Bridges -{ - public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced - { +namespace PepperDash.Essentials.Core.Bridges +{ + public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced + { [JoinName("PowerOn")] public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "STB Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); @@ -236,5 +236,5 @@ namespace PepperDash.Essentials.Core.Bridges : base(joinStart, type) { } - } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 81f3774a..3637b6e2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -143,6 +143,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs index 581ea3b5..33ab25da 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DiscPlayer/IRDiscPlayerBase.cs @@ -4,19 +4,20 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using Newtonsoft.Json.Linq; - using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Bridges; namespace PepperDash.Essentials.Devices.Common { - public class IRBlurayBase : EssentialsDevice, IDiscPlayerControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking + public class IRBlurayBase : EssentialsBridgeableDevice, IDiscPlayerControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking { public IrOutputPortController IrPort { get; private set; } @@ -45,6 +46,113 @@ namespace PepperDash.Essentials.Devices.Common OutputPorts = new RoutingPortCollection { HdmiOut, AnyAudioOut }; } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new IRBlurayBaseJoinMap(joinStart); + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to SetTopBox: {0}", Name); + + + trilist.OnlineStatusChange += new OnlineStatusChangeEventHandler((o, a) => + { + if (a.DeviceOnLine) + { + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; + } + }); + + var powerDev = this as IHasPowerControl; + if (powerDev != null) + { + trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, powerDev.PowerOn); + trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, powerDev.PowerOff); + trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, powerDev.PowerToggle); + } + + var dpadDev = this as IDPad; + if (dpadDev != null) + { + trilist.SetBoolSigAction(joinMap.Up.JoinNumber, dpadDev.Up); + trilist.SetBoolSigAction(joinMap.Down.JoinNumber, dpadDev.Down); + trilist.SetBoolSigAction(joinMap.Left.JoinNumber, dpadDev.Left); + trilist.SetBoolSigAction(joinMap.Right.JoinNumber, dpadDev.Right); + trilist.SetBoolSigAction(joinMap.Select.JoinNumber, dpadDev.Select); + trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, dpadDev.Menu); + trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, dpadDev.Exit); + } + + var channelDev = this as IChannel; + if (channelDev != null) + { + trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, channelDev.ChannelUp); + trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, channelDev.ChannelDown); + trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, channelDev.LastChannel); + trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, channelDev.Guide); + trilist.SetBoolSigAction(joinMap.Info.JoinNumber, channelDev.Info); + trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, channelDev.Exit); + } + + var colorDev = this as IColor; + if (colorDev != null) + { + trilist.SetBoolSigAction(joinMap.Red.JoinNumber, colorDev.Red); + trilist.SetBoolSigAction(joinMap.Green.JoinNumber, colorDev.Green); + trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, colorDev.Yellow); + trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, colorDev.Blue); + } + + var keypadDev = this as ISetTopBoxNumericKeypad; + if (keypadDev != null) + { + trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = keypadDev.KeypadAccessoryButton1Label; + trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = keypadDev.KeypadAccessoryButton2Label; + + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = keypadDev.HasKeypadAccessoryButton1; + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = keypadDev.HasKeypadAccessoryButton2; + + trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, keypadDev.Digit0); + trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, keypadDev.Digit1); + trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, keypadDev.Digit2); + trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, keypadDev.Digit3); + trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, keypadDev.Digit4); + trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, keypadDev.Digit5); + trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, keypadDev.Digit6); + trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, keypadDev.Digit7); + trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, keypadDev.Digit8); + trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, keypadDev.Digit9); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, keypadDev.KeypadAccessoryButton1); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, keypadDev.KeypadAccessoryButton1); + trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, keypadDev.KeypadEnter); + } + + var transportDev = this as ITransport; + if (transportDev != null) + { + trilist.SetBoolSigAction(joinMap.Play.JoinNumber, transportDev.Play); + trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, transportDev.Pause); + trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, transportDev.Rewind); + trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, transportDev.FFwd); + trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, transportDev.ChapMinus); + trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, transportDev.ChapPlus); + trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, transportDev.Stop); + trilist.SetBoolSigAction(joinMap.Record.JoinNumber, transportDev.Record); + } + } + #region IDPad Members diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs index 394d7b8d..db72d8eb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs @@ -388,9 +388,16 @@ namespace PepperDash.Essentials.Devices.Common } Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - Debug.Console(0, "Linking to Display: {0}", Name); + Debug.Console(0, "Linking to SetTopBox: {0}", Name); + + trilist.OnlineStatusChange += new OnlineStatusChangeEventHandler((o, a) => + { + if (a.DeviceOnLine) + { + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; + } + }); - trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; var stbBase = this as ISetTopBoxControls; if (stbBase != null) From 24a435c9654f6e747b854385cee80e3edc7c1b15 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Feb 2021 10:18:19 -0700 Subject: [PATCH 118/480] Prevents join map info from printing on program start (JoinMapBaseAdvanced constructor) unless debug level is > 0 --- .../PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs index b9825749..aa8e2e6d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs @@ -233,7 +233,10 @@ namespace PepperDash.Essentials.Core } - PrintJoinMapInfo(); + if (Debug.Level > 0) + { + PrintJoinMapInfo(); + } } /// From bc548563923aabbb8e3a6a6379b3727ad38409cc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Feb 2021 11:27:07 -0700 Subject: [PATCH 119/480] #542 Updates log level for error messages when constructing devices --- PepperDashEssentials/ControlSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 3e3798a4..5df5c1a2 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -383,11 +383,11 @@ namespace PepperDash.Essentials if (newDev != null) DeviceManager.AddDevice(newDev); else - Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); + Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); } catch (Exception e) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e); + Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e); } } Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); From 70204801595cca8e9a6737c2f6126fbc02293ea1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Feb 2021 11:44:33 -0700 Subject: [PATCH 120/480] Moves console messages about adding factory methods to level 1 --- .../PepperDashEssentialsBase/Factory/DeviceFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index e337b7d4..3f38e2d5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -67,13 +67,13 @@ namespace PepperDash.Essentials.Core /// public static void AddFactoryForType(string typeName, Func method) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); } public static void AddFactoryForType(string typeName, string description, CType cType, Func method) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); if(FactoryMethods.ContainsKey(typeName)) { From e356f57e1ad2700d9e978b832f9584ddcebb0bbc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Feb 2021 16:50:18 -0700 Subject: [PATCH 121/480] #415 Adds camera mute methods and feedback to CiscoSparkCodec Adds new IHasCameraMute to more clearly define functions and implements on CiscoSparkCodec and ZoomRoom --- .../Cameras/CameraControl.cs | 11 ++++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 55 +++++++++++++++++-- .../VideoCodec/CiscoCodec/xStatus.cs | 17 ++++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 27 ++++++++- 4 files changed, 104 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs index c0a0442c..208b38de 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraControl.cs @@ -46,6 +46,17 @@ namespace PepperDash.Essentials.Devices.Common.Cameras void CameraOff(); } + /// + /// Describes the ability to mute and unmute camera video + /// + public interface IHasCameraMute + { + BoolFeedback CameraIsMutedFeedback { get; } + void CameraMuteOn(); + void CameraMuteOff(); + void CameraMuteToggle(); + } + public class CameraSelectedEventArgs : EventArgs { public CameraBase SelectedCamera { get; private set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 208dd03e..4d074678 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -29,7 +29,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, - ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding + ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute { public event EventHandler DirectoryResultReturned; @@ -311,6 +311,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); LocalLayoutIsProminentFeedback = new BoolFeedback(LocalLayoutIsProminentFeedbackFunc); FarEndIsSharingContentFeedback = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); + CameraIsOffFeedback = new BoolFeedback(() => CodecStatus.Status.Video.Input.MainVideoMute.BoolValue); + CameraIsMutedFeedback = CameraIsOffFeedback; + PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); @@ -376,8 +379,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate; CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction += SharingContentIsOnFeedback.FireUpdate; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction += FarEndIsSharingContentFeedback.FireUpdate; + CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; + CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; + CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); @@ -1631,6 +1635,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public void CameraAutoModeOn() { SendText("xCommand Cameras SpeakerTrack Activate"); + CameraMuteOff(); } public void CameraAutoModeOff() @@ -1706,6 +1711,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco _selectedCamera = value; SelectedCameraFeedback.FireUpdate(); ControllingFarEndCameraFeedback.FireUpdate(); + if (CameraIsOffFeedback.BoolValue) + CameraMuteOff(); var handler = CameraSelected; if (handler != null) @@ -1969,7 +1976,47 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco #endregion - } + + #region IHasCameraOff Members + + public BoolFeedback CameraIsOffFeedback { get; private set; } + + public void CameraOff() + { + CameraMuteOn(); + } + + #endregion + + public BoolFeedback CameraIsMutedFeedback { get; private set; } + + /// + /// Mutes the outgoing camera video + /// + public void CameraMuteOn() + { + SendText("xCommand Video InputMainVideo Mute"); + } + + /// + /// Unmutes the outgoing camera video + /// + public void CameraMuteOff() + { + SendText("xCommand Video InputMainVideo Unmute"); + } + + /// + /// Toggles the camera mute state + /// + public void CameraMuteToggle() + { + if (CameraIsMutedFeedback.BoolValue) + CameraMuteOff(); + else + CameraMuteOn(); + } + } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index e3fd4dcb..7fa4e655 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -1606,6 +1606,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public string Value { get; set; } } + public class MainVideoMute : ValueProperty + { + public bool BoolValue { get; private set; } + + public string Value + { + set + { + // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false + BoolValue = value == "On"; + OnValueChanged(); + } + } + + } + public class ConnectorId { public string Value { get; set; } @@ -1662,6 +1678,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { public List Connector { get; set; } public MainVideoSource MainVideoSource { get; set; } + public MainVideoMute MainVideoMute { get; set; } public List Source { get; set; } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 980c7a61..84617c6d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, IRouting, - IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraAutoMode, + IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing { private const long MeetingRefreshTimer = 60000; @@ -98,6 +98,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc); + CameraIsMutedFeedback = CameraIsOffFeedback; + CameraAutoModeIsOnFeedback = new BoolFeedback(CameraAutoModeIsOnFeedbackFunc); CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer); @@ -1775,16 +1777,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void CameraOff() { - SendText("zConfiguration Call Camera Mute: On"); + CameraMuteOn(); } #endregion + public BoolFeedback CameraIsMutedFeedback { get; private set; } + + public void CameraMuteOn() + { + SendText("zConfiguration Call Camera Mute: On"); + } + + public void CameraMuteOff() + { + SendText("zConfiguration Call Camera Mute: Off"); + } + + public void CameraMuteToggle() + { + if (CameraIsMutedFeedback.BoolValue) + CameraMuteOff(); + else + CameraMuteOn(); + } + #region Implementation of IHasCameraAutoMode //Zoom doesn't support camera auto modes. Setting this to just unmute video public void CameraAutoModeOn() { + CameraMuteOff(); throw new NotImplementedException("Zoom Room Doesn't support camera auto mode"); } From 36b5faa3d9c5f5eaccb2f4c69b7696137e332b4a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 10:39:05 -0700 Subject: [PATCH 122/480] #618 Fix Occ sensor inheritance structure --- .../GlsOccupancySensorBaseController.cs | 172 +++------------ .../GlsOdtOccupancySensorController.cs | 196 +++++++++--------- .../GlsOirOccupancySensorController.cs | 80 +++++++ 3 files changed, 214 insertions(+), 234 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOirOccupancySensorController.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index c788f293..2b07c623 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -1,13 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; using Newtonsoft.Json; using PepperDash.Core; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Bridges; @@ -15,11 +11,11 @@ namespace PepperDash.Essentials.Core { [Description("Wrapper class for Single Technology GLS Occupancy Sensors")] [ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0}")] - public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider + public abstract class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider { public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; } - public GlsOccupancySensorBase OccSensor { get; private set; } + protected GlsOccupancySensorBase OccSensor; public BoolFeedback RoomIsOccupiedFeedback { get; private set; } @@ -58,44 +54,12 @@ namespace PepperDash.Essentials.Core } } - public GlsOccupancySensorBaseController(string key, Func preActivationFunc, - DeviceConfig config) - : base(key, config.Name) + protected GlsOccupancySensorBaseController(string key, DeviceConfig config) + : this(key, config.Name, config) { - var props = config.Properties.ToObject(); - - if (props != null) - { - PropertiesConfig = props; - } - else - { - Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig"); - } - - AddPreActivationAction(() => - { - OccSensor = preActivationFunc(config); - - RegisterCrestronGenericBase(OccSensor); - - RegisterGlsOdtSensorBaseController(OccSensor); - - }); - - AddPostActivationAction(() => - { - OccSensor.OnlineStatusChange += (o, a) => - { - if (a.DeviceOnLine) - { - ApplySettingsToSensorFromConfig(); - } - }; - }); } - public GlsOccupancySensorBaseController(string key, string name, DeviceConfig config) + protected GlsOccupancySensorBaseController(string key, string name, DeviceConfig config) : base(key, name) { @@ -183,7 +147,7 @@ namespace PepperDash.Essentials.Core } } - protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor) + protected void RegisterGlsOccupancySensorBaseController(GlsOccupancySensorBase occSensor) { OccSensor = occSensor; @@ -253,8 +217,8 @@ namespace PepperDash.Essentials.Core switch (args.EventId) { - case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId: - case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId: + case GlsOccupancySensorBase.RoomVacantFeedbackEventId: + case GlsOccupancySensorBase.RoomOccupiedFeedbackEventId: Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); RoomIsOccupiedFeedback.FireUpdate(); break; @@ -298,60 +262,36 @@ namespace PepperDash.Essentials.Core } } - /// - /// Enables or disables the PIR sensor - /// - /// - public void SetPirEnable(bool state) - { - Debug.Console(1, this, "Setting EnablePir to: {0}", state); + /// + /// Enables or disables the PIR sensor + /// + /// + public void SetPirEnable(bool state) + { + Debug.Console(1, this, "Setting EnablePir to: {0}", state); - if (state) - { - OccSensor.EnablePir.BoolValue = state; - OccSensor.DisablePir.BoolValue = !state; - } - else - { - OccSensor.EnablePir.BoolValue = state; - OccSensor.DisablePir.BoolValue = !state; - } - } + OccSensor.EnablePir.BoolValue = state; + OccSensor.DisablePir.BoolValue = !state; + } - /// - /// Enables or disables the LED Flash - /// - /// - public void SetLedFlashEnable(bool state) - { - if (state) - { - OccSensor.EnableLedFlash.BoolValue = state; - OccSensor.DisableLedFlash.BoolValue = !state; - } - else - { - OccSensor.EnableLedFlash.BoolValue = state; - OccSensor.DisableLedFlash.BoolValue = !state; - } - } + /// + /// Enables or disables the LED Flash + /// + /// + public void SetLedFlashEnable(bool state) + { + OccSensor.EnableLedFlash.BoolValue = state; + OccSensor.DisableLedFlash.BoolValue = !state; + } - /// + /// /// Enables or disables short timeout based on state /// /// public void SetShortTimeoutState(bool state) { - if (state) - { OccSensor.EnableShortTimeout.BoolValue = state; OccSensor.DisableShortTimeout.BoolValue = !state; - } - else - { - OccSensor.EnableShortTimeout.BoolValue = state; - OccSensor.DisableShortTimeout.BoolValue = !state; - } } public void IncrementPirSensitivityInOccupiedState(bool pressRelease) @@ -406,11 +346,10 @@ namespace PepperDash.Essentials.Core OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value; } - /// - /// Method to print current occ settings to console. - /// - /// - public virtual void GetSettings() + /// + /// Method to print current occ settings to console. + /// + public virtual void GetSettings() { var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); @@ -544,53 +483,6 @@ namespace PepperDash.Essentials.Core #endregion } - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); - } - - #region PreActivation - - private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc) - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - var branchId = control.ControlPortNumber; - var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - - if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); - return new GlsOirCCn(cresnetId, Global.ControlSystem); - } - var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; - - if (cresnetBridge != null) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); - return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); - } - Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); - return null; - } - #endregion - - public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory - { - public GlsOccupancySensorBaseControllerFactory() - { - TypeNames = new List() { "glsoirccn" }; - } - - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); - - return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc); - } - - } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index e19c9ba7..f8afe49d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Core [ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0,\"enableUsA\": true,\"enableUsB\": true,\"orWhenVacatedState\": true}")] public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController { - public new GlsOdtCCn OccSensor { get; private set; } + private GlsOdtCCn _occSensor; public BoolFeedback OrWhenVacatedFeedback { get; private set; } @@ -42,31 +42,29 @@ namespace PepperDash.Essentials.Core { AddPreActivationAction(() => { - OccSensor = preActivationFunc(config); + _occSensor = preActivationFunc(config); - RegisterCrestronGenericBase(OccSensor); + RegisterCrestronGenericBase(_occSensor); - RegisterGlsOdtSensorBaseController(OccSensor); + RegisterGlsOccupancySensorBaseController(OccSensor); - AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); + AndWhenVacatedFeedback = new BoolFeedback(() => _occSensor.AndWhenVacatedFeedback.BoolValue); - OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); + OrWhenVacatedFeedback = new BoolFeedback(() => _occSensor.OrWhenVacatedFeedback.BoolValue); - UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); + UltrasonicAEnabledFeedback = new BoolFeedback(() => _occSensor.UsAEnabledFeedback.BoolValue); - UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); + UltrasonicBEnabledFeedback = new BoolFeedback(() => _occSensor.UsBEnabledFeedback.BoolValue); - RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); + RawOccupancyPirFeedback = new BoolFeedback(() => _occSensor.RawOccupancyPirFeedback.BoolValue); - RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); + RawOccupancyUsFeedback = new BoolFeedback(() => _occSensor.RawOccupancyUsFeedback.BoolValue); - UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); - - UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); - - }); + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => _occSensor.UsSensitivityInVacantStateFeedback.UShortValue); + UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => _occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); + }); } protected override void ApplySettingsToSensorFromConfig() @@ -114,45 +112,59 @@ namespace PepperDash.Essentials.Core /// protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) { - if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) - AndWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId) - OrWhenVacatedFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId) - UltrasonicAEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) - UltrasonicBEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) - UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) - UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); + switch (args.EventId) + { + case GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId: + AndWhenVacatedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId: + OrWhenVacatedFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.UsAEnabledFeedbackEventId: + UltrasonicAEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.UsBEnabledFeedbackEventId: + UltrasonicBEnabledFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId: + UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId: + UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); + break; + } - base.OccSensor_GlsOccupancySensorChange(device, args); + base.OccSensor_GlsOccupancySensorChange(device, args); } - /// + /// /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. /// Then calls the base delegate method to ensure any common event IDs are captured. /// /// /// protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) - { - if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) - RawOccupancyPirFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) - RawOccupancyUsFeedback.FireUpdate(); + { + switch (args.EventId) + { + case GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId: + RawOccupancyPirFeedback.FireUpdate(); + break; + case GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId: + RawOccupancyUsFeedback.FireUpdate(); + break; + } - base.OccSensor_BaseEvent(device, args); - } + base.OccSensor_BaseEvent(device, args); + } - /// + /// /// Sets the OrWhenVacated state /// /// public void SetOrWhenVacatedState(bool state) { - OccSensor.OrWhenVacated.BoolValue = state; + _occSensor.OrWhenVacated.BoolValue = state; } /// @@ -161,7 +173,7 @@ namespace PepperDash.Essentials.Core /// public void SetAndWhenVacatedState(bool state) { - OccSensor.AndWhenVacated.BoolValue = state; + _occSensor.AndWhenVacated.BoolValue = state; } /// @@ -170,8 +182,8 @@ namespace PepperDash.Essentials.Core /// public void SetUsAEnable(bool state) { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; + _occSensor.EnableUsA.BoolValue = state; + _occSensor.DisableUsA.BoolValue = !state; } @@ -181,28 +193,28 @@ namespace PepperDash.Essentials.Core /// public void SetUsBEnable(bool state) { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; + _occSensor.EnableUsB.BoolValue = state; + _occSensor.DisableUsB.BoolValue = !state; } public void IncrementUsSensitivityInOccupiedState(bool pressRelease) { - OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + _occSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; } public void DecrementUsSensitivityInOccupiedState(bool pressRelease) { - OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + _occSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; } public void IncrementUsSensitivityInVacantState(bool pressRelease) { - OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; + _occSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; } public void DecrementUsSensitivityInVacantState(bool pressRelease) { - OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; + _occSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; } public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) @@ -218,62 +230,58 @@ namespace PepperDash.Essentials.Core base.GetSettings(); Debug.Console(0, this, "Ultrasonic Enabled A: {0} | B: {1}", - OccSensor.UsAEnabledFeedback.BoolValue, - OccSensor.UsBEnabledFeedback.BoolValue); + _occSensor.UsAEnabledFeedback.BoolValue, + _occSensor.UsBEnabledFeedback.BoolValue); Debug.Console(0, this, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}", - OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue, - OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + _occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue, + _occSensor.UsSensitivityInVacantStateFeedback.UShortValue); var dash = new string('*', 50); CrestronConsole.PrintLine(string.Format("{0}\n", dash)); } - - #region PreActivation - - private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc) - { - var control = CommFactory.GetControlPropertiesConfig(dc); - var cresnetId = control.CresnetIdInt; - var branchId = control.ControlPortNumber; - var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; - - if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); - return new GlsOdtCCn(cresnetId, Global.ControlSystem); - } - var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; - - if (cresnetBridge != null) - { - Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); - return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); - } - Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); - return null; - } - #endregion - - public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory - { - public GlsOdtOccupancySensorControllerFactory() - { - TypeNames = new List() { "glsodtccn" }; - } - - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); - - return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc); - } - - } } + public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory + { + public GlsOdtOccupancySensorControllerFactory() + { + TypeNames = new List { "glsodtccn" }; + } + + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc); + } + + private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = String.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey); + return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOirOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOirOccupancySensorController.cs new file mode 100644 index 00000000..573d94ac --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOirOccupancySensorController.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.GeneralIO; +using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core +{ + public class GlsOirOccupancySensorController:GlsOccupancySensorBaseController + { + private GlsOirCCn _occSensor; + + public GlsOirOccupancySensorController(string key, Func preActivationFunc,DeviceConfig config) : this(key,config.Name, preActivationFunc, config) + { + } + + public GlsOirOccupancySensorController(string key, string name, Func preActivationFunc, DeviceConfig config) : base(key, name, config) + { + AddPreActivationAction(() => + { + _occSensor = preActivationFunc(config); + + RegisterCrestronGenericBase(_occSensor); + + RegisterGlsOccupancySensorBaseController(_occSensor); + }); + } + + #region Overrides of CrestronGenericBridgeableBaseDevice + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge); + } + + #endregion + } + + public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory + { + public GlsOccupancySensorBaseControllerFactory() + { + TypeNames = new List { "glsoirccn" }; + } + + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOirOccupancySensorController Device"); + + return new GlsOirOccupancySensorController(dc.Key, GetGlsOirCCn, dc); + } + + private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey); + return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + + } +} \ No newline at end of file From dbd3ab2f70fb446cf864da0f439cce3cc629f6b6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 10:44:21 -0700 Subject: [PATCH 123/480] #618 more refactoring --- .../GlsOccupancySensorBaseController.cs | 193 ++++++++++-------- .../GlsOdtOccupancySensorController.cs | 3 - .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 109 insertions(+), 88 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 2b07c623..045a4143 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -285,16 +285,16 @@ namespace PepperDash.Essentials.Core } /// - /// Enables or disables short timeout based on state - /// - /// - public void SetShortTimeoutState(bool state) - { - OccSensor.EnableShortTimeout.BoolValue = state; - OccSensor.DisableShortTimeout.BoolValue = !state; - } + /// Enables or disables short timeout based on state + /// + /// + public void SetShortTimeoutState(bool state) + { + OccSensor.EnableShortTimeout.BoolValue = state; + OccSensor.DisableShortTimeout.BoolValue = !state; + } - public void IncrementPirSensitivityInOccupiedState(bool pressRelease) + public void IncrementPirSensitivityInOccupiedState(bool pressRelease) { OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease; } @@ -393,7 +393,6 @@ namespace PepperDash.Essentials.Core Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - #region Single and Dual Sensor Stuff occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name; @@ -405,84 +404,108 @@ namespace PepperDash.Essentials.Core } }; - // Occupied status - trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); - trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); - occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); - occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); - occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); - trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates); + LinkSingleTechSensorToApi(occController, trilist, joinMap); - // Timouts - trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout); - occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); - occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); - - // LED Flash - trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false)); - occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); - - // Short Timeout - trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true)); - trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false)); - occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); - - // PIR Sensor - trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true)); - trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false)); - occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); - - // PIR Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState); - trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState); - occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); - - // PIR Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState); - trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState); - occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); - #endregion - - #region Dual Technology Sensor Stuff - var odtOccController = occController as GlsOdtOccupancySensorController; - - if (odtOccController == null) return; - // OR When Vacated - trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState); - odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); - - // AND When Vacated - trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState); - odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); - - // Ultrasonic A Sensor - trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false)); - odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); - - // Ultrasonic B Sensor - trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true)); - trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false)); - odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); - - // US Sensitivity in Occupied State - trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState); - trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState); - odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); - - // US Sensitivity in Vacant State - trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState); - trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState); - odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); - - //Sensor Raw States - odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); - odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); - - #endregion + LinkDualTechSensorToApi(occController, trilist, joinMap); } + private static void LinkDualTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist, + GlsOccupancySensorBaseJoinMap joinMap) + { + var odtOccController = occController as GlsOdtOccupancySensorController; + + if (odtOccController == null) + { + return; + } + // OR When Vacated + trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState); + odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]); + + // AND When Vacated + trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState); + odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]); + + // Ultrasonic A Sensor + trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]); + + // Ultrasonic B Sensor + trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false)); + odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); + + // US Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, + odtOccController.IncrementUsSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, + odtOccController.DecrementUsSensitivityInOccupiedState); + odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig( + trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]); + + // US Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, + odtOccController.IncrementUsSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, + odtOccController.DecrementUsSensitivityInVacantState); + odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig( + trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]); + + //Sensor Raw States + odtOccController.RawOccupancyPirFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); + odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); + } + + private static void LinkSingleTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist, + GlsOccupancySensorBaseJoinMap joinMap) + { +// Occupied status + trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); + trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); + occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); + occController.RoomIsOccupiedFeedback.LinkComplementInputSig( + trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); + occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]); + trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates); + + // Timouts + trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout); + occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]); + occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]); + + // LED Flash + trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true)); + trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false)); + occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]); + + // Short Timeout + trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true)); + trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false)); + occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]); + + // PIR Sensor + trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true)); + trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false)); + occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]); + + // PIR Sensitivity in Occupied State + trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, + occController.IncrementPirSensitivityInOccupiedState); + trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, + occController.DecrementPirSensitivityInOccupiedState); + occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig( + trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]); + + // PIR Sensitivity in Vacant State + trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, + occController.IncrementPirSensitivityInVacantState); + trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, + occController.DecrementPirSensitivityInVacantState); + occController.PirSensitivityInVacantStateFeedback.LinkInputSig( + trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]); + } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index f8afe49d..35ecb397 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; using PepperDash.Core; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Bridges; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 3637b6e2..cf5587dd 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -229,6 +229,7 @@ + From c04d79931d17b9793bd9d0ad1e638ab96ff62a1c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 10:51:48 -0700 Subject: [PATCH 124/480] #617 Fix ForceOccupied/ForceVacant methods --- .../GlsOccupancySensorBaseController.cs | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 045a4143..35ca2ae7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -314,14 +314,40 @@ namespace PepperDash.Essentials.Core OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease; } - public void ForceOccupied() + /// + /// Pulse ForceOccupied on the sensor for .5 seconds + /// + public void ForceOccupied() + { + CrestronInvoke.BeginInvoke((o) => + { + ForceOccupied(true); + CrestronEnvironment.Sleep(500); + ForceOccupied(false); + }); + } + + public void ForceOccupied(bool value) { - OccSensor.ForceOccupied.BoolValue = true; + OccSensor.ForceOccupied.BoolValue = value; } - public void ForceVacant() + /// + /// Pulse ForceVacant on the sensor for .5 seconds + /// + public void ForceVacant() + { + CrestronInvoke.BeginInvoke((o) => + { + ForceVacant(true); + CrestronEnvironment.Sleep(500); + ForceVacant(false); + }); + } + + public void ForceVacant(bool value) { - OccSensor.ForceVacant.BoolValue = true; + OccSensor.ForceVacant.BoolValue = value; } public void EnableRawStates(bool state) @@ -462,8 +488,8 @@ namespace PepperDash.Essentials.Core GlsOccupancySensorBaseJoinMap joinMap) { // Occupied status - trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); - trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); + trilist.SetBoolSigAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied); + trilist.SetBoolSigAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant); occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]); occController.RoomIsOccupiedFeedback.LinkComplementInputSig( trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]); From 1da481a8db2203b0f45dd82525f0a1aebd840e67 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 10:53:39 -0700 Subject: [PATCH 125/480] #619 Correct feedback for linking to API --- .../Occupancy/GlsOccupancySensorBaseController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs index 35ca2ae7..53db1716 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorBaseController.cs @@ -460,7 +460,7 @@ namespace PepperDash.Essentials.Core // Ultrasonic B Sensor trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true)); trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false)); - odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); + odtOccController.UltrasonicBEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]); // US Sensitivity in Occupied State trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, From ca497c8f47ff7ffacbc29f84ee6b7f2620ad828e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 10:55:01 -0700 Subject: [PATCH 126/480] #620 Fix Join Map Comment --- .../Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs index cc76e793..72cb1433 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs @@ -154,7 +154,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("PirSensitivityInVacantState")] public JoinDataComplete PirSensitivityInVacantState = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 }, - new JoinMetadata { Description = "Occ Sensor Ultrasonic Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Occ Sensor PIR Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog }); [JoinName("Name")] public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, From 43297c03417b039d30af05d2f647a538224bb8d4 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 11:53:07 -0700 Subject: [PATCH 127/480] #618 Fix issue with wrong field getting sent to a method --- .../Occupancy/GlsOdtOccupancySensorController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs index 35ecb397..d5e18280 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOdtOccupancySensorController.cs @@ -43,7 +43,7 @@ namespace PepperDash.Essentials.Core RegisterCrestronGenericBase(_occSensor); - RegisterGlsOccupancySensorBaseController(OccSensor); + RegisterGlsOccupancySensorBaseController(_occSensor); AndWhenVacatedFeedback = new BoolFeedback(() => _occSensor.AndWhenVacatedFeedback.BoolValue); From 4ab3cdb1ff193e4b3e8cf4fdb9d9e1108b46c5b8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 13:03:23 -0700 Subject: [PATCH 128/480] #451 Fix namespace issues --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 2 +- .../JoinMaps/GlsPartitionSensorJoinMap.cs | 140 +++ .../JoinMaps/VideoCodecControllerJoinMap.cs | 892 ++++++++++++++++++ .../DeviceTypeInterfaces/IHasBranding.cs | 14 +- .../DeviceTypeInterfaces/IHasPhoneDialing.cs | 19 +- .../ILanguageDefinition.cs | 19 +- .../DeviceTypeInterfaces/ILanguageProvider.cs | 16 +- .../DeviceTypeInterfaces/LanguageLabel.cs | 17 +- .../Devices/GenericIRController.cs | 135 ++- .../Factory/ReadyEventArgs.cs | 22 +- .../Gateways/CenRfgwController.cs | 2 - .../GlsPartitionSensorController.cs | 2 +- .../Queues/ComsMessage.cs | 74 +- .../Queues/GenericQueue.cs | 246 ++++- .../PepperDashEssentialsBase/Queues/IQueue.cs | 12 +- .../Queues/IQueueMessage.cs | 13 +- .../Queues/ProcessStringMessage.cs | 46 +- .../Queues/StringResponseProcessor.cs | 106 ++- .../Remotes/Hrxx0WirelessRemoteController.cs | 2 +- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 3 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 1 - 21 files changed, 1759 insertions(+), 24 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 48ee7285..d6b58e5b 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Common.AudioCodec; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs index 74402689..08f8400e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs @@ -1,8 +1,148 @@ using System; using PepperDash.Essentials.Core; +namespace PepperDash.Essentials.Core.Bridges.JoinMaps +{ + public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced + { + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("Enable")] + public JoinDataComplete Enable = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Enable", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PartitionSensed")] + public JoinDataComplete PartitionSensed = new JoinDataComplete( + new JoinData + { + JoinNumber = 3, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Partition Sensed", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PartitionNotSensed")] + public JoinDataComplete PartitionNotSensed = new JoinDataComplete( + new JoinData + { + JoinNumber = 4, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Partition Not Sensed", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncreaseSensitivity")] + public JoinDataComplete IncreaseSensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 6, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Increase Sensitivity", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DecreaseSensitivity")] + public JoinDataComplete DecreaseSensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 7, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Decrease Sensitivity", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Sensitivity")] + public JoinDataComplete Sensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Sensitivity", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + /// + /// Constructor to use when instantiating this Join Map without inheriting from it + /// + /// Join this join map will start at + public GlsPartitionSensorJoinMap(uint joinStart) + : this(joinStart, typeof(GlsPartitionSensorJoinMap)) + { + + } + + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + protected GlsPartitionSensorJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + + } + } +} + namespace PepperDash_Essentials_Core.Bridges.JoinMaps { + [Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")] public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced { [JoinName("IsOnline")] diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 8054a077..cce0f7d5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -1,8 +1,900 @@ using System; using PepperDash.Essentials.Core; +namespace PepperDash.Essentials.Core.Bridges.JoinMaps +{ + public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced + { + #region Status + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Device is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Direction", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = + new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Layout Toggle", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraLayoutStringFb")] + public JoinDataComplete CameraLayoutStringFb = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Layout Fb", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = + new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Auto", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = + new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Manual", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = + new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = + new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Number Select/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = + new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Left", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = + new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Right", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPresetNames")] + public JoinDataComplete CameraPresetNames = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Names - XSIG, max of 15", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraPresetSelect")] + public JoinDataComplete CameraPresetSelect = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Select", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPresetSave")] + public JoinDataComplete CameraPresetSave = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Save Selected Preset", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Self View Toggle/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = + new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Auto Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = + new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Off Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = + new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = + new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = + new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom In", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = + new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom Out", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallData = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Dial String", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentParticipants")] + public JoinDataComplete CurrentParticipants = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata() + { + Description = "Current Participants XSig", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentSource")] + public JoinDataComplete CurrentSource = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Source", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DialMeeting1")] + public JoinDataComplete DialMeeting1 = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join first meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting2")] + public JoinDataComplete DialMeeting2 = + new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join second meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting3")] + public JoinDataComplete DialMeeting3 = + new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join third meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = + new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial selected directory line", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntries")] + public JoinDataComplete DirectoryEntries = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Entries - XSig, 255 entries", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Selected Entry Is Contact FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = + new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = + new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = + new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go back one directory level", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryHasChanged")] + public JoinDataComplete DirectoryHasChanged = + new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory has changed FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory is on Root FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Line Selected FB", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = + new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go to Directory Root", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Row Count FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search Busy FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Select Row", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = + new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Folder Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("0")] + public JoinDataComplete Dtmf0 = + new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 0", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("1")] + public JoinDataComplete Dtmf1 = + new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 1", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("2")] + public JoinDataComplete Dtmf2 = + new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 2", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("3")] + public JoinDataComplete Dtmf3 = + new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 3", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("4")] + public JoinDataComplete Dtmf4 = + new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 4", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("5")] + public JoinDataComplete Dtmf5 = + new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 5", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("6")] + public JoinDataComplete Dtmf6 = + new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 6", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("7")] + public JoinDataComplete Dtmf7 = + new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 7", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("8")] + public JoinDataComplete Dtmf8 = + new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 8", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("9")] + public JoinDataComplete Dtmf9 = + new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 9", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("#")] + public JoinDataComplete DtmfPound = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF #", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("*")] + public JoinDataComplete DtmfStar = + new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF *", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndCall")] + public JoinDataComplete EndCall = + new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("HookState")] + public JoinDataComplete HookState = + new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Hook State", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Answer Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = + new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Reject Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("ManualDial")] + public JoinDataComplete ManualDial = + new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial manual string", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Meeting Count Fb")] + public JoinDataComplete MeetingCount = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Meeting Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteToggle")] + public JoinDataComplete MicMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MinutesBeforeMeetingStart")] + public JoinDataComplete MinutesBeforeMeetingStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Minutes before meeting start that a meeting is joinable", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ParticipantCount")] + public JoinDataComplete ParticipantCount = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Participant Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("Schedule")] + public JoinDataComplete Schedule = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Schedule Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("AutoShareWhileInCall")] + public JoinDataComplete SourceShareAutoStart = + new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, + new JoinMetadata + { + Description = "When high, will autostart sharing when a call is joined", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareEnd")] + public JoinDataComplete SourceShareEnd = + new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Stop Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareStart")] + public JoinDataComplete SourceShareStart = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Start Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("RecievingContent")] + public JoinDataComplete RecievingContent = + new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Recieving content from the far end", + JoinType = eJoinType.Digital, + JoinCapabilities = eJoinCapabilities.ToSIMPL + }); + + [JoinName("SelfviewPosition")] + public JoinDataComplete SelfviewPosition = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SelfviewPositionFb")] + public JoinDataComplete SelfviewPositionFb = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, + new JoinMetadata + { + Description = "Speed Dial", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("UpdateMeetings")] + public JoinDataComplete UpdateMeetings = + new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Update Meetings", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeDown")] + public JoinDataComplete VolumeDown = + new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeLevel")] + public JoinDataComplete VolumeLevel = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Level", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("VolumeMuteOff")] + public JoinDataComplete VolumeMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOn")] + public JoinDataComplete VolumeMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteToggle")] + public JoinDataComplete VolumeMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeUp")] + public JoinDataComplete VolumeUp = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialPhoneCall")] + public JoinDataComplete DialPhone = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneHookState")] + public JoinDataComplete PhoneHookState = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndPhoneCall")] + public JoinDataComplete HangUpPhone = + new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up PHone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneString")] + public JoinDataComplete PhoneDialString = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Phone Dial String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + public VideoCodecControllerJoinMap(uint joinStart) + : base(joinStart, typeof(VideoCodecControllerJoinMap)) + { + } + + public VideoCodecControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} + namespace PepperDash_Essentials_Core.Bridges.JoinMaps { + [Obsolete("Use PepperDash.Essentials.Core.Bridges.JoinMaps")] public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced { #region Status diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs index d5c95c47..63f4917a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs @@ -1,8 +1,20 @@ -namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +using System; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { public interface IHasBranding { bool BrandingEnabled { get; } void InitializeBranding(string roomKey); } +} + +namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +{ + [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] + public interface IHasBranding + { + bool BrandingEnabled { get; } + void InitializeBranding(string roomKey); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs index 2b7af8ad..7f75adec 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs @@ -1,6 +1,7 @@ -using PepperDash.Essentials.Core; +using System; +using PepperDash.Essentials.Core; -namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { public interface IHasPhoneDialing { @@ -11,4 +12,18 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces void EndPhoneCall(); void SendDtmfToPhone(string digit); } +} + +namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +{ + [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] + public interface IHasPhoneDialing + { + BoolFeedback PhoneOffHookFeedback { get; } + StringFeedback CallerIdNameFeedback { get; } + StringFeedback CallerIdNumberFeedback { get; } + void DialPhoneCall(string number); + void EndPhoneCall(); + void SendDtmfToPhone(string digit); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs index f124240d..abf138a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { public interface ILanguageDefinition { @@ -15,4 +15,21 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces List DestinationGroupNames { get; set; } List RoomNames { get; set; } } +} + +namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +{ + [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] + public interface ILanguageDefinition + { + string LocaleName { get; set; } + string FriendlyName { get; set; } + bool Enable { get; set; } + List UiLabels { get; set; } + List Sources { get; set; } + List Destinations { get; set; } + List SourceGroupNames { get; set; } + List DestinationGroupNames { get; set; } + List RoomNames { get; set; } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs index 2ae483f6..dd48723d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs @@ -1,9 +1,21 @@ using System; -using System.Collections.Generic; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + + public interface ILanguageProvider + { + ILanguageDefinition CurrentLanguage { get; set; } + + event EventHandler CurrentLanguageChanged; + } + +} namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { - public interface ILanguageProvider + [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] + public interface ILanguageProvider { ILanguageDefinition CurrentLanguage { get; set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs index 345da2ed..c7d26722 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs @@ -1,6 +1,7 @@ -using PepperDash.Core; +using System; +using PepperDash.Core; -namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { public class LanguageLabel { @@ -9,4 +10,16 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces public string DisplayText { get; set; } public uint JoinNumber { get; set; } } +} + +namespace PepperDash_Essentials_Core.DeviceTypeInterfaces +{ + [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] + public class LanguageLabel + { + public string Key { get; set; } + public string Description { get; set; } + public string DisplayText { get; set; } + public uint JoinNumber { get; set; } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs index bf4544de..b0a40a47 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs @@ -7,7 +7,7 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; -namespace PepperDash_Essentials_Core.Devices +namespace PepperDash.Essentials.Core.Devices { public class GenericIrController: EssentialsBridgeableDevice { @@ -133,6 +133,139 @@ namespace PepperDash_Essentials_Core.Devices return new GenericIrController(dc.Key, dc.Name, irPort); } + #endregion + } +} + +namespace PepperDash_Essentials_Core.Devices +{ + [Obsolete("Use PepperDash.Essentials.Core.Devices")] + public class GenericIrController : EssentialsBridgeableDevice + { + //data storage for bridging + private BasicTriList _trilist; + private uint _joinStart; + private string _joinMapKey; + private EiscApiAdvanced _bridge; + + private readonly IrOutputPortController _port; + + public string[] IrCommands { get { return _port.IrFileCommands; } } + + public GenericIrController(string key, string name, IrOutputPortController irPort) + : base(key, name) + { + _port = irPort; + + if (_port == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "IR Port is null, device will not function"); + return; + } + DeviceManager.AddDevice(_port); + + _port.DriverLoaded.OutputChange += DriverLoadedOnOutputChange; + } + + private void DriverLoadedOnOutputChange(object sender, FeedbackEventArgs args) + { + if (!args.BoolValue) + { + return; + } + + if (_trilist == null || _bridge == null) + { + return; + } + + LinkToApi(_trilist, _joinStart, _joinMapKey, _bridge); + } + + #region Overrides of EssentialsBridgeableDevice + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + //if driver isn't loaded yet, store the variables until it is loaded, then call the LinkToApi method again + if (!_port.DriverIsLoaded) + { + _trilist = trilist; + _joinStart = joinStart; + _joinMapKey = joinMapKey; + _bridge = bridge; + return; + } + + var joinMap = new GenericIrControllerJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + for (uint i = 0; i < _port.IrFileCommands.Length; i++) + { + var cmd = _port.IrFileCommands[i]; + var joinData = new JoinDataComplete(new JoinData { JoinNumber = i, JoinSpan = 1 }, + new JoinMetadata + { + Description = cmd, + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + joinData.SetJoinOffset(joinStart); + + joinMap.Joins.Add(cmd, joinData); + + trilist.SetBoolSigAction(joinData.JoinNumber, (b) => Press(cmd, b)); + } + + joinMap.PrintJoinMapInfo(); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + } + + #endregion + + public void Press(string command, bool pressRelease) + { + _port.PressRelease(command, pressRelease); + } + } + + public sealed class GenericIrControllerJoinMap : JoinMapBaseAdvanced + { + public GenericIrControllerJoinMap(uint joinStart) + : base(joinStart) + { + } + } + + public class GenericIrControllerFactory : EssentialsDeviceFactory + { + public GenericIrControllerFactory() + { + TypeNames = new List { "genericIrController" }; + } + #region Overrides of EssentialsDeviceFactory + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new Generic IR Controller Device"); + + var irPort = IRPortHelper.GetIrOutputPortController(dc); + + return new GenericIrController(dc.Key, dc.Name, irPort); + } + #endregion } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs index 89c0b7b3..de7bc3a5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; -namespace PepperDash_Essentials_Core +namespace PepperDash.Essentials.Core { public class IsReadyEventArgs : EventArgs { @@ -16,6 +16,26 @@ namespace PepperDash_Essentials_Core } } + public interface IHasReady + { + event EventHandler IsReadyEvent; + bool IsReady { get; } + } +} + +namespace PepperDash_Essentials_Core +{ + [Obsolete("Use PepperDash.Essentials.Core")] + public class IsReadyEventArgs : EventArgs + { + public bool IsReady { get; set; } + + public IsReadyEventArgs(bool data) + { + IsReady = data; + } + } + public interface IHasReady { event EventHandler IsReadyEvent; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs index fb7968d9..03e8f51d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Gateways/CenRfgwController.cs @@ -10,9 +10,7 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; -using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; -using PepperDash_Essentials_Core; namespace PepperDash.Essentials.Core diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 7ade8ba5..b0b58f34 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -4,7 +4,7 @@ using Crestron.SimplSharpPro.GeneralIO; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core.Bridges; -using PepperDash_Essentials_Core.Bridges.JoinMaps; +using PepperDash.Essentials.Core.Bridges.JoinMaps; using System; using System.Collections.Generic; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs index fce6291d..3c01032e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs @@ -1,7 +1,7 @@ using System; using PepperDash.Core; -namespace PepperDash_Essentials_Core.Queues +namespace PepperDash.Essentials.Core.Queues { /// /// IBasicCommunication Message for IQueue @@ -62,6 +62,78 @@ namespace PepperDash_Essentials_Core.Queues } } + /// + /// Shows either the byte[] or string to be sent + /// + public override string ToString() + { + return _bytes != null ? _bytes.ToString() : _string; + } + } +} + +namespace PepperDash_Essentials_Core.Queues +{ + /// + /// IBasicCommunication Message for IQueue + /// + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public class ComsMessage : IQueueMessage + { + private readonly byte[] _bytes; + private readonly IBasicCommunication _coms; + private readonly string _string; + private readonly bool _isByteMessage; + + /// + /// Constructor for a string message + /// + /// IBasicCommunication to send the message + /// Message to send + public ComsMessage(IBasicCommunication coms, string message) + { + Validate(coms, message); + _coms = coms; + _string = message; + } + + /// + /// Constructor for a byte message + /// + /// IBasicCommunication to send the message + /// Message to send + public ComsMessage(IBasicCommunication coms, byte[] message) + { + Validate(coms, message); + _coms = coms; + _bytes = message; + _isByteMessage = true; + } + + private void Validate(IBasicCommunication coms, object message) + { + if (coms == null) + throw new ArgumentNullException("coms"); + + if (message == null) + throw new ArgumentNullException("message"); + } + + /// + /// Dispatchs the string/byte[] to the IBasicCommunication specified + /// + public void Dispatch() + { + if (_isByteMessage) + { + _coms.SendBytes(_bytes); + } + else + { + _coms.SendText(_string); + } + } + /// /// Shows either the byte[] or string to be sent /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index e1b175a6..1fcc497c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -3,7 +3,7 @@ using Crestron.SimplSharp; using Crestron.SimplSharpPro.CrestronThread; using PepperDash.Core; -namespace PepperDash_Essentials_Core.Queues +namespace PepperDash.Essentials.Core.Queues { /// /// Threadsafe processing of queued items with pacing if required @@ -236,6 +236,250 @@ namespace PepperDash_Essentials_Core.Queues Dispose(false); } + /// + /// Key + /// + public string Key + { + get { return _key; } + } + } +} + +namespace PepperDash_Essentials_Core.Queues +{ + /// + /// Threadsafe processing of queued items with pacing if required + /// + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public class GenericQueue : IQueue + { + private readonly string _key; + protected readonly CrestronQueue _queue; + protected readonly Thread _worker; + protected readonly CEvent _waitHandle = new CEvent(); + + private bool _delayEnabled; + private int _delayTime; + + private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority; + + /// + /// If the instance has been disposed. + /// + public bool Disposed { get; private set; } + + /// + /// Returns the capacity of the CrestronQueue (fixed Size property) + /// + public int QueueCapacity + { + get + { + return _queue.Size; + } + } + + /// + /// Returns the number of elements currently in the CrestronQueue + /// + public int QueueCount + { + get + { + return _queue.Count; + } + } + + /// + /// Constructor with no thread priority + /// + /// + public GenericQueue(string key) + : this(key, _defaultPriority, 0, 0) + { + } + + /// + /// Constructor with queue size + /// + /// + /// Fixed size for the queue to hold + public GenericQueue(string key, int capacity) + : this(key, _defaultPriority, capacity, 0) + { + } + + /// + /// Constructor for generic queue with no pacing + /// + /// Key + /// Pacing in ms between actions + public GenericQueue(int pacing, string key) + : this(key, _defaultPriority, 0, pacing) + { + } + + /// + /// Constructor with pacing and capacity + /// + /// + /// + /// + public GenericQueue(string key, int pacing, int capacity) + : this(key, _defaultPriority, capacity, pacing) + { + } + + /// + /// Constructor with pacing and priority + /// + /// + /// + /// + public GenericQueue(string key, int pacing, Thread.eThreadPriority priority) + : this(key, priority, 0, pacing) + { + } + + /// + /// Constructor with pacing, priority and capacity + /// + /// + /// + /// + public GenericQueue(string key, Thread.eThreadPriority priority, int capacity) + : this(key, priority, capacity, 0) + { + } + + /// + /// Constructor with pacing, priority and capacity + /// + /// + /// + /// + /// + public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity) + : this(key, priority, capacity, pacing) + { + } + + /// + /// Constructor for generic queue with no pacing + /// + /// Key + /// + private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) + { + _key = key; + int cap = 25; // sets default + if (capacity > 0) + { + cap = capacity; // overrides default + } + _queue = new CrestronQueue(cap); + _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) + { + Priority = priority + }; + + SetDelayValues(pacing); + } + + private void SetDelayValues(int pacing) + { + _delayEnabled = pacing > 0; + _delayTime = pacing; + + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; + + Dispose(); + }; + } + + /// + /// Thread callback + /// + /// The action used to process dequeued items + /// Null when the thread is exited + private object ProcessQueue(object obj) + { + while (true) + { + IQueueMessage item = null; + + if (_queue.Count > 0) + { + item = _queue.Dequeue(); + if (item == null) + break; + } + if (item != null) + { + try + { + Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString()); + item.Dispatch(); + + if (_delayEnabled) + Thread.Sleep(_delayTime); + } + catch (Exception ex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace); + } + } + else _waitHandle.Wait(); + } + + return null; + } + + public void Enqueue(IQueueMessage item) + { + _queue.Enqueue(item); + _waitHandle.Set(); + } + + /// + /// Disposes the thread and cleans up resources. Thread cannot be restarted once + /// disposed. + /// + public void Dispose() + { + Dispose(true); + CrestronEnvironment.GC.SuppressFinalize(this); + } + + /// + /// Actually does the disposing. If you override this method, be sure to either call the base implementation + /// or clean up all the resources yourself. + /// + /// set to true unless called from finalizer + protected void Dispose(bool disposing) + { + if (Disposed) + return; + + if (disposing) + { + Enqueue(null); + _worker.Join(); + _waitHandle.Close(); + } + + Disposed = true; + } + + ~GenericQueue() + { + Dispose(false); + } + /// /// Key /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs index 852542d5..15803330 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs @@ -5,11 +5,21 @@ using System.Text; using Crestron.SimplSharp; using PepperDash.Core; -namespace PepperDash_Essentials_Core.Queues +namespace PepperDash.Essentials.Core.Queues { public interface IQueue : IKeyed, IDisposable where T : class { void Enqueue(T item); bool Disposed { get; } } +} + +namespace PepperDash_Essentials_Core.Queues +{ + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public interface IQueue : IKeyed, IDisposable where T : class + { + void Enqueue(T item); + bool Disposed { get; } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs index ee0d87d2..8ffd4d96 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs @@ -1,7 +1,18 @@ -namespace PepperDash_Essentials_Core.Queues +using System; + +namespace PepperDash.Essentials.Core.Queues { public interface IQueueMessage { void Dispatch(); } +} + +namespace PepperDash_Essentials_Core.Queues +{ + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public interface IQueueMessage + { + void Dispatch(); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs index a15f7231..d8ea4ada 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs @@ -1,6 +1,6 @@ using System; -namespace PepperDash_Essentials_Core.Queues +namespace PepperDash.Essentials.Core.Queues { /// /// Message class for processing strings via an IQueue @@ -32,6 +32,50 @@ namespace PepperDash_Essentials_Core.Queues _action(_message); } + /// + /// To string + /// + /// The current message + public override string ToString() + { + return _message ?? String.Empty; + } + } +} + +namespace PepperDash_Essentials_Core.Queues +{ + /// + /// Message class for processing strings via an IQueue + /// + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public class ProcessStringMessage : IQueueMessage + { + private readonly Action _action; + private readonly string _message; + + /// + /// Constructor + /// + /// Message to be processed + /// Action to invoke on the message + public ProcessStringMessage(string message, Action action) + { + _message = message; + _action = action; + } + + /// + /// Processes the string with the given action + /// + public void Dispatch() + { + if (_action == null || String.IsNullOrEmpty(_message)) + return; + + _action(_message); + } + /// /// To string /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs index 7f6477a3..e2db5d72 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs @@ -2,7 +2,7 @@ using Crestron.SimplSharp; using PepperDash.Core; -namespace PepperDash_Essentials_Core.Queues +namespace PepperDash.Essentials.Core.Queues { public sealed class StringResponseProcessor : IKeyed, IDisposable { @@ -98,6 +98,110 @@ namespace PepperDash_Essentials_Core.Queues /// public bool Disposed { get; private set; } + ~StringResponseProcessor() + { + Dispose(false); + } + } +} + +namespace PepperDash_Essentials_Core.Queues +{ + [Obsolete("Use PepperDash.Essentials.Core.Queues")] + public sealed class StringResponseProcessor : IKeyed, IDisposable + { + private readonly Action _processStringAction; + private readonly IQueue _queue; + private readonly IBasicCommunication _coms; + private readonly CommunicationGather _gather; + + private StringResponseProcessor(string key, Action processStringAction) + { + _processStringAction = processStringAction; + _queue = new GenericQueue(key); + + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; + + Dispose(); + }; + } + + /// + /// Constructor that builds an instance and subscribes to coms TextReceived for processing + /// + /// Com port to process strings from + /// Action to process the incoming strings + public StringResponseProcessor(IBasicCommunication coms, Action processStringAction) + : this(coms.Key, processStringAction) + { + _coms = coms; + coms.TextReceived += OnResponseReceived; + } + + /// + /// Constructor that builds an instance and subscribes to gather Line Received for processing + /// + /// Gather to process strings from + /// Action to process the incoming strings + public StringResponseProcessor(CommunicationGather gather, Action processStringAction) + : this(gather.Port.Key, processStringAction) + { + _gather = gather; + gather.LineReceived += OnResponseReceived; + } + + private void OnResponseReceived(object sender, GenericCommMethodReceiveTextArgs args) + { + _queue.Enqueue(new ProcessStringMessage(args.Text, _processStringAction)); + } + + /// + /// Key + /// + public string Key + { + get { return _queue.Key; } + } + + /// + /// Disposes the instance and cleans up resources. + /// + public void Dispose() + { + Dispose(true); + CrestronEnvironment.GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (Disposed) + return; + + if (disposing) + { + if (_coms != null) + _coms.TextReceived -= OnResponseReceived; + + if (_gather != null) + { + _gather.LineReceived -= OnResponseReceived; + _gather.Stop(); + } + + _queue.Dispose(); + } + + Disposed = true; + } + + /// + /// If the instance has been disposed or not. If it has, you can not use it anymore + /// + public bool Disposed { get; private set; } + ~StringResponseProcessor() { Dispose(false); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs index 161cba45..e4fcab5b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Remotes/Hrxx0WirelessRemoteController.cs @@ -83,7 +83,7 @@ namespace PepperDash.Essentials.Core } } - void _gateway_IsReadyEvent(object sender, PepperDash_Essentials_Core.IsReadyEventArgs e) + void _gateway_IsReadyEvent(object sender, IsReadyEventArgs e) { if (e.IsReady != true) return; _remote = GetHr1x0WirelessRemote(_config); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 4d074678..af7233fb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -18,8 +18,7 @@ using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; -using PepperDash_Essentials_Core.Queues; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Queues; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 84617c6d..42a389a7 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -17,7 +17,6 @@ using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { From 52c96cc2c3b2ef4971503e9e575188a247b525b4 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 15:40:18 -0700 Subject: [PATCH 129/480] fix it so that wrong namespace classes inherit from right namespace classes --- .../JoinMaps/GlsPartitionSensorJoinMap.cs | 140 +-- .../JoinMaps/VideoCodecControllerJoinMap.cs | 798 +----------------- .../DeviceTypeInterfaces/IHasBranding.cs | 5 +- .../DeviceTypeInterfaces/IHasPhoneDialing.cs | 9 +- .../ILanguageDefinition.cs | 11 +- .../DeviceTypeInterfaces/ILanguageProvider.cs | 5 +- .../DeviceTypeInterfaces/LanguageLabel.cs | 6 +- .../Devices/GenericIRController.cs | 133 --- .../Factory/ReadyEventArgs.cs | 13 +- .../Queues/ComsMessage.cs | 50 +- .../Queues/GenericQueue.cs | 156 +--- .../PepperDashEssentialsBase/Queues/IQueue.cs | 4 +- .../Queues/IQueueMessage.cs | 3 +- .../Queues/ProcessStringMessage.cs | 31 +- .../Queues/StringResponseProcessor.cs | 4 +- .../VideoCodec/VideoCodecBase.cs | 3 +- 16 files changed, 41 insertions(+), 1330 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs index 08f8400e..b7af7cdf 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs @@ -142,140 +142,20 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps namespace PepperDash_Essentials_Core.Bridges.JoinMaps { + /// + /// + /// [Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")] - public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced + public class GlsPartitionSensorJoinMap : PepperDash.Essentials.Core.Bridges.JoinMaps.GlsPartitionSensorJoinMap { - [JoinName("IsOnline")] - public JoinDataComplete IsOnline = new JoinDataComplete( - new JoinData - { - JoinNumber = 1, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Is Online", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Name")] - public JoinDataComplete Name = new JoinDataComplete( - new JoinData - { - JoinNumber = 1, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("Enable")] - public JoinDataComplete Enable = new JoinDataComplete( - new JoinData - { - JoinNumber = 2, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Enable", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PartitionSensed")] - public JoinDataComplete PartitionSensed = new JoinDataComplete( - new JoinData - { - JoinNumber = 3, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Partition Sensed", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PartitionNotSensed")] - public JoinDataComplete PartitionNotSensed = new JoinDataComplete( - new JoinData - { - JoinNumber = 4, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Partition Not Sensed", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncreaseSensitivity")] - public JoinDataComplete IncreaseSensitivity = new JoinDataComplete( - new JoinData - { - JoinNumber = 6, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Increase Sensitivity", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DecreaseSensitivity")] - public JoinDataComplete DecreaseSensitivity = new JoinDataComplete( - new JoinData - { - JoinNumber = 7, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Decrease Sensitivity", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Sensitivity")] - public JoinDataComplete Sensitivity = new JoinDataComplete( - new JoinData - { - JoinNumber = 2, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Sensitivity", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - /// - /// Constructor to use when instantiating this Join Map without inheriting from it - /// - /// Join this join map will start at - public GlsPartitionSensorJoinMap(uint joinStart) - : this(joinStart, typeof (GlsPartitionSensorJoinMap)) - { - - } - - /// - /// Constructor to use when extending this Join map - /// - /// Join this join map will start at - /// Type of the child join map - protected GlsPartitionSensorJoinMap(uint joinStart, Type type) - : base(joinStart, type) + public GlsPartitionSensorJoinMap(uint joinStart) + : this(joinStart, typeof(GlsPartitionSensorJoinMap)) { + } + + protected GlsPartitionSensorJoinMap(uint joinStart, Type type) : base(joinStart, type) + { } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index cce0f7d5..2651f929 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -895,804 +895,10 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps namespace PepperDash_Essentials_Core.Bridges.JoinMaps { [Obsolete("Use PepperDash.Essentials.Core.Bridges.JoinMaps")] - public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced + public class VideoCodecControllerJoinMap : PepperDash.Essentials.Core.Bridges.JoinMaps.VideoCodecControllerJoinMap { - #region Status - [JoinName("IsOnline")] public JoinDataComplete IsOnline = - new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 1}, - new JoinMetadata - { - Description = "Device is Online", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - #endregion - - [JoinName("CallDirection")] public JoinDataComplete CallDirection = - new JoinDataComplete(new JoinData {JoinNumber = 22, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Call Direction", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraLayout")] public JoinDataComplete CameraLayout = - new JoinDataComplete(new JoinData {JoinNumber = 142, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Layout Toggle", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraLayoutStringFb")] public JoinDataComplete CameraLayoutStringFb = - new JoinDataComplete(new JoinData {JoinNumber = 141, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Layout Fb", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraModeAuto")] public JoinDataComplete CameraModeAuto = - new JoinDataComplete(new JoinData {JoinNumber = 131, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Mode Auto", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeManual")] public JoinDataComplete CameraModeManual = - new JoinDataComplete(new JoinData {JoinNumber = 132, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Mode Manual", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeOff")] public JoinDataComplete CameraModeOff = - new JoinDataComplete(new JoinData {JoinNumber = 133, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Mode Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraNumberSelect")] public JoinDataComplete CameraNumberSelect = - new JoinDataComplete(new JoinData {JoinNumber = 60, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Number Select/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPanLeft")] public JoinDataComplete CameraPanLeft = - new JoinDataComplete(new JoinData {JoinNumber = 113, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Pan Left", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPanRight")] public JoinDataComplete CameraPanRight = - new JoinDataComplete(new JoinData {JoinNumber = 114, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Pan Right", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPresetNames")] public JoinDataComplete CameraPresetNames = - new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Preset Names - XSIG, max of 15", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraPresetSelect")] public JoinDataComplete CameraPresetSelect = - new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Preset Select", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPresetSave")] public JoinDataComplete CameraPresetSave = - new JoinDataComplete(new JoinData {JoinNumber = 121, JoinSpan = 1}, - new JoinMetadata - { - Description = "Save Selected Preset", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSelfView")] public JoinDataComplete CameraSelfView = - new JoinDataComplete(new JoinData {JoinNumber = 141, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Self View Toggle/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsAutoMode")] public JoinDataComplete CameraSupportsAutoMode = - new JoinDataComplete(new JoinData {JoinNumber = 143, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Supports Auto Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsOffMode")] public JoinDataComplete CameraSupportsOffMode = - new JoinDataComplete(new JoinData {JoinNumber = 144, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Supports Off Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltDown")] public JoinDataComplete CameraTiltDown = - new JoinDataComplete(new JoinData {JoinNumber = 112, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Tilt Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltUp")] public JoinDataComplete CameraTiltUp = - new JoinDataComplete(new JoinData {JoinNumber = 111, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Tilt Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomIn")] public JoinDataComplete CameraZoomIn = - new JoinDataComplete(new JoinData {JoinNumber = 115, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Zoom In", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomOut")] public JoinDataComplete CameraZoomOut = - new JoinDataComplete(new JoinData {JoinNumber = 116, JoinSpan = 1}, - new JoinMetadata - { - Description = "Camera Zoom Out", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CurrentCallName")] public JoinDataComplete CurrentCallData = - new JoinDataComplete(new JoinData {JoinNumber = 2, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Call Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentDialString")] public JoinDataComplete CurrentDialString = - new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Dial String", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentParticipants")] public JoinDataComplete CurrentParticipants = - new JoinDataComplete(new JoinData {JoinNumber = 151, JoinSpan = 1}, - new JoinMetadata() - { - Description = "Current Participants XSig", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentSource")] public JoinDataComplete CurrentSource = - new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Source", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DialMeeting1")] public JoinDataComplete DialMeeting1 = - new JoinDataComplete(new JoinData {JoinNumber = 161, JoinSpan = 1}, - new JoinMetadata - { - Description = "Join first meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting2")] - public JoinDataComplete DialMeeting2 = - new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join second meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting3")] - public JoinDataComplete DialMeeting3 = - new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join third meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryDialSelectedLine")] public JoinDataComplete DirectoryDialSelectedLine = - new JoinDataComplete(new JoinData {JoinNumber = 106, JoinSpan = 1}, - new JoinMetadata - { - Description = "Dial selected directory line", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntries")] public JoinDataComplete DirectoryEntries = - new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Entries - XSig, 255 entries", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntryIsContact")] public JoinDataComplete DirectoryEntryIsContact = - new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Selected Entry Is Contact FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntrySelectedName")] public JoinDataComplete DirectoryEntrySelectedName = - new JoinDataComplete(new JoinData {JoinNumber = 356, JoinSpan = 1}, - new JoinMetadata - { - Description = "Selected Directory Entry Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntrySelectedNumber")] public JoinDataComplete DirectoryEntrySelectedNumber = - new JoinDataComplete(new JoinData {JoinNumber = 357, JoinSpan = 1}, - new JoinMetadata - { - Description = "Selected Directory Entry Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryFolderBack")] public JoinDataComplete DirectoryFolderBack = - new JoinDataComplete(new JoinData {JoinNumber = 105, JoinSpan = 1}, - new JoinMetadata - { - Description = "Go back one directory level", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryHasChanged")] public JoinDataComplete DirectoryHasChanged = - new JoinDataComplete(new JoinData {JoinNumber = 103, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory has changed FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryIsRoot")] public JoinDataComplete DirectoryIsRoot = - new JoinDataComplete(new JoinData {JoinNumber = 102, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory is on Root FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryLineSelected")] public JoinDataComplete DirectoryLineSelected = - new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Line Selected FB", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRoot")] public JoinDataComplete DirectoryRoot = - new JoinDataComplete(new JoinData {JoinNumber = 104, JoinSpan = 1}, - new JoinMetadata - { - Description = "Go to Directory Root", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRowCount")] public JoinDataComplete DirectoryRowCount = - new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Row Count FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySearchBusy")] public JoinDataComplete DirectorySearchBusy = - new JoinDataComplete(new JoinData {JoinNumber = 100, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Search Busy FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectorySearchString")] public JoinDataComplete DirectorySearchString = - new JoinDataComplete(new JoinData {JoinNumber = 100, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Search String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectorySelectRow")] public JoinDataComplete DirectorySelectRow = - new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1}, - new JoinMetadata - { - Description = "Directory Select Row", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySelectedFolderName")] public JoinDataComplete DirectorySelectedFolderName = - new JoinDataComplete(new JoinData {JoinNumber = 358, JoinSpan = 1}, - new JoinMetadata - { - Description = "Selected Directory Folder Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("0")] public JoinDataComplete Dtmf0 = - new JoinDataComplete(new JoinData {JoinNumber = 20, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 0", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("1")] public JoinDataComplete Dtmf1 = - new JoinDataComplete(new JoinData {JoinNumber = 11, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 1", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("2")] public JoinDataComplete Dtmf2 = - new JoinDataComplete(new JoinData {JoinNumber = 12, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 2", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("3")] public JoinDataComplete Dtmf3 = - new JoinDataComplete(new JoinData {JoinNumber = 13, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 3", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("4")] public JoinDataComplete Dtmf4 = - new JoinDataComplete(new JoinData {JoinNumber = 14, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 4", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("5")] public JoinDataComplete Dtmf5 = - new JoinDataComplete(new JoinData {JoinNumber = 15, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 5", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("6")] public JoinDataComplete Dtmf6 = - new JoinDataComplete(new JoinData {JoinNumber = 16, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 6", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("7")] public JoinDataComplete Dtmf7 = - new JoinDataComplete(new JoinData {JoinNumber = 17, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 7", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("8")] public JoinDataComplete Dtmf8 = - new JoinDataComplete(new JoinData {JoinNumber = 18, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 8", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("9")] public JoinDataComplete Dtmf9 = - new JoinDataComplete(new JoinData {JoinNumber = 19, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF 9", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("#")] public JoinDataComplete DtmfPound = - new JoinDataComplete(new JoinData {JoinNumber = 22, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF #", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("*")] public JoinDataComplete DtmfStar = - new JoinDataComplete(new JoinData {JoinNumber = 21, JoinSpan = 1}, - new JoinMetadata - { - Description = "DTMF *", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndCall")] public JoinDataComplete EndCall = - new JoinDataComplete(new JoinData {JoinNumber = 24, JoinSpan = 1}, - new JoinMetadata - { - Description = "Hang Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("HookState")] public JoinDataComplete HookState = - new JoinDataComplete(new JoinData {JoinNumber = 31, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Hook State", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingAnswer")] public JoinDataComplete IncomingAnswer = - new JoinDataComplete(new JoinData {JoinNumber = 51, JoinSpan = 1}, - new JoinMetadata - { - Description = "Answer Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCall")] public JoinDataComplete IncomingCall = - new JoinDataComplete(new JoinData {JoinNumber = 50, JoinSpan = 1}, - new JoinMetadata - { - Description = "Incoming Call", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCallName")] public JoinDataComplete IncomingCallName = - new JoinDataComplete(new JoinData {JoinNumber = 51, JoinSpan = 1}, - new JoinMetadata - { - Description = "Incoming Call Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingCallNumber")] public JoinDataComplete IncomingCallNumber = - new JoinDataComplete(new JoinData {JoinNumber = 52, JoinSpan = 1}, - new JoinMetadata - { - Description = "Incoming Call Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingReject")] public JoinDataComplete IncomingReject = - new JoinDataComplete(new JoinData {JoinNumber = 52, JoinSpan = 1}, - new JoinMetadata - { - Description = "Reject Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("ManualDial")] public JoinDataComplete ManualDial = - new JoinDataComplete(new JoinData {JoinNumber = 71, JoinSpan = 1}, - new JoinMetadata - { - Description = "Dial manual string", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Meeting Count Fb")] public JoinDataComplete MeetingCount = - new JoinDataComplete(new JoinData {JoinNumber = 161, JoinSpan = 1}, - new JoinMetadata - { - Description = "Meeting Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("MicMuteOff")] public JoinDataComplete MicMuteOff = - new JoinDataComplete(new JoinData {JoinNumber = 172, JoinSpan = 1}, - new JoinMetadata - { - Description = "Mic Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteOn")] public JoinDataComplete MicMuteOn = - new JoinDataComplete(new JoinData {JoinNumber = 171, JoinSpan = 1}, - new JoinMetadata - { - Description = "Mic Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteToggle")] public JoinDataComplete MicMuteToggle = - new JoinDataComplete(new JoinData {JoinNumber = 173, JoinSpan = 1}, - new JoinMetadata - { - Description = "Mic Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MinutesBeforeMeetingStart")] public JoinDataComplete MinutesBeforeMeetingStart = - new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 1}, - new JoinMetadata - { - Description = "Minutes before meeting start that a meeting is joinable", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("ParticipantCount")] public JoinDataComplete ParticipantCount = - new JoinDataComplete(new JoinData {JoinNumber = 151, JoinSpan = 1}, - new JoinMetadata - { - Description = "Current Participant Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("Schedule")] public JoinDataComplete Schedule = - new JoinDataComplete(new JoinData {JoinNumber = 102, JoinSpan = 1}, - new JoinMetadata - { - Description = "Schedule Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("AutoShareWhileInCall")] public JoinDataComplete SourceShareAutoStart = - new JoinDataComplete(new JoinData {JoinNumber = 203, JoinSpan = 1}, - new JoinMetadata - { - Description = "When high, will autostart sharing when a call is joined", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareEnd")] public JoinDataComplete SourceShareEnd = - new JoinDataComplete(new JoinData {JoinNumber = 202, JoinSpan = 1}, - new JoinMetadata - { - Description = "Stop Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareStart")] public JoinDataComplete SourceShareStart = - new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1}, - new JoinMetadata - { - Description = "Start Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("RecievingContent")] public JoinDataComplete RecievingContent = - new JoinDataComplete(new JoinData {JoinNumber = 204, JoinSpan = 1}, - new JoinMetadata - { - Description = "Recieving content from the far end", - JoinType = eJoinType.Digital, - JoinCapabilities = eJoinCapabilities.ToSIMPL - }); - - [JoinName("SelfviewPosition")] public JoinDataComplete SelfviewPosition = - new JoinDataComplete(new JoinData {JoinNumber = 211, JoinSpan = 1}, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SelfviewPositionFb")] - public JoinDataComplete SelfviewPositionFb = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("SpeedDialStart")] public JoinDataComplete SpeedDialStart = - new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 4}, - new JoinMetadata - { - Description = "Speed Dial", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("UpdateMeetings")] public JoinDataComplete UpdateMeetings = - new JoinDataComplete(new JoinData {JoinNumber = 160, JoinSpan = 1}, - new JoinMetadata - { - Description = "Update Meetings", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeDown")] public JoinDataComplete VolumeDown = - new JoinDataComplete(new JoinData {JoinNumber = 175, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeLevel")] public JoinDataComplete VolumeLevel = - new JoinDataComplete(new JoinData {JoinNumber = 174, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Level", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("VolumeMuteOff")] public JoinDataComplete VolumeMuteOff = - new JoinDataComplete(new JoinData {JoinNumber = 177, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteOn")] public JoinDataComplete VolumeMuteOn = - new JoinDataComplete(new JoinData {JoinNumber = 176, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteToggle")] public JoinDataComplete VolumeMuteToggle = - new JoinDataComplete(new JoinData {JoinNumber = 178, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeUp")] public JoinDataComplete VolumeUp = - new JoinDataComplete(new JoinData {JoinNumber = 174, JoinSpan = 1}, - new JoinMetadata - { - Description = "Volume Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialPhoneCall")] - public JoinDataComplete DialPhone = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneHookState")] - public JoinDataComplete PhoneHookState = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndPhoneCall")] - public JoinDataComplete HangUpPhone = - new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Hang Up PHone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneString")] - public JoinDataComplete PhoneDialString = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Phone Dial String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof (VideoCodecControllerJoinMap)) + public VideoCodecControllerJoinMap(uint joinStart) : this(joinStart, typeof (VideoCodecControllerJoinMap)) { } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs index 63f4917a..5eac89ed 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs @@ -12,9 +12,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface IHasBranding + public interface IHasBranding:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasBranding { - bool BrandingEnabled { get; } - void InitializeBranding(string roomKey); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs index 7f75adec..60d60636 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs @@ -1,5 +1,4 @@ using System; -using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { @@ -17,13 +16,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface IHasPhoneDialing + public interface IHasPhoneDialing:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasPhoneDialing { - BoolFeedback PhoneOffHookFeedback { get; } - StringFeedback CallerIdNameFeedback { get; } - StringFeedback CallerIdNumberFeedback { get; } - void DialPhoneCall(string number); - void EndPhoneCall(); - void SendDtmfToPhone(string digit); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs index abf138a4..cbc7aa5c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs @@ -20,16 +20,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface ILanguageDefinition + public interface ILanguageDefinition:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageDefinition { - string LocaleName { get; set; } - string FriendlyName { get; set; } - bool Enable { get; set; } - List UiLabels { get; set; } - List Sources { get; set; } - List Destinations { get; set; } - List SourceGroupNames { get; set; } - List DestinationGroupNames { get; set; } - List RoomNames { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs index dd48723d..f0c1e334 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs @@ -15,11 +15,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface ILanguageProvider + public interface ILanguageProvider:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageProvider { - ILanguageDefinition CurrentLanguage { get; set; } - - event EventHandler CurrentLanguageChanged; } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs index c7d26722..a6143665 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs @@ -15,11 +15,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public class LanguageLabel + public class LanguageLabel: PepperDash.Essentials.Core.DeviceTypeInterfaces.LanguageLabel { - public string Key { get; set; } - public string Description { get; set; } - public string DisplayText { get; set; } - public uint JoinNumber { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs index b0a40a47..409562a2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs @@ -133,139 +133,6 @@ namespace PepperDash.Essentials.Core.Devices return new GenericIrController(dc.Key, dc.Name, irPort); } - #endregion - } -} - -namespace PepperDash_Essentials_Core.Devices -{ - [Obsolete("Use PepperDash.Essentials.Core.Devices")] - public class GenericIrController : EssentialsBridgeableDevice - { - //data storage for bridging - private BasicTriList _trilist; - private uint _joinStart; - private string _joinMapKey; - private EiscApiAdvanced _bridge; - - private readonly IrOutputPortController _port; - - public string[] IrCommands { get { return _port.IrFileCommands; } } - - public GenericIrController(string key, string name, IrOutputPortController irPort) - : base(key, name) - { - _port = irPort; - - if (_port == null) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Error, "IR Port is null, device will not function"); - return; - } - DeviceManager.AddDevice(_port); - - _port.DriverLoaded.OutputChange += DriverLoadedOnOutputChange; - } - - private void DriverLoadedOnOutputChange(object sender, FeedbackEventArgs args) - { - if (!args.BoolValue) - { - return; - } - - if (_trilist == null || _bridge == null) - { - return; - } - - LinkToApi(_trilist, _joinStart, _joinMapKey, _bridge); - } - - #region Overrides of EssentialsBridgeableDevice - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - //if driver isn't loaded yet, store the variables until it is loaded, then call the LinkToApi method again - if (!_port.DriverIsLoaded) - { - _trilist = trilist; - _joinStart = joinStart; - _joinMapKey = joinMapKey; - _bridge = bridge; - return; - } - - var joinMap = new GenericIrControllerJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - for (uint i = 0; i < _port.IrFileCommands.Length; i++) - { - var cmd = _port.IrFileCommands[i]; - var joinData = new JoinDataComplete(new JoinData { JoinNumber = i, JoinSpan = 1 }, - new JoinMetadata - { - Description = cmd, - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - joinData.SetJoinOffset(joinStart); - - joinMap.Joins.Add(cmd, joinData); - - trilist.SetBoolSigAction(joinData.JoinNumber, (b) => Press(cmd, b)); - } - - joinMap.PrintJoinMapInfo(); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - } - - #endregion - - public void Press(string command, bool pressRelease) - { - _port.PressRelease(command, pressRelease); - } - } - - public sealed class GenericIrControllerJoinMap : JoinMapBaseAdvanced - { - public GenericIrControllerJoinMap(uint joinStart) - : base(joinStart) - { - } - } - - public class GenericIrControllerFactory : EssentialsDeviceFactory - { - public GenericIrControllerFactory() - { - TypeNames = new List { "genericIrController" }; - } - #region Overrides of EssentialsDeviceFactory - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new Generic IR Controller Device"); - - var irPort = IRPortHelper.GetIrOutputPortController(dc); - - return new GenericIrController(dc.Key, dc.Name, irPort); - } - #endregion } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs index de7bc3a5..eceefff5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core { @@ -26,19 +27,15 @@ namespace PepperDash.Essentials.Core namespace PepperDash_Essentials_Core { [Obsolete("Use PepperDash.Essentials.Core")] - public class IsReadyEventArgs : EventArgs + public class IsReadyEventArgs : PepperDash.Essentials.Core.IsReadyEventArgs { - public bool IsReady { get; set; } - - public IsReadyEventArgs(bool data) + public IsReadyEventArgs(bool data) : base(data) { - IsReady = data; } } - public interface IHasReady + [Obsolete("Use PepperDash.Essentials.Core")] + public interface IHasReady: PepperDash.Essentials.Core.IHasReady { - event EventHandler IsReadyEvent; - bool IsReady { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs index 3c01032e..acf3bbea 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs @@ -78,23 +78,15 @@ namespace PepperDash_Essentials_Core.Queues /// IBasicCommunication Message for IQueue /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class ComsMessage : IQueueMessage + public class ComsMessage : PepperDash.Essentials.Core.Queues.ComsMessage { - private readonly byte[] _bytes; - private readonly IBasicCommunication _coms; - private readonly string _string; - private readonly bool _isByteMessage; - /// /// Constructor for a string message /// /// IBasicCommunication to send the message /// Message to send - public ComsMessage(IBasicCommunication coms, string message) + public ComsMessage(IBasicCommunication coms, string message):base(coms, message) { - Validate(coms, message); - _coms = coms; - _string = message; } /// @@ -102,44 +94,8 @@ namespace PepperDash_Essentials_Core.Queues /// /// IBasicCommunication to send the message /// Message to send - public ComsMessage(IBasicCommunication coms, byte[] message) + public ComsMessage(IBasicCommunication coms, byte[] message):base(coms, message) { - Validate(coms, message); - _coms = coms; - _bytes = message; - _isByteMessage = true; - } - - private void Validate(IBasicCommunication coms, object message) - { - if (coms == null) - throw new ArgumentNullException("coms"); - - if (message == null) - throw new ArgumentNullException("message"); - } - - /// - /// Dispatchs the string/byte[] to the IBasicCommunication specified - /// - public void Dispatch() - { - if (_isByteMessage) - { - _coms.SendBytes(_bytes); - } - else - { - _coms.SendText(_string); - } - } - - /// - /// Shows either the byte[] or string to be sent - /// - public override string ToString() - { - return _bytes != null ? _bytes.ToString() : _string; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 1fcc497c..c2a46d62 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -126,7 +126,9 @@ namespace PepperDash.Essentials.Core.Queues /// /// Key /// - private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) + /// + /// + protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) { _key = key; int cap = 25; // sets default @@ -252,44 +254,14 @@ namespace PepperDash_Essentials_Core.Queues /// Threadsafe processing of queued items with pacing if required /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class GenericQueue : IQueue + public class GenericQueue : PepperDash.Essentials.Core.Queues.GenericQueue { - private readonly string _key; - protected readonly CrestronQueue _queue; - protected readonly Thread _worker; - protected readonly CEvent _waitHandle = new CEvent(); - private bool _delayEnabled; private int _delayTime; private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority; - /// - /// If the instance has been disposed. - /// - public bool Disposed { get; private set; } - - /// - /// Returns the capacity of the CrestronQueue (fixed Size property) - /// - public int QueueCapacity - { - get - { - return _queue.Size; - } - } - - /// - /// Returns the number of elements currently in the CrestronQueue - /// - public int QueueCount - { - get - { - return _queue.Count; - } - } + /// /// Constructor with no thread priority @@ -370,122 +342,10 @@ namespace PepperDash_Essentials_Core.Queues /// /// Key /// - private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) + /// + /// + private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing):base(key, priority, capacity, pacing) { - _key = key; - int cap = 25; // sets default - if (capacity > 0) - { - cap = capacity; // overrides default - } - _queue = new CrestronQueue(cap); - _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) - { - Priority = priority - }; - - SetDelayValues(pacing); - } - - private void SetDelayValues(int pacing) - { - _delayEnabled = pacing > 0; - _delayTime = pacing; - - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; - - Dispose(); - }; - } - - /// - /// Thread callback - /// - /// The action used to process dequeued items - /// Null when the thread is exited - private object ProcessQueue(object obj) - { - while (true) - { - IQueueMessage item = null; - - if (_queue.Count > 0) - { - item = _queue.Dequeue(); - if (item == null) - break; - } - if (item != null) - { - try - { - Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString()); - item.Dispatch(); - - if (_delayEnabled) - Thread.Sleep(_delayTime); - } - catch (Exception ex) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace); - } - } - else _waitHandle.Wait(); - } - - return null; - } - - public void Enqueue(IQueueMessage item) - { - _queue.Enqueue(item); - _waitHandle.Set(); - } - - /// - /// Disposes the thread and cleans up resources. Thread cannot be restarted once - /// disposed. - /// - public void Dispose() - { - Dispose(true); - CrestronEnvironment.GC.SuppressFinalize(this); - } - - /// - /// Actually does the disposing. If you override this method, be sure to either call the base implementation - /// or clean up all the resources yourself. - /// - /// set to true unless called from finalizer - protected void Dispose(bool disposing) - { - if (Disposed) - return; - - if (disposing) - { - Enqueue(null); - _worker.Join(); - _waitHandle.Close(); - } - - Disposed = true; - } - - ~GenericQueue() - { - Dispose(false); - } - - /// - /// Key - /// - public string Key - { - get { return _key; } } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs index 15803330..c5198245 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs @@ -17,9 +17,7 @@ namespace PepperDash.Essentials.Core.Queues namespace PepperDash_Essentials_Core.Queues { [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public interface IQueue : IKeyed, IDisposable where T : class + public interface IQueue : PepperDash.Essentials.Core.Queues.IQueue where T: class { - void Enqueue(T item); - bool Disposed { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs index 8ffd4d96..0758e1d8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs @@ -11,8 +11,7 @@ namespace PepperDash.Essentials.Core.Queues namespace PepperDash_Essentials_Core.Queues { [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public interface IQueueMessage + public interface IQueueMessage:PepperDash.Essentials.Core.Queues.IQueueMessage { - void Dispatch(); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs index d8ea4ada..65f02801 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs @@ -49,40 +49,13 @@ namespace PepperDash_Essentials_Core.Queues /// Message class for processing strings via an IQueue /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class ProcessStringMessage : IQueueMessage + public class ProcessStringMessage : PepperDash.Essentials.Core.Queues.ProcessStringMessage { - private readonly Action _action; - private readonly string _message; - /// /// Constructor /// /// Message to be processed /// Action to invoke on the message - public ProcessStringMessage(string message, Action action) - { - _message = message; - _action = action; - } - - /// - /// Processes the string with the given action - /// - public void Dispatch() - { - if (_action == null || String.IsNullOrEmpty(_message)) - return; - - _action(_message); - } - - /// - /// To string - /// - /// The current message - public override string ToString() - { - return _message ?? String.Empty; - } + public ProcessStringMessage(string message, Action action) : base(message, action){} } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs index e2db5d72..6ae61a53 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs @@ -111,14 +111,14 @@ namespace PepperDash_Essentials_Core.Queues public sealed class StringResponseProcessor : IKeyed, IDisposable { private readonly Action _processStringAction; - private readonly IQueue _queue; + private readonly PepperDash.Essentials.Core.Queues.IQueue _queue; private readonly IBasicCommunication _coms; private readonly CommunicationGather _gather; private StringResponseProcessor(string key, Action processStringAction) { _processStringAction = processStringAction; - _queue = new GenericQueue(key); + _queue = new PepperDash.Essentials.Core.Queues.GenericQueue(key); CrestronEnvironment.ProgramStatusEventHandler += programEvent => { 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 8765b0e1..1a755cef 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 @@ -19,8 +19,7 @@ using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; -using PepperDash_Essentials_Core.Bridges.JoinMaps; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Bridges.JoinMaps; using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Devices.Common.VideoCodec From 890abf438384bfa800c7dc0cb14cfcdce173ca5f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 16:19:29 -0700 Subject: [PATCH 130/480] initial updates to ExecuteSwitch --- .../Chassis/DmChassisController.cs | 154 +++++++++++++----- 1 file changed, 116 insertions(+), 38 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 3c5567c4..8fc3ef4b 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1171,18 +1171,24 @@ namespace PepperDash.Essentials.DM #region IRouting Members public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) { - Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); - - var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail - var output = Convert.ToUInt32(outputSelector); - - var chassisSize = (uint) Chassis.NumberOfInputs; //need this to determine USB routing values 8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); + + var input = inputSelector as DMInput;//Input Selector could be null... + + var output = outputSelector as DMOutput; + + if (output == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, + outputSelector); + return; + + } // Check to see if there's an off timer waiting on this and if so, cancel - var key = new PortNumberType(output, sigType); - if (input == 0) + var key = new PortNumberType(output.Number, sigType); + if (input == null) { StartOffTimer(key); } @@ -1196,22 +1202,27 @@ namespace PepperDash.Essentials.DM } } - var inCard = input == 0 ? null : Chassis.Inputs[input]; - var outCard = input == 0 ? null : Chassis.Outputs[output]; + //var inCard = input == 0 ? null : Chassis.Inputs[input]; + //var outCard = input == 0 ? null : Chassis.Outputs[output]; // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) { - Chassis.VideoEnter.BoolValue = true; - Chassis.Outputs[output].VideoOut = inCard; - } - - if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - { - (Chassis as DmMDMnxn).AudioEnter.BoolValue = true; - Chassis.Outputs[output].AudioOut = inCard; + Chassis.VideoEnter.BoolValue = true; + output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard; } + if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + { + var dmMdMnxn = Chassis as DmMDMnxn; + if (dmMdMnxn != null) + { + dmMdMnxn.AudioEnter.BoolValue = true; + } + output.VideoOut = input; + //Chassis.Outputs[output].AudioOut = inCard; + } + if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) { //using base here because USB can be routed between 2 output cards or 2 input cards @@ -1219,7 +1230,7 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", input, output); - if (input > chassisSize) + if (input != null && input.Number > chassisSize) { //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 //need this to determine USB routing values @@ -1230,24 +1241,23 @@ namespace PepperDash.Essentials.DM if (chassisSize == 8) { - outputIndex = input - 16; + outputIndex = input.Number - 16; } else { - outputIndex = input - chassisSize; + outputIndex = input.Number - chassisSize; } + dmCard = Chassis.Outputs[outputIndex]; } else { - dmCard = inCard; - } - Chassis.USBEnter.BoolValue = true; - if (Chassis.Outputs[output] != null) - { - Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Outputs[input], dmCard); - Chassis.Outputs[output].USBRoutedTo = dmCard; + dmCard = input; } + Chassis.USBEnter.BoolValue = true; + + Debug.Console(2, this, "Routing USB for input {0} to {1}", input, dmCard); + output.USBRoutedTo = dmCard; } if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) @@ -1268,17 +1278,17 @@ namespace PepperDash.Essentials.DM if (chassisSize == 8) { - outputIndex = input - 16; + outputIndex = input.Number - 16; } else { - outputIndex = input - chassisSize; + outputIndex = input.Number - chassisSize; } dmCard = Chassis.Outputs[outputIndex]; } - else - { - dmCard = Chassis.Inputs[input]; + else + { + dmCard = input; } @@ -1297,9 +1307,77 @@ namespace PepperDash.Essentials.DM #region IRoutingNumeric Members - public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) - { - ExecuteSwitch(inputSelector, outputSelector, sigType); + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) + { + var chassisSize = (uint)Chassis.NumberOfInputs; //need this to determine USB routing values 8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 + //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 + //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + + DMInputOutputBase dmCard; + + if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + { + if (outputSelector > chassisSize) + { + uint outputIndex; + + if (chassisSize == 8) + { + outputIndex = (uint) inputSelector - 16; + } + else + { + outputIndex = inputSelector - chassisSize; + } + dmCard = Chassis.Outputs[outputIndex]; + } + else + { + dmCard = Chassis.Inputs[inputSelector]; + } + + ExecuteSwitch(dmCard, Chassis.Outputs[outputSelector], sigType); + return; + } + if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) + { + Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", inputSelector, outputSelector); + + if (inputSelector > chassisSize) + { + //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 + //need this to determine USB routing values + //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 + //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 + //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 + uint outputIndex; + + if (chassisSize == 8) + { + outputIndex = (uint) inputSelector - 16; + } + else + { + outputIndex = inputSelector - chassisSize; + } + + dmCard = Chassis.Outputs[outputIndex]; + } + else + { + dmCard = Chassis.Inputs[inputSelector]; + } + Chassis.USBEnter.BoolValue = true; + + Debug.Console(2, this, "Routing USB for input {0} to {1}", inputSelector, dmCard); + ExecuteSwitch(dmCard, Chassis.Outputs[outputSelector], sigType); + return; + } + + var inputCard = Chassis.Inputs[inputSelector]; + var outputCard = Chassis.Outputs[outputSelector]; + + ExecuteSwitch(inputCard, outputCard, sigType); } #endregion From f828cbecbd7bbf74882737a76ee423040ef4d7dc Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Feb 2021 16:23:48 -0700 Subject: [PATCH 131/480] fix USB routing --- .../Chassis/DmChassisController.cs | 79 +------------------ 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 8fc3ef4b..83f40677 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1223,85 +1223,12 @@ namespace PepperDash.Essentials.DM //Chassis.Outputs[output].AudioOut = inCard; } - if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) - { - //using base here because USB can be routed between 2 output cards or 2 input cards - DMInputOutputBase dmCard; - - Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", input, output); - - if (input != null && input.Number > chassisSize) - { - //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 - //need this to determine USB routing values - //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 - uint outputIndex; - - if (chassisSize == 8) - { - outputIndex = input.Number - 16; - } - else - { - outputIndex = input.Number - chassisSize; - } - - dmCard = Chassis.Outputs[outputIndex]; - } - else - { - dmCard = input; - } + if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput || (sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + { Chassis.USBEnter.BoolValue = true; - - Debug.Console(2, this, "Routing USB for input {0} to {1}", input, dmCard); - output.USBRoutedTo = dmCard; + output.USBRoutedTo = input; } - if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) - { - //using base here because USB can be routed between 2 output cards or 2 input cards - DMInputOutputBase dmCard; - - Debug.Console(2, this, "Executing USB Input switch.\r\n in:{0} output: {1}", input, output); - - if (output > chassisSize) - { - //wanting to route an input to an output. Subtract chassis size and get output, unless it's 8x8 - //need this to determine USB routing values - //8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 - //16x16 1-16 is inputs 1-16, 17-32 is outputs 1-16 - //32x32 1-32 is inputs 1-32, 33-64 is outputs 1-32 - uint outputIndex; - - if (chassisSize == 8) - { - outputIndex = input.Number - 16; - } - else - { - outputIndex = input.Number - chassisSize; - } - dmCard = Chassis.Outputs[outputIndex]; - } - else - { - dmCard = input; - } - - - - Chassis.USBEnter.BoolValue = true; - - if (Chassis.Inputs[output] == null) - { - return; - } - Debug.Console(2, this, "Routing USB for input {0} to {1}", Chassis.Inputs[output], dmCard); - Chassis.Inputs[output].USBRoutedTo = dmCard; - } } #endregion From ef63c1db02d52edf6e595cce2c0672f66eca8184 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 19 Feb 2021 08:51:59 -0700 Subject: [PATCH 132/480] Updating DM Controller to add DMInput/Output as selector instead of number --- .../Chassis/DmChassisController.cs | 507 +++++++++--------- 1 file changed, 260 insertions(+), 247 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 83f40677..39b6c0e0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -133,6 +133,8 @@ namespace PepperDash.Essentials.DM var controller = new DmChassisController(key, name, chassis); + // + // add the cards and port names foreach (var kvp in properties.InputSlots) controller.AddInputCard(kvp.Value, kvp.Key); @@ -485,169 +487,170 @@ namespace PepperDash.Essentials.DM type = type.ToLower(); - if (type == "dmchd") - { - var inputCard = new DmcHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmchddsp") - { - var inputCard = new DmcHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4khd") - { - var inputCard = new Dmc4kHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4khddsp") - { - var inputCard = new Dmc4kHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4kzhd") - { - var inputCard = new Dmc4kzHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4kzhddsp") - { - var inputCard = new Dmc4kzHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmcc") - { - var inputCard = new DmcC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmccdsp") - { - var inputCard = new DmcCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kc") - { - var inputCard = new Dmc4kC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kcdsp") - { - var inputCard = new Dmc4kCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kzc") - { - var inputCard = new Dmc4kzC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kzcdsp") - { - var inputCard = new Dmc4kzCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmccat") - { - new DmcCat(number, this.Chassis); - AddDmInCardPorts(number); - } - else if (type == "dmccatdsp") - { - new DmcCatDsp(number, this.Chassis); - AddDmInCardPorts(number); - } - else if (type == "dmcs") - { - new DmcS(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcsdsp") - { - new DmcSDsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcs2") - { - new DmcS2(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcs2dsp") - { - new DmcS2Dsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcsdi") - { - new DmcSdi(number, Chassis); - AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Sdi, null); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcdvi") - { - new DmcDvi(number, Chassis); - AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvga") - { - new DmcVga(number, Chassis); - AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidbnc") - { - new DmcVidBnc(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidrcaa") - { - new DmcVidRcaA(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidrcad") - { - new DmcVidRcaD(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvid4") - { - new DmcVid4(number, Chassis); - AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcstr") - { - new DmcStr(number, Chassis); - AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); - AddInCardHdmiAndAudioLoopPorts(number); + switch (type) + { + case "dmchd": + { + var inputCard = new DmcHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmchddsp": + { + var inputCard = new DmcHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmc4khd": + { + var inputCard = new Dmc4kHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmc4khddsp": + { + var inputCard = new Dmc4kHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmc4kzhd": + { + var inputCard = new Dmc4kzHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmc4kzhddsp": + { + var inputCard = new Dmc4kzHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + break; + case "dmcc": + { + var inputCard = new DmcC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmccdsp": + { + var inputCard = new DmcCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmc4kc": + { + var inputCard = new Dmc4kC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmc4kcdsp": + { + var inputCard = new Dmc4kCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmc4kzc": + { + var inputCard = new Dmc4kzC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmc4kzcdsp": + { + var inputCard = new Dmc4kzCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + break; + case "dmccat": + new DmcCat(number, this.Chassis); + AddDmInCardPorts(number); + break; + case "dmccatdsp": + new DmcCatDsp(number, this.Chassis); + AddDmInCardPorts(number); + break; + case "dmcs": + new DmcS(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + break; + case "dmcsdsp": + new DmcSDsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + break; + case "dmcs2": + new DmcS2(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + break; + case "dmcs2dsp": + new DmcS2Dsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + break; + case "dmcsdi": + new DmcSdi(number, Chassis); + AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Sdi, null); + AddInCardHdmiAndAudioLoopPorts(number); + break; + case "dmcdvi": + new DmcDvi(number, Chassis); + AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + break; + case "dmcvga": + new DmcVga(number, Chassis); + AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + break; + case "dmcvidbnc": + new DmcVidBnc(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + break; + case "dmcvidrcaa": + new DmcVidRcaA(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + break; + case "dmcvidrcad": + new DmcVidRcaD(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); + AddInCardHdmiLoopPort(number); + break; + case "dmcvid4": + new DmcVid4(number, Chassis); + AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInCardHdmiLoopPort(number); + break; + case "dmcstr": + new DmcStr(number, Chassis); + AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); + AddInCardHdmiAndAudioLoopPorts(number); + break; } } @@ -692,104 +695,114 @@ namespace PepperDash.Essentials.DM type = type.ToLower(); Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); - if (type == "dmc4khdo") - { - var outputCard = new Dmc4kHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); + switch (type) + { + case "dmc4khdo": + { + var outputCard = new Dmc4kHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + break; + case "dmc4kzhdo": + { + var outputCard = new Dmc4kzHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + break; + case "dmchdo": + { + var outputCard = new DmcHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + break; + case "dmc4kcohd": + { + var outputCard = new Dmc4kCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + break; + case "dmc4kzcohd": + { + var outputCard = new Dmc4kzCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + break; + case "dmccohd": + { + var outputCard = new DmcCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + break; + case "dmccatohd": + { + var outputCard = new DmcCatoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + break; + case "dmcsohd": + { + var outputCard = new DmcSoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 2]); + } + break; + case "dmcs2ohd": + { + var outputCard = new DmcS2oHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 2]); + } + break; + case "dmcstro": + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Streaming, Chassis.Outputs[2 * (number - 1) + 1]); + break; + default: + Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); + break; } - else if (type == "dmc4kzhdo") - { - var outputCard = new Dmc4kzHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); - } - else if (type == "dmchdo") - { - var outputCard = new DmcHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); - } - else if (type == "dmc4kcohd") - { - var outputCard = new Dmc4kCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmc4kzcohd") - { - var outputCard = new Dmc4kzCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmccohd") - { - var outputCard = new DmcCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmccatohd") - { - var outputCard = new DmcCatoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmcsohd") - { - var outputCard = new DmcSoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 2); - } - else if (type == "dmcs2ohd") - { - var outputCard = new DmcS2oHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 2); - } - else if (type == "dmcstro") - { - var outputCard = new DmcStroSingle(number, Chassis); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Streaming, 2 * (number - 1) + 1); - } - - else - Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); } void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) { AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, - 2 * (number - 1) + 1); + Chassis.Outputs[2 * (number - 1) + 1]); AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 2, cecPort2); + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 2], cecPort2); AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, - 2 * (number - 1) + 2); + Chassis.Outputs[2 * (number - 1) + 2]); } void AddDmcCoPorts(uint number, ICec cecPort1) { AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 1); + eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 1]); AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 2); + eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 2]); } /// @@ -799,7 +812,7 @@ namespace PepperDash.Essentials.DM { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) + var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) { FeedbackMatchObject = Chassis.Inputs[cardNum] }; @@ -814,7 +827,7 @@ namespace PepperDash.Essentials.DM { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) + var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) { FeedbackMatchObject = Chassis.Inputs[cardNum] }; ; From ac0926717321b711aa2934c8df913b1ac9486203 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 19 Feb 2021 08:55:34 -0700 Subject: [PATCH 133/480] Add Clear input port for Essentials Routing --- .../Essentials_DM/Chassis/DmChassisController.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 39b6c0e0..9679331e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -21,8 +21,9 @@ namespace PepperDash.Essentials.DM /// /// [Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")] - public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback - { + public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback + { + private const string NonePortKey = "inputCard0--None"; public DMChassisPropertiesConfig PropertiesConfig { get; set; } public Switch Chassis { get; private set; } @@ -133,7 +134,11 @@ namespace PepperDash.Essentials.DM var controller = new DmChassisController(key, name, chassis); - // + // + var clearInputPort = new RoutingInputPort(NonePortKey, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.None, null, controller); + + controller.InputPorts.Add(clearInputPort); // add the cards and port names foreach (var kvp in properties.InputSlots) From dca21aa4dcc5c71547e07550cd3a4d8b27c54943 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 19 Feb 2021 16:43:18 -0700 Subject: [PATCH 134/480] Fixed some issues discovered during testing --- .../Chassis/DmChassisController.cs | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 9679331e..63099e60 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -813,16 +813,9 @@ namespace PepperDash.Essentials.DM /// /// Adds InputPort /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) - { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) - { - FeedbackMatchObject = Chassis.Inputs[cardNum] - }; - - InputPorts.Add(inputPort); + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) + { + AddInputPortWithDebug(cardNum, portName, sigType, portType, null); } /// @@ -846,19 +839,9 @@ namespace PepperDash.Essentials.DM /// /// Adds OutputPort /// - void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) - { - var portKey = string.Format("{0}--{1}", cardName, portName); - Debug.Console(2, this, "Adding output port '{0}'", portKey); - - var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); - - if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0) - { - outputPort.FeedbackMatchObject = Chassis.Outputs[(uint) selector]; - } - - OutputPorts.Add(outputPort); + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) + { + AddOutputPortWithDebug(cardName, portName, sigType, portType, selector, null); } /// @@ -872,7 +855,7 @@ namespace PepperDash.Essentials.DM if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0) { - outputPort.FeedbackMatchObject = Chassis.Outputs[(uint)selector]; + outputPort.FeedbackMatchObject = selector; } if (cecPort != null) outputPort.Port = cecPort; @@ -1162,7 +1145,7 @@ namespace PepperDash.Essentials.DM { if (RouteOffTimers.ContainsKey(pnt)) return; - RouteOffTimers[pnt] = new CTimer(o => { ExecuteSwitch(0, pnt.Number, pnt.Type); }, RouteOffTime); + RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); } // Send out sigs when coming online @@ -1205,7 +1188,7 @@ namespace PepperDash.Essentials.DM } // Check to see if there's an off timer waiting on this and if so, cancel - var key = new PortNumberType(output.Number, sigType); + var key = new PortNumberType(output, sigType); if (input == null) { StartOffTimer(key); @@ -1873,13 +1856,23 @@ namespace PepperDash.Essentials.DM public struct PortNumberType { public uint Number { get; private set; } + public object Selector { get; private set; } public eRoutingSignalType Type { get; private set; } - public PortNumberType(uint number, eRoutingSignalType type) + public PortNumberType(object selector, eRoutingSignalType type) : this() { - Number = number; - Type = type; + Selector = selector; + Type = type; + + if (Selector is DMOutput) + { + Number = (selector as DMOutput).Number; + } + else if (Selector is uint) + { + Number = (uint) selector; + } } } From 93c0b339583115c376034c5d4156163ca25610ef Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Feb 2021 09:55:09 -0700 Subject: [PATCH 135/480] Updated dmps & blade chassis to use similar routing --- .../Chassis/DmBladeChassisController.cs | 34 +++++--- .../Chassis/DmpsRoutingController.cs | 77 +++++++++---------- 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index abeba8d8..cee6a955 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -567,9 +567,7 @@ namespace PepperDash.Essentials.DM { void StartOffTimer(PortNumberType pnt) { if (RouteOffTimers.ContainsKey(pnt)) return; - RouteOffTimers[pnt] = new CTimer(o => { - ExecuteSwitch(0, pnt.Number, pnt.Type); - }, RouteOffTime); + RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); } @@ -592,11 +590,22 @@ namespace PepperDash.Essentials.DM { public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) { Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); - var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail - var output = Convert.ToUInt32(outputSelector); + var input = inputSelector as DMInput; // Cast can sometimes fail + var output = outputSelector as DMOutput; + + + if (output == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, + outputSelector); + return; + } + // Check to see if there's an off timer waiting on this and if so, cancel var key = new PortNumberType(output, sigType); - if (input == 0) { + + if (input == null) { StartOffTimer(key); } else { @@ -609,13 +618,13 @@ namespace PepperDash.Essentials.DM { - var inCard = input == 0 ? null : Chassis.Inputs[input]; - var outCard = input == 0 ? null : Chassis.Outputs[output]; + /*var inCard = input == 0 ? null : Chassis.Inputs[input]; + var outCard = input == 0 ? null : Chassis.Outputs[output];*/ // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES - if ((sigType | eRoutingSignalType.Video) != eRoutingSignalType.Video) return; + if ((sigType & eRoutingSignalType.Video) != eRoutingSignalType.Video) return; Chassis.VideoEnter.BoolValue = true; - Chassis.Outputs[output].VideoOut = inCard; + output.VideoOut = input; } #endregion @@ -624,7 +633,10 @@ namespace PepperDash.Essentials.DM { public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { - ExecuteSwitch(inputSelector, outputSelector, sigType); + var input = Chassis.Inputs[inputSelector]; + var output = Chassis.Outputs[outputSelector]; + + ExecuteSwitch(input, output, sigType); } #endregion diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 34d1cd60..0d9b0692 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -848,21 +848,32 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType); - var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail - var output = Convert.ToUInt32(outputSelector); + //var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail + //var output = Convert.ToUInt32(outputSelector); + + var input = inputSelector as DMInput; + var output = outputSelector as DMOutput; + + if (output == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, + outputSelector); + return; + } var sigTypeIsUsbOrVideo = ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) || ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) || ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput); - if ((input <= Dmps.NumberOfSwitcherInputs && output <= Dmps.NumberOfSwitcherOutputs && + if (input == null || (input.Number <= Dmps.NumberOfSwitcherInputs && output.Number <= Dmps.NumberOfSwitcherOutputs && sigTypeIsUsbOrVideo) || - (input <= Dmps.NumberOfSwitcherInputs + 5 && output <= Dmps.NumberOfSwitcherOutputs && + (input.Number <= Dmps.NumberOfSwitcherInputs + 5 && output.Number <= Dmps.NumberOfSwitcherOutputs && (sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)) { // Check to see if there's an off timer waiting on this and if so, cancel var key = new PortNumberType(output, sigType); - if (input == 0) + if (input == null) { StartOffTimer(key); } @@ -877,60 +888,45 @@ namespace PepperDash.Essentials.DM } - DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput; + //DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput; //if (inCard != null) //{ // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) { - DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; - //SystemControl.VideoEnter.BoolValue = true; - if (dmOutputCard != null) - dmOutputCard.VideoOut = dmInputCard; + + output.VideoOut = input; } if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) { - DMInput dmInputCard = null; - if (input <= Dmps.NumberOfSwitcherInputs) + try { - dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; + output.AudioOut = input; } + catch (NotSupportedException) + { + Debug.Console(1, this, "Routing input {0} audio to output {1}", + (eDmps34KAudioOutSource) input.Number, + (CrestronControlSystem.eDmps34K350COutputs) output.Number); - if (dmOutputCard != null) - try - { - dmOutputCard.AudioOut = dmInputCard; - } - catch (NotSupportedException) - { - Debug.Console(1, this, "Routing input {0} audio to output {1}", - (eDmps34KAudioOutSource) input, (CrestronControlSystem.eDmps34K350COutputs) output); - - dmOutputCard.AudioOutSource = (eDmps34KAudioOutSource) input; - } + output.AudioOutSource = (eDmps34KAudioOutSource) input.Number; + } } if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) { - DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; - if (dmOutputCard != null) - dmOutputCard.USBRoutedTo = dmInputCard; + + output.USBRoutedTo = input; } - if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + if ((sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput) { - DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; - if (dmInputCard != null) - dmInputCard.USBRoutedTo = dmOutputCard; + return; } - //} - //else - //{ - // Debug.Console(1, this, "Unable to execute route from input {0} to output {1}. Input card not available", inputSelector, outputSelector); - //} - + if (input != null) + input.USBRoutedTo = output; } else { @@ -950,7 +946,10 @@ namespace PepperDash.Essentials.DM public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { - ExecuteSwitch(inputSelector, outputSelector, sigType); + var input = Dmps.SwitcherInputs[inputSelector]; + var output = Dmps.SwitcherOutputs[outputSelector]; + + ExecuteSwitch(input, output, sigType); } #endregion From 8a6d5ebd56360ba0024fe68d44ff7f501746de94 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Feb 2021 10:00:24 -0700 Subject: [PATCH 136/480] Update port creation for DMPS --- .../Chassis/DmpsRoutingController.cs | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 0d9b0692..e6bec335 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -531,15 +531,7 @@ namespace PepperDash.Essentials.DM private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) - { - FeedbackMatchObject = Dmps.SwitcherInputs[cardNum] - }; - ; - - InputPorts.Add(inputPort); + AddInputPortWithDebug(cardNum, portName, sigType, portType, null); } /// @@ -549,11 +541,10 @@ namespace PepperDash.Essentials.DM { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) + var inputPort = new RoutingInputPort(portKey, sigType, portType, Dmps.SwitcherInputs[cardNum], this) { FeedbackMatchObject = Dmps.SwitcherInputs[cardNum] }; - ; if (cecPort != null) inputPort.Port = cecPort; @@ -672,7 +663,7 @@ namespace PepperDash.Essentials.DM /// void AddAudioOnlyOutputPort(uint number, string portName) { - AddOutputPortWithDebug(number, portName, eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, number); + AddOutputPortWithDebug(number, portName, eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, Dmps.SwitcherOutputs[number]); } /// @@ -682,7 +673,7 @@ namespace PepperDash.Essentials.DM /// void AddHdmiOutputPort(uint number, ICec cecPort) { - AddOutputPortWithDebug(number, string.Format("hdmiOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, number, cecPort); + AddOutputPortWithDebug(number, string.Format("hdmiOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Dmps.SwitcherOutputs[number], cecPort); } /// @@ -691,7 +682,7 @@ namespace PepperDash.Essentials.DM /// void AddDmOutputPort(uint number) { - AddOutputPortWithDebug(number, string.Format("dmOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, number); + AddOutputPortWithDebug(number, string.Format("dmOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Dmps.SwitcherOutputs[number]); } /// @@ -699,12 +690,7 @@ namespace PepperDash.Essentials.DM /// void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { - var portKey = string.Format("outputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding output port '{0}'", portKey); - OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this) - { - FeedbackMatchObject = Dmps.SwitcherOutputs[cardNum] - }); + AddOutputPortWithDebug(cardNum, portName, sigType, portType, selector, null); } /// @@ -908,10 +894,12 @@ namespace PepperDash.Essentials.DM catch (NotSupportedException) { Debug.Console(1, this, "Routing input {0} audio to output {1}", - (eDmps34KAudioOutSource) input.Number, + (eDmps34KAudioOutSource) (input == null ? 0 : input.Number), (CrestronControlSystem.eDmps34K350COutputs) output.Number); - output.AudioOutSource = (eDmps34KAudioOutSource) input.Number; + output.AudioOutSource = input == null + ? eDmps34KAudioOutSource.NoRoute + : (eDmps34KAudioOutSource)input.Number; } } From be78d17af528822b6815d9c2e78307f237575bd6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Feb 2021 10:02:34 -0700 Subject: [PATCH 137/480] update Blade chassis ports --- .../Chassis/DmBladeChassisController.cs | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index cee6a955..e4126411 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -367,34 +367,28 @@ namespace PepperDash.Essentials.DM { } void AddHdmiOutBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, number); + AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]); } void AddDmOutBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, number); + AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]); } void AddDmOutMmFiberBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, number); + AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]); } void AddDmOutSmFiberBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, number); + AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]); } /// /// Adds InputPort /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) - { - FeedbackMatchObject = Chassis.Inputs[cardNum] - }; - - InputPorts.Add(inputPort); + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) + { + AddInputPortWithDebug(cardNum, portName, sigType, portType, null); } /// @@ -405,7 +399,7 @@ namespace PepperDash.Essentials.DM { { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this) + var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) { FeedbackMatchObject = Chassis.Inputs[cardNum] }; From 1990201215a01fd9d71009f2956c22c75cb2ea74 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Feb 2021 10:11:57 -0700 Subject: [PATCH 138/480] add none ports to DMPS & Blade chassis --- .../Chassis/DmBladeChassisController.cs | 6 +++ .../Chassis/DmpsRoutingController.cs | 40 +++++++++---------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index e4126411..5b2995da 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -23,6 +23,8 @@ namespace PepperDash.Essentials.DM { /// public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback { + private const string NonePortKey = "inputCard0--None"; + public DMChassisPropertiesConfig PropertiesConfig { get; set; } public Switch Chassis { get; private set; } @@ -112,6 +114,10 @@ namespace PepperDash.Essentials.DM { controller.AddVolumeControl(outNum, audio); } + controller.InputPorts.Add(new RoutingInputPort(NonePortKey, eRoutingSignalType.Video, + eRoutingPortConnectionType.None, null, controller)); + + controller.InputNames = properties.InputNames; controller.OutputNames = properties.OutputNames; controller.PropertiesConfig = properties; diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index e6bec335..4c110905 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -21,6 +21,8 @@ namespace PepperDash.Essentials.DM { public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumericWithFeedback, IHasFeedback { + private const string NonePortKey = "none"; + public CrestronControlSystem Dmps { get; set; } public ISystemControl SystemControl { get; private set; } @@ -75,20 +77,18 @@ namespace PepperDash.Essentials.DM { try { - - ISystemControl systemControl = null; - - systemControl = Global.ControlSystem.SystemControl as ISystemControl; + var systemControl = Global.ControlSystem.SystemControl; if (systemControl == null) { return null; } - var controller = new DmpsRoutingController(key, name, systemControl); - - controller.InputNames = properties.InputNames; - controller.OutputNames = properties.OutputNames; + var controller = new DmpsRoutingController(key, name, systemControl) + { + InputNames = properties.InputNames, + OutputNames = properties.OutputNames + }; if (!string.IsNullOrEmpty(properties.NoRouteText)) controller.NoRouteText = properties.NoRouteText; @@ -96,9 +96,9 @@ namespace PepperDash.Essentials.DM return controller; } - catch (System.Exception e) + catch (Exception e) { - Debug.Console(0, "Error getting DMPS Controller:\r{0}", e); + Debug.Console(0, "Error getting DMPS Controller:\r\n{0}", e); } return null; } @@ -113,6 +113,7 @@ namespace PepperDash.Essentials.DM public DmpsRoutingController(string key, string name, ISystemControl systemControl) : base(key, name) { + Dmps = Global.ControlSystem; SystemControl = systemControl; @@ -427,14 +428,11 @@ namespace PepperDash.Essentials.DM { Debug.Console(1, this, "Adding Input Card Number {0} Type: {1}", inputCard.Number, inputCard.CardInputOutputType.ToString()); - InputEndpointOnlineFeedbacks[inputCard.Number] = new BoolFeedback(() => { return inputCard.EndpointOnlineFeedback; }); + InputEndpointOnlineFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.EndpointOnlineFeedback); if (inputCard.VideoDetectedFeedback != null) { - VideoInputSyncFeedbacks[inputCard.Number] = new BoolFeedback(() => - { - return inputCard.VideoDetectedFeedback.BoolValue; - }); + VideoInputSyncFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.VideoDetectedFeedback.BoolValue); } InputNameFeedbacks[inputCard.Number] = new StringFeedback(() => @@ -443,13 +441,10 @@ namespace PepperDash.Essentials.DM { Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue); return inputCard.NameFeedback.StringValue; + } - } - else - { - Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number); - return ""; - } + Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number); + return ""; }); AddInputCard(inputCard.Number, inputCard); @@ -459,6 +454,9 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "***********Input Card of type {0} is cannot be cast as DMInput*************", card.CardInputOutputType); } } + + InputPorts.Add(new RoutingInputPort(NonePortKey, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.None, null, this)); } /// From 51f294c37f89dd5182fa619ff3ebe6cd012599b0 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Feb 2021 13:27:32 -0700 Subject: [PATCH 139/480] fix ExecuteSwitchNumeric for 0 --- .../Essentials_DM/Chassis/DmBladeChassisController.cs | 2 +- .../Essentials DM/Essentials_DM/Chassis/DmChassisController.cs | 2 +- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index 5b2995da..97140f0e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -633,7 +633,7 @@ namespace PepperDash.Essentials.DM { public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { - var input = Chassis.Inputs[inputSelector]; + var input = inputSelector == 0 ? null : Chassis.Inputs[inputSelector]; var output = Chassis.Outputs[outputSelector]; ExecuteSwitch(input, output, sigType); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 63099e60..4d5826b5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1302,7 +1302,7 @@ namespace PepperDash.Essentials.DM return; } - var inputCard = Chassis.Inputs[inputSelector]; + var inputCard = inputSelector == 0 ? null : Chassis.Inputs[inputSelector]; var outputCard = Chassis.Outputs[outputSelector]; ExecuteSwitch(inputCard, outputCard, sigType); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 4c110905..248518aa 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -932,7 +932,7 @@ namespace PepperDash.Essentials.DM public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { - var input = Dmps.SwitcherInputs[inputSelector]; + var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector]; var output = Dmps.SwitcherOutputs[outputSelector]; ExecuteSwitch(input, output, sigType); From 7078ba55c7d196b12607708a498acc176ccf2611 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 23 Feb 2021 13:21:01 -0700 Subject: [PATCH 140/480] fix dmps off timer --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 248518aa..d88af7f4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -820,7 +820,7 @@ namespace PepperDash.Essentials.DM { if (RouteOffTimers.ContainsKey(pnt)) return; - RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(0, pnt.Number, pnt.Type), RouteOffTime); + RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); } #region IRouting Members From eef3b5fb3152a670f8d55efac9f86053bf736bf8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 23 Feb 2021 15:53:07 -0700 Subject: [PATCH 141/480] updates & fixes for countdown timer --- .../Timers/CountdownTimer.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs index aabd6436..381a57df 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs @@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Core public string Key { get; private set; } public BoolFeedback IsRunningFeedback { get; private set; } - bool _IsRunning; + bool _isRunning; public IntFeedback PercentFeedback { get; private set; } public StringFeedback TimeRemainingFeedback { get; private set; } @@ -41,34 +41,32 @@ namespace PepperDash.Essentials.Core public SecondsCountdownTimer(string key) { Key = key; - IsRunningFeedback = new BoolFeedback(() => _IsRunning); + IsRunningFeedback = new BoolFeedback(() => _isRunning); TimeRemainingFeedback = new StringFeedback(() => { // Need to handle up and down here. - if (StartTime == null || FinishTime == null) - return ""; var timeSpan = FinishTime - DateTime.Now; if (timeSpan.TotalSeconds < 60) { return Math.Round(timeSpan.TotalSeconds).ToString(); } + else if (timeSpan.TotalSeconds < 0) + { + return "0"; + } else { Debug.Console(2, this, "timeSpan.Minutes == {0}, timeSpan.Seconds == {1}", timeSpan.Minutes, timeSpan.Seconds); - return String.Format("{0:D2}:{1:D2}", - timeSpan.Minutes, - timeSpan.Seconds); + return String.Format("{0:c}", timeSpan); } }); PercentFeedback = new IntFeedback(() => { - if (StartTime == null || FinishTime == null) - return 0; - double percent = (FinishTime - DateTime.Now).TotalSeconds + var percent = (FinishTime - DateTime.Now).TotalSeconds / (FinishTime - StartTime).TotalSeconds * 100; return (int)percent; @@ -80,7 +78,7 @@ namespace PepperDash.Essentials.Core /// public void Start() { - if (_IsRunning) + if (_isRunning) return; StartTime = DateTime.Now; FinishTime = StartTime + TimeSpan.FromSeconds(SecondsToCount); @@ -88,7 +86,7 @@ namespace PepperDash.Essentials.Core if (SecondTimer != null) SecondTimer.Stop(); SecondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000); - _IsRunning = true; + _isRunning = true; IsRunningFeedback.FireUpdate(); var handler = HasStarted; @@ -101,7 +99,7 @@ namespace PepperDash.Essentials.Core /// public void Reset() { - _IsRunning = false; + _isRunning = false; Start(); } @@ -133,7 +131,7 @@ namespace PepperDash.Essentials.Core { if (SecondTimer != null) SecondTimer.Stop(); - _IsRunning = false; + _isRunning = false; IsRunningFeedback.FireUpdate(); } From b20009b24738ef0b432851ce5aebbd1333d6fdc8 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 24 Feb 2021 14:27:11 -0700 Subject: [PATCH 142/480] add Math.Floor calls to ignore milliseconds Change formatting for timeRemaining Add logic to prevent initial timeRemaining value from being massive negative value --- .../Timers/CountdownTimer.cs | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs index 381a57df..3678b092 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs @@ -32,7 +32,7 @@ namespace PepperDash.Essentials.Core public DateTime StartTime { get; private set; } public DateTime FinishTime { get; private set; } - CTimer SecondTimer; + private CTimer _secondTimer; /// /// Constructor @@ -49,28 +49,26 @@ namespace PepperDash.Essentials.Core var timeSpan = FinishTime - DateTime.Now; - if (timeSpan.TotalSeconds < 60) + Debug.Console(2, this, + "timeSpan.Minutes == {0}, timeSpan.Seconds == {1}, timeSpan.TotalSeconds == {2}", + timeSpan.Minutes, timeSpan.Seconds, timeSpan.TotalSeconds); + + if (Math.Floor(timeSpan.TotalSeconds) < 60 && Math.Floor(timeSpan.TotalSeconds) >= 0) //ignore milliseconds { - return Math.Round(timeSpan.TotalSeconds).ToString(); - } - else if (timeSpan.TotalSeconds < 0) - { - return "0"; - } - else - { - Debug.Console(2, this, "timeSpan.Minutes == {0}, timeSpan.Seconds == {1}", timeSpan.Minutes, timeSpan.Seconds); - return String.Format("{0:c}", timeSpan); + return String.Format("{0:00}", timeSpan.Seconds); } + + return Math.Floor(timeSpan.TotalSeconds) < 0 + ? "00" + : String.Format("{0:00}:{1:00}", timeSpan.Minutes, timeSpan.Seconds); }); - PercentFeedback = new IntFeedback(() => - { - var percent = (FinishTime - DateTime.Now).TotalSeconds - / (FinishTime - StartTime).TotalSeconds - * 100; - return (int)percent; - }); + PercentFeedback = + new IntFeedback( + () => + (int) + (Math.Floor((FinishTime - DateTime.Now).TotalSeconds)/ + Math.Floor((FinishTime - StartTime).TotalSeconds)*100)); } /// @@ -83,9 +81,9 @@ namespace PepperDash.Essentials.Core StartTime = DateTime.Now; FinishTime = StartTime + TimeSpan.FromSeconds(SecondsToCount); - if (SecondTimer != null) - SecondTimer.Stop(); - SecondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000); + if (_secondTimer != null) + _secondTimer.Stop(); + _secondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000); _isRunning = true; IsRunningFeedback.FireUpdate(); @@ -129,19 +127,22 @@ namespace PepperDash.Essentials.Core void StopHelper() { - if (SecondTimer != null) - SecondTimer.Stop(); + if (_secondTimer != null) + _secondTimer.Stop(); _isRunning = false; IsRunningFeedback.FireUpdate(); } void SecondElapsedTimerCallback(object o) { + if (DateTime.Now >= FinishTime) + { + Finish(); + return; + } + PercentFeedback.FireUpdate(); TimeRemainingFeedback.FireUpdate(); - - if (DateTime.Now >= FinishTime) - Finish(); } } } \ No newline at end of file From 9f840fae416ba231c7c10c1c6f894785e381c33b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Feb 2021 16:53:35 -0700 Subject: [PATCH 143/480] add DestinationListItem --- .../Devices/DestinationListItem.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs new file mode 100644 index 00000000..369e2a95 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs @@ -0,0 +1,50 @@ +using Newtonsoft.Json; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core +{ + public class DestinationListItem + { + [JsonProperty("sinkKey")] + public string SinkKey { get; set; } + + private EssentialsDevice _sinkDevice; + + [JsonIgnore] + public EssentialsDevice SinkDevice + { + get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); } + } + + public string PreferredName + { + get + { + if (!string.IsNullOrEmpty(Name)) + { + return Name; + } + + return SinkDevice == null ? "---" : SinkDevice.Name; + } + } + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("includeInDestinationList")] + public bool IncludeInDestinationList { get; set; } + + [JsonProperty("order")] + public int Order { get; set; } + + [JsonProperty("surfaceLocation")] + public int SurfaceLocation { get; set; } + + [JsonProperty("verticalLocation")] + public int VerticalLocation { get; set; } + + [JsonProperty("horizontalLocation")] + public int HorizontalLocation { get; set; } + } +} \ No newline at end of file From 0649cea367d092b4604f1202be25dfa6d600dac7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Feb 2021 16:53:51 -0700 Subject: [PATCH 144/480] Add DestinationLists to config --- .../Config/BasicConfig.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index 7cbaa5a1..ee52e1ef 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using Crestron.SimplSharp; using Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.Core; using Newtonsoft.Json.Linq; @@ -25,7 +20,10 @@ namespace PepperDash.Essentials.Core.Config [JsonProperty("sourceLists")] public Dictionary> SourceLists { get; set; } - [JsonProperty("tieLines")] + [JsonProperty("destinationLists")] + public Dictionary> DestinationLists { get; set; } + + [JsonProperty("tieLines")] public List TieLines { get; set; } [JsonProperty("joinMaps")] @@ -42,6 +40,16 @@ namespace PepperDash.Essentials.Core.Config return SourceLists[key]; } + public Dictionary GetDestinationListForKey(string key) + { + if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key)) + { + return null; + } + + return DestinationLists[key]; + } + /// /// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null /// From 0dcbb652df946c21c2467fed462d69587373d511 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Feb 2021 17:00:57 -0700 Subject: [PATCH 145/480] add properties to SourceListItem add XML Comments --- .../PepperDashEssentialsBase/Config/BasicConfig.cs | 5 +++++ .../Devices/SourceListItem.cs | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index ee52e1ef..dfab0e09 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -40,6 +40,11 @@ namespace PepperDash.Essentials.Core.Config return SourceLists[key]; } + /// + /// Retrieves a DestinationListItem based on the key + /// + /// key of the item to retrieve + /// DestinationListItem if the key exists, null otherwise public Dictionary GetDestinationListForKey(string key) { if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key)) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs index 601d75a7..e302a2a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/SourceListItem.cs @@ -130,10 +130,24 @@ namespace PepperDash.Essentials.Core [JsonProperty("sourceListKey")] public string SourceListKey { get; set; } + /// + /// Indicates if the device associated with this source is controllable + /// + [JsonProperty("isControllable")] + public bool IsControllable { get; set; } + + /// + /// Indicates that the device associated with this source has audio available + /// + [JsonProperty("isAudioSource")] + public bool IsAudioSource { get; set; } + public SourceListItem() { Icon = "Blank"; } + + } public class SourceRouteListItem From 7c7ae65d401159c7276e31f6c3642f48364190ca Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 25 Feb 2021 17:01:24 -0700 Subject: [PATCH 146/480] Update PepperDash_Essentials_Core.csproj --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index cf5587dd..d9357d9e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -189,6 +189,7 @@ + From f25219c20a7f40f97210d6ca041e776ccd02bdcf Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 26 Feb 2021 12:35:17 -0700 Subject: [PATCH 147/480] update docker.yml to create a release on all builds --- .github/workflows/docker.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 003b1f66..9e85ad09 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -78,16 +78,9 @@ jobs: with: name: Version path: ${{env.GITHUB_HOME}}\output\version.txt - # Create the release on the source repo - - name: Create tag for non-rc builds - if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta') - run: | - git tag $($Env:VERSION) - git push --tags origin - name: Create Release id: create_release # using contributor's version to allow for pointing at the right commit - if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-') uses: fleskesvor/create-release@feature/support-target-commitish with: tag_name: ${{ env.VERSION }} From 00589488ac17154ac824630e60e4cf4b3cf611f7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 26 Feb 2021 14:16:53 -0700 Subject: [PATCH 148/480] Adds null check for _worker before checking thread state --- .../PepperDashEssentialsBase/Utilities/ActionSequence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs index bc1e8a4e..90c99579 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Utilities/ActionSequence.cs @@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Utilities /// public void StartSequence() { - if (_worker.ThreadState == Thread.eThreadStates.ThreadRunning) + if (_worker !=null && _worker.ThreadState == Thread.eThreadStates.ThreadRunning) { Debug.Console(1, this, "Thread already running. Cannot Start Sequence"); return; From d2ebc340bd6246aec50d56e1e0df670da4058452 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 1 Mar 2021 15:15:50 -0700 Subject: [PATCH 149/480] add Sink Type property --- .../PepperDashEssentialsBase/Devices/DestinationListItem.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs index 369e2a95..1c7ad835 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs @@ -46,5 +46,8 @@ namespace PepperDash.Essentials.Core [JsonProperty("horizontalLocation")] public int HorizontalLocation { get; set; } + + [JsonProperty("sinkType")] + public eRoutingSignalType SinkType { get; set; } } } \ No newline at end of file From f0415d0d059f5f0d527e320fe672665480278ba6 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 2 Mar 2021 11:57:10 -0700 Subject: [PATCH 150/480] Adds new mirroredTuners config property and additional help comments --- .../Room/Config/EssentialsTechRoomConfig.cs | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 06e67f39..4404b377 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -5,30 +5,62 @@ namespace PepperDash.Essentials.Room.Config { public class EssentialsTechRoomConfig { + /// + /// The key of the dummy device used to enable routing + /// [JsonProperty("dummySourceKey")] public string DummySourceKey { get; set; } + /// + /// The keys of the displays assigned to this room + /// [JsonProperty("displays")] - public List Displays; + public List Displays { get; set; } + /// + /// The keys of the tuners assinged to this room + /// [JsonProperty("tuners")] - public List Tuners; + public List Tuners { get; set; } + /// + /// PIN to access the room as a normal user + /// [JsonProperty("userPin")] - public string UserPin; + public string UserPin { get; set; } + /// + /// PIN to access the room as a tech user + /// [JsonProperty("techPin")] - public string TechPin; + public string TechPin { get; set; } + /// + /// Name of the presets file. Path prefix is assumed to be /html/presets/lists/ + /// [JsonProperty("presetsFileName")] - public string PresetsFileName; + public string PresetsFileName { get; set; } [JsonProperty("scheduledEvents")] - public List ScheduledEvents; + public List ScheduledEvents { get; set; } - [JsonProperty("isPrimary")] public bool IsPrimary; + /// + /// Indicates that the room is the primary when true + /// + [JsonProperty("isPrimary")] + public bool IsPrimary { get; set; } - [JsonProperty("isTvPresetsProvider")] public bool IsTvPresetsProvider; + /// + /// Indicates which tuners should mirror preset recall when two rooms are configured in a primary->secondary scenario + /// + [JsonProperty("mirroredTuners")] + public List MirroredTuners { get; set; } + + /// + /// Indicates the room + /// + [JsonProperty("isTvPresetsProvider")] + public bool IsTvPresetsProvider; public EssentialsTechRoomConfig() { From 57f2d7c9389aa70719611efec2cb31c658503e3f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 2 Mar 2021 15:09:24 -0700 Subject: [PATCH 151/480] #637 Updates LinkToApi method to map configured tuners --- .../Room/Config/EssentialsTechRoomConfig.cs | 2 +- .../Room/Types/EssentialsTechRoom.cs | 50 +++++++++++++++---- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs index 4404b377..9ff3a2d2 100644 --- a/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs @@ -54,7 +54,7 @@ namespace PepperDash.Essentials.Room.Config /// Indicates which tuners should mirror preset recall when two rooms are configured in a primary->secondary scenario /// [JsonProperty("mirroredTuners")] - public List MirroredTuners { get; set; } + public Dictionary MirroredTuners { get; set; } /// /// Indicates the room diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index bfa56646..2908642a 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -373,13 +373,30 @@ Params: {2}" uint i; if (_config.IsPrimary) { - i = 0; - foreach (var feedback in CurrentPresetsFeedbacks) + + if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0) { - feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]); - i++; + foreach (var tuner in _config.MirroredTuners) + { + var f = CurrentPresetsFeedbacks[tuner.Value]; + + if (f == null) + { + Debug.Console(1, this, "Unable to find feedback with key: {0}", tuner.Value); + continue; + } + + f.LinkInputSig(trilist.StringInput[(uint)(joinMap.CurrentPreset.JoinNumber + tuner.Key)]); + } } + //i = 0; + //foreach (var feedback in CurrentPresetsFeedbacks) + //{ + // feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]); + // i++; + //} + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) @@ -396,14 +413,29 @@ Params: {2}" return; } - i = 0; - foreach (var setTopBox in _tuners) + + if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0) { - var tuner = setTopBox; + foreach (var tuner in _config.MirroredTuners) + { + var t = _tuners[tuner.Value]; - trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + if (t == null) + { + Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value); + continue; + } - i++; + trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + tuner.Key, s => _tunerPresets.Dial(s, t)); + } + + //foreach (var setTopBox in _tuners) + //{ + // var tuner = setTopBox; + + // trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + + //} } } From 847e106b8d3f7bad487b0a0de43e5431d24c0a65 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 2 Mar 2021 15:34:35 -0700 Subject: [PATCH 152/480] Adds some debug statements at level 1 to help confirm joins are mapped correctly --- .../Room/Types/EssentialsTechRoom.cs | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 2908642a..b8bbc081 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -373,7 +373,7 @@ Params: {2}" uint i; if (_config.IsPrimary) { - + Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring"); if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0) { foreach (var tuner in _config.MirroredTuners) @@ -386,7 +386,9 @@ Params: {2}" continue; } - f.LinkInputSig(trilist.StringInput[(uint)(joinMap.CurrentPreset.JoinNumber + tuner.Key)]); + var join = joinMap.CurrentPreset.JoinNumber + tuner.Key; + f.LinkInputSig(trilist.StringInput[(uint)(join)]); + Debug.Console(1, this, "Linked Current Preset feedback for tuner: {0} to serial join: {1}", tuner.Value, join); } } @@ -412,30 +414,35 @@ Params: {2}" return; } - - - if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0) + else { - foreach (var tuner in _config.MirroredTuners) - { - var t = _tuners[tuner.Value]; + Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring"); - if (t == null) + if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0) + { + foreach (var tuner in _config.MirroredTuners) { - Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value); - continue; + var t = _tuners[tuner.Value]; + + if (t == null) + { + Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value); + continue; + } + + var join = joinMap.CurrentPreset.JoinNumber + tuner.Key; + trilist.SetStringSigAction(join, s => _tunerPresets.Dial(s, t)); + Debug.Console(1, this, "Linked preset recall action for tuner: {0} to serial join: {1}", tuner.Value, join); } - trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + tuner.Key, s => _tunerPresets.Dial(s, t)); + //foreach (var setTopBox in _tuners) + //{ + // var tuner = setTopBox; + + // trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + + //} } - - //foreach (var setTopBox in _tuners) - //{ - // var tuner = setTopBox; - - // trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); - - //} } } From 743accd980b764fca96ade2aef438d6bb9814b38 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 3 Mar 2021 10:03:42 -0700 Subject: [PATCH 153/480] update actions to remove pushes to build repos --- .github/workflows/docker.yml | 157 ----------------------------------- .github/workflows/main.yml | 145 -------------------------------- 2 files changed, 302 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9e85ad09..d429cdc0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -143,160 +143,3 @@ jobs: run: nuget push **/*.nupkg -source github - name: Publish nuget package to nuget.org run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json - # This step always runs and pushes the build to the internal build rep - Internal_Push_Output: - needs: Build_Project - runs-on: windows-latest - steps: - - name: check Github ref - run: ${{toJson(github.ref)}} - # Checkout the repo - - name: Checkout Builds Repo - uses: actions/checkout@v2 - with: - token: ${{ secrets.BUILDS_TOKEN }} - repository: PepperDash-Engineering/essentials-builds - ref: ${{ Env.GITHUB_REF }} - # Download the version artifact from the build job - - name: Download Build Version Info - uses: actions/download-artifact@v1 - with: - name: Version - - name: Check Directory - run: Get-ChildItem "./" - # Set the version number environment variable from the file we just downloaded - - name: Set Version Number - shell: powershell - run: | - Get-ChildItem "./Version" - $version = Get-Content -Path ./Version/version.txt - Write-Host "Version: $version" - echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Remove-Item -Path ./Version/version.txt - Remove-Item -Path ./Version - # Checkout/Create the branch - - name: Create new branch - run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") - # Download the build output into the repo - - name: Download Build output - uses: actions/download-artifact@v1 - with: - name: Build - path: ./ - - name: Check directory - run: Get-ChildItem ./ - # Unzip the build package file - - name: Unzip Build file - run: | - Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ - Remove-Item -Path .\*.zip - - name: Check directory again - run: Get-ChildItem ./ - # Copy Contents of output folder to root directory - - name: Copy Files to root & delete output directory - run: | - Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") - Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ - Remove-Item -Path .\output -Recurse - # Commits the build output to the branch and tags it with the version - - name: Commit build output and tag the commit - shell: powershell - run: | - git config user.email "actions@pepperdash.com" - git config user.name "GitHub Actions" - git add . - $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" - Write-Host "Commit: $commit" - git commit -m $commit - git tag $($Env:VERSION) - # Push the commit - - name: Push to Builds Repo - shell: powershell - run: | - $branch = $($Env:GITHUB_REF) -replace "refs/heads/" - Write-Host "Branch: $branch" - git push -u origin $($branch) --force - # Push the tags - - name: Push tags - run: git push --tags origin - - name: Check Directory - run: Get-ChildItem ./ - # This step only runs if the branch is main or release/ runs and pushes the build to the public build repo - Public_Push_Output: - needs: Build_Project - runs-on: windows-latest - if: contains(github.ref, 'main') || contains(github.ref, '/release/') - steps: - # Checkout the repo - - name: check Github ref - run: ${{toJson(github.ref)}} - - name: Checkout Builds Repo - uses: actions/checkout@v2 - with: - token: ${{ secrets.BUILDS_TOKEN }} - repository: PepperDash/Essentials-Builds - ref: ${{ Env.GITHUB_REF }} - # Download the version artifact from the build job - - name: Download Build Version Info - uses: actions/download-artifact@v1 - with: - name: Version - - name: Check Directory - run: Get-ChildItem "./" - # Set the version number environment variable from the file we just downloaded - - name: Set Version Number - shell: powershell - run: | - Get-ChildItem "./Version" - $version = Get-Content -Path ./Version/version.txt - Write-Host "Version: $version" - echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Remove-Item -Path ./Version/version.txt - Remove-Item -Path ./Version - # Checkout/Create the branch - - name: Create new branch - run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") - # Download the build output into the repo - - name: Download Build output - uses: actions/download-artifact@v1 - with: - name: Build - path: ./ - - name: Check directory - run: Get-ChildItem ./ - # Unzip the build package file - - name: Unzip Build file - run: | - Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ - Remove-Item -Path .\*.zip - - name: Check directory again - run: Get-ChildItem ./ - # Copy Contents of output folder to root directory - - name: Copy Files to root & delete output directory - run: | - Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") - Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ - Remove-Item -Path .\output -Recurse - # Commits the build output to the branch and tags it with the version - - name: Commit build output and tag the commit - shell: powershell - run: | - git config user.email "actions@pepperdash.com" - git config user.name "GitHub Actions" - git add . - $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" - Write-Host "Commit: $commit" - git commit -m $commit - git tag $($Env:VERSION) - # Push the commit - - name: Push to Builds Repo - shell: powershell - run: | - $branch = $($Env:GITHUB_REF) -replace "refs/heads/" - Write-Host "Branch: $branch" - git push -u origin $($branch) --force - # Push the tags - - name: Push tags - run: git push --tags origin - - name: Check Directory - run: Get-ChildItem ./ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1a6a278..dc219ce3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -123,148 +123,3 @@ jobs: run: nuget push **/*.nupkg -source github - name: Publish nuget package to nuget.org run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json - Internal_Push_Output: - needs: Build_Project - runs-on: windows-latest - steps: - # Checkout the repo - - name: Checkout Builds Repo - uses: actions/checkout@v2 - with: - token: ${{ secrets.BUILDS_TOKEN }} - repository: PepperDash-Engineering/essentials-builds - ref: ${{ Env.GITHUB_REF }} - # Download the version artifact from the build job - - name: Download Build Version Info - uses: actions/download-artifact@v1 - with: - name: Version - - name: Check Directory - run: Get-ChildItem "./" - # Set the version number environment variable from the file we just downloaded - - name: Set Version Number - shell: powershell - run: | - Get-ChildItem "./Version" - $version = Get-Content -Path ./Version/version.txt - Write-Host "Version: $version" - echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Remove-Item -Path ./Version/version.txt - Remove-Item -Path ./Version - # Checkout/Create the branch - - name: Checkout main branch - run: git checkout main - # Download the build output into the repo - - name: Download Build output - uses: actions/download-artifact@v1 - with: - name: Build - path: ./ - - name: Check directory - run: Get-ChildItem ./ - # Unzip the build package file - - name: Unzip Build file - run: | - Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ - Remove-Item -Path .\*.zip - - name: Check directory again - run: Get-ChildItem ./ - # Copy Contents of output folder to root directory - - name: Copy Files to root & delete output directory - run: | - Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") - Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ - Remove-Item -Path .\output -Recurse - # Commits the build output to the branch and tags it with the version - - name: Commit build output and tag the commit - shell: powershell - run: | - git config user.email "actions@pepperdash.com" - git config user.name "GitHub Actions" - git add . - $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" - Write-Host "Commit: $commit" - git commit -m $commit - git tag $($Env:VERSION) - # Push the commit - - name: Push to Builds Repo - shell: powershell - run: git push -u origin main --force - # Push the tags - - name: Push tags - run: git push --tags origin - - name: Check Directory - run: Get-ChildItem ./ - # This step only runs if the branch is main or release/ runs and pushes the build to the public build repo - Public_Push_Output: - needs: Build_Project - runs-on: windows-latest - steps: - # Checkout the repo - - name: Checkout Builds Repo - uses: actions/checkout@v2 - with: - token: ${{ secrets.BUILDS_TOKEN }} - repository: PepperDash/Essentials-Builds - ref: ${{ Env.GITHUB_REF }} - # Download the version artifact from the build job - - name: Download Build Version Info - uses: actions/download-artifact@v1 - with: - name: Version - - name: Check Directory - run: Get-ChildItem "./" - # Set the version number environment variable from the file we just downloaded - - name: Set Version Number - shell: powershell - run: | - Get-ChildItem "./Version" - $version = Get-Content -Path ./Version/version.txt - Write-Host "Version: $version" - echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - Remove-Item -Path ./Version/version.txt - Remove-Item -Path ./Version - # Checkout main branch - - name: Create new branch - run: git checkout main - # Download the build output into the repo - - name: Download Build output - uses: actions/download-artifact@v1 - with: - name: Build - path: ./ - - name: Check directory - run: Get-ChildItem ./ - # Unzip the build package file - - name: Unzip Build file - run: | - Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ - Remove-Item -Path .\*.zip - - name: Check directory again - run: Get-ChildItem ./ - # Copy Contents of output folder to root directory - - name: Copy Files to root & delete output directory - run: | - Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") - Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ - Remove-Item -Path .\output -Recurse - # Commits the build output to the branch and tags it with the version - - name: Commit build output and tag the commit - shell: powershell - run: | - git config user.email "actions@pepperdash.com" - git config user.name "GitHub Actions" - git add . - $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" - Write-Host "Commit: $commit" - git commit -m $commit - git tag $($Env:VERSION) - # Push the commit - - name: Push to Builds Repo - shell: powershell - run: git push -u origin main --force - # Push the tags - - name: Push tags - run: git push --tags origin - - name: Check Directory - run: Get-ChildItem ./ From 79fd1f7424b7c563e21262eda5ac7dde3f937d14 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 3 Mar 2021 14:43:42 -0700 Subject: [PATCH 154/480] add destinationListKey property and remove DDVC --- PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs | 2 ++ ...RoomPropertiesConfig.cs => SimplRoomPropertiesConfig.cs} | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) rename PepperDashEssentials/Room/Config/{DDVC01RoomPropertiesConfig.cs => SimplRoomPropertiesConfig.cs} (78%) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 201b583c..7c7e4c49 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -196,6 +196,8 @@ namespace PepperDash.Essentials.Room.Config public string DefaultAudioKey { get; set; } [JsonProperty("sourceListKey")] public string SourceListKey { get; set; } + [JsonProperty("destinationListKey")] + public string DestinationListKey { get; set; } [JsonProperty("defaultSourceItem")] public string DefaultSourceItem { get; set; } diff --git a/PepperDashEssentials/Room/Config/DDVC01RoomPropertiesConfig.cs b/PepperDashEssentials/Room/Config/SimplRoomPropertiesConfig.cs similarity index 78% rename from PepperDashEssentials/Room/Config/DDVC01RoomPropertiesConfig.cs rename to PepperDashEssentials/Room/Config/SimplRoomPropertiesConfig.cs index be779f3a..f0fea9b9 100644 --- a/PepperDashEssentials/Room/Config/DDVC01RoomPropertiesConfig.cs +++ b/PepperDashEssentials/Room/Config/SimplRoomPropertiesConfig.cs @@ -8,19 +8,19 @@ using Newtonsoft.Json; namespace PepperDash.Essentials.Room.Config { - public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig + public class SimplRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig { [JsonProperty("roomPhoneNumber")] public string RoomPhoneNumber { get; set; } [JsonProperty("roomURI")] public string RoomURI { get; set; } [JsonProperty("speedDials")] - public List SpeedDials { get; set; } + public List SpeedDials { get; set; } [JsonProperty("volumeSliderNames")] public List VolumeSliderNames { get; set; } } - public class DDVC01SpeedDial + public class SimplSpeedDial { [JsonProperty("name")] public string Name { get; set; } From e23fe06feffe7c881495c4167ff56a3a3aca8bdb Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 5 Mar 2021 15:32:21 -0700 Subject: [PATCH 155/480] update name change in csproj --- PepperDashEssentials/PepperDashEssentials.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index b7df4b0d..7b548dd5 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -137,7 +137,7 @@ - + From 8ba0920cc02464437e06b9fc30de1ebd060fdc34 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 5 Mar 2021 15:41:22 -0700 Subject: [PATCH 156/480] add jsonProperty decorator for PreferredName --- .../PepperDashEssentialsBase/Devices/DestinationListItem.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs index 1c7ad835..49379e44 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DestinationListItem.cs @@ -16,6 +16,7 @@ namespace PepperDash.Essentials.Core get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); } } + [JsonProperty("preferredName")] public string PreferredName { get From 74231a428d0f8a5214e36992f2fe8481b0b46616 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 5 Mar 2021 17:31:21 -0700 Subject: [PATCH 157/480] removed unnecessary stack trace printing --- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index 01da1c54..543729da 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -381,7 +381,7 @@ namespace PepperDash.Essentials catch (Exception e) { Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}", - loadedAssembly.Name, e, type.Name); + loadedAssembly.Name, e.Message, type.Name); continue; } From f74fa35ca49be3f6e4747b6e3c115a2ad05dfc32 Mon Sep 17 00:00:00 2001 From: Jonathan Arndt Date: Tue, 9 Mar 2021 23:12:57 -0800 Subject: [PATCH 158/480] Solution updated to remove all TX/RX data that device classes are printing when talking to 3rd party devices --- ._packages.config | Bin 0 -> 4096 bytes .../Comm and IR/ConsoleCommMockDevice.cs | 7 ---- .../Comm and IR/GenericComm.cs | 1 - .../Comm and IR/GenericHttpClient.cs | 7 ---- .../PepperDash_Essentials_Core.csproj | 30 +++++++++--------- .../PepperDash_Essentials_DM.csproj | 16 +++++----- .../Essentials Devices Common.csproj | 18 +++++------ 7 files changed, 32 insertions(+), 47 deletions(-) create mode 100644 ._packages.config diff --git a/._packages.config b/._packages.config new file mode 100644 index 0000000000000000000000000000000000000000..fb4e4d515a152bb29b45da17229b4f7d3f5ffea2 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103vTE(|} z0z?PH0-$mMG%bukK2%&PIX_n~v7jI)RWB#8xTLf=H6ukeOGKnpcvUpO=`EQ>l=XnpUEal#`g34eSd;bq#3>)&Fp>$S}zL G{|^B4Fe-BZ literal 0 HcmV?d00001 diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs index f360e52b..8fc31ea5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs @@ -47,13 +47,6 @@ namespace PepperDash.Essentials.Core return true; } - void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) - { - if (Debug.Level == 2) - Debug.Console(2, this, "RX: '{0}'", - ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text); - } - void SendLine(string s) { //if (Debug.Level == 2) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs index db5ef9ec..8380a290 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs @@ -96,7 +96,6 @@ namespace PepperDash.Essentials.Core // this is a permanent event handler. This cannot be -= from event CommPort.TextReceived += (s, a) => { - Debug.Console(2, this, "RX: {0}", a.Text); trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text); }; trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s)); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericHttpClient.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericHttpClient.cs index 87cde373..31342a94 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericHttpClient.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericHttpClient.cs @@ -33,7 +33,6 @@ namespace PepperDash.Essentials.Core string url = string.Format("http://{0}/{1}", Client.HostName, path); request.Url = new UrlParser(url); HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request); - Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url); } public void SendText(string format, params object[] items) { @@ -41,7 +40,6 @@ namespace PepperDash.Essentials.Core string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items)); request.Url = new UrlParser(url); HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request); - Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url); } public void SendTextNoResponse(string format, params object[] items) @@ -50,7 +48,6 @@ namespace PepperDash.Essentials.Core string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items)); request.Url = new UrlParser(url); Client.Dispatch(request); - Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url); } private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request) @@ -63,10 +60,6 @@ namespace PepperDash.Essentials.Core { if (ResponseRecived != null) ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error)); - - Debug.Console(2, this, "GenericHttpClient ResponseReceived"); - Debug.Console(2, this, "RX:{0}", responseReceived.ContentString); - Debug.Console(2, this, "TX:{0}", (request as HttpClientRequest).Url.ToString()); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index cf5587dd..d5bce861 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -48,39 +48,39 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll @@ -89,30 +89,30 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll 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 63b20c98..4f674d9d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -48,15 +48,15 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll @@ -65,26 +65,26 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index bfee822e..6586bd41 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -48,19 +48,19 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll @@ -69,26 +69,26 @@ False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe False False - ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll From 29b77f5629a4dc1e51aba665e9b84308e3749eee Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 10 Mar 2021 17:28:32 -0500 Subject: [PATCH 159/480] Update CecPortController class to implement IBasicCommunicationWithStreamDebuggingB --- .../Comm and IR/CecPortController.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs index 1ab38d89..08358742 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs @@ -11,8 +11,10 @@ using PepperDash.Core; namespace PepperDash.Essentials.Core { - public class CecPortController : Device, IBasicCommunication + public class CecPortController : Device, IBasicCommunicationWithStreamDebugging { + public CommunicationStreamDebugging StreamDebugging { get; private set; } + public event EventHandler BytesReceived; public event EventHandler TextReceived; @@ -23,6 +25,8 @@ namespace PepperDash.Essentials.Core public CecPortController(string key, Func postActivationFunc, EssentialsControlPropertiesConfig config):base(key) { + StreamDebugging = new CommunicationStreamDebugging(key); + AddPostActivationAction(() => { Port = postActivationFunc(config); @@ -57,8 +61,12 @@ namespace PepperDash.Essentials.Core bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); } var textHandler = TextReceived; - if (textHandler != null) - textHandler(this, new GenericCommMethodReceiveTextArgs(s)); + if (textHandler != null) + { + if (StreamDebugging.RxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Recevied: '{0}'", s); + textHandler(this, new GenericCommMethodReceiveTextArgs(s)); + } } #region IBasicCommunication Members @@ -67,6 +75,8 @@ namespace PepperDash.Essentials.Core { if (Port == null) return; + if (StreamDebugging.TxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text); Port.StreamCec.Send.StringValue = text; } @@ -75,6 +85,8 @@ namespace PepperDash.Essentials.Core if (Port == null) return; var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length); + if (StreamDebugging.TxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes)); Port.StreamCec.Send.StringValue = text; } From a583fdb72af98f1a660d31712b4200232a095c63 Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 11 Mar 2021 12:25:46 -0500 Subject: [PATCH 160/480] Update StreamDebugging on receive for both CECPortController and ComPortController --- .../Comm and IR/CecPortController.cs | 6 ++++-- .../Comm and IR/ComPortController.cs | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs index 08358742..203c2f1a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CecPortController.cs @@ -54,17 +54,19 @@ namespace PepperDash.Essentials.Core void OnDataReceived(string s) { - var bytesHandler = BytesReceived; + var bytesHandler = BytesReceived; if (bytesHandler != null) { var bytes = Encoding.GetEncoding(28591).GetBytes(s); + if (StreamDebugging.RxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes)); bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); } var textHandler = TextReceived; if (textHandler != null) { if (StreamDebugging.RxStreamDebuggingIsEnabled) - Debug.Console(0, this, "Recevied: '{0}'", s); + Debug.Console(0, this, "Received: '{0}'", s); textHandler(this, new GenericCommMethodReceiveTextArgs(s)); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs index 75e9ae72..6d454ac5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ComPortController.cs @@ -92,18 +92,20 @@ namespace PepperDash.Essentials.Core void OnDataReceived(string s) { + var bytesHandler = BytesReceived; if (bytesHandler != null) { var bytes = Encoding.GetEncoding(28591).GetBytes(s); + if (StreamDebugging.RxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes)); bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes)); } var textHandler = TextReceived; if (textHandler != null) { - if (StreamDebugging.RxStreamDebuggingIsEnabled) - Debug.Console(0, this, "Recevied: '{0}'", s); - + if (StreamDebugging.RxStreamDebuggingIsEnabled) + Debug.Console(0, this, "Received: '{0}'", s); textHandler(this, new GenericCommMethodReceiveTextArgs(s)); } } From 00d2159d06bc3849bd73a705963c6b9f4def5ff8 Mon Sep 17 00:00:00 2001 From: Jonathan Arndt Date: Thu, 11 Mar 2021 11:14:59 -0800 Subject: [PATCH 161/480] Reset branch HEAD to f74fa35c commit. Removed all TX: and RX: Console.Debug statements and built successfully. --- .../Comm and IR/ConsoleCommMockDevice.cs | 2 +- .../DSP/BiampTesira/BiampTesiraForteDsp.cs | 7 ------- .../Environment/Lutron/LutronQuantum.cs | 1 - .../ImageProcessors/AnalogWay/AnalongWayLiveCore.cs | 10 +--------- .../ImageProcessors/TVOneCorio.cs | 8 +------- .../Power Controllers/Digitallogger.cs | 5 ----- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 2 +- 7 files changed, 4 insertions(+), 31 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs index 8fc31ea5..db06d2aa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/ConsoleCommMockDevice.cs @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core { Communication = comm; PortGather = new CommunicationGather(Communication, '\x0d'); - PortGather.LineReceived += this.Port_LineReceived; + //PortGather.LineReceived += this.Port_LineReceived; CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties); LineEnding = props.LineEnding; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs index 2af9586e..a171b672 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/DSP/BiampTesira/BiampTesiraForteDsp.cs @@ -165,12 +165,6 @@ namespace PepperDash.Essentials.Devices.Common.DSP /// private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) { - if (Debug.Level == 2) - Debug.Console(2, this, "RX: '{0}'", - ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text); - - Debug.Console(1, this, "RX: '{0}'", args.Text); - try { if (args.Text.IndexOf("Welcome to the Tesira Text Protocol Server...") > -1) @@ -288,7 +282,6 @@ namespace PepperDash.Essentials.Devices.Common.DSP /// Command to send public void SendLine(string s) { - Debug.Console(1, this, "TX: '{0}'", s); Communication.SendText(s + "\x0a"); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs index 23bbc913..f2d030e8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Environment/Lutron/LutronQuantum.cs @@ -232,7 +232,6 @@ namespace PepperDash.Essentials.Devices.Common.Environment.Lutron /// public void SendLine(string s) { - Debug.Console(2, this, "TX: '{0}'", s); Communication.SendText(s + Delimiter); } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs index 97d8a8dd..742ff6f6 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/AnalogWay/AnalongWayLiveCore.cs @@ -133,7 +133,6 @@ namespace PepperDash.Essentials.Devices.Common /// void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) { - Debug.Console(2, this, "TVOneCurio RX: '{0}'", args.Text); try { if (args.Text.IndexOf("login") > -1) @@ -142,24 +141,18 @@ namespace PepperDash.Essentials.Devices.Common } else if (args.Text.IndexOf("!Done Preset.Take =") > -1) { - string presetNumberParse = args.Text.Remove(0, args.Text.IndexOf("=") + 2); Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse); CurrentPreset = ushort.Parse(presetNumberParse); PresetFeedback.FireUpdate(); - - - } - - + } } catch (Exception e) { if (Debug.Level == 2) Debug.Console(2, this, "Error parsing response: '{0}'\n{1}", args.Text, e); } - } /// @@ -168,7 +161,6 @@ namespace PepperDash.Essentials.Devices.Common /// Command to send public void SendLine(string s) { - Debug.Console(1, this, "TVOne Cusio TX: '{0}'", s); Communication.SendText(s + "\x0d\x0a"); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs index b5a1004f..4bcbf340 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/ImageProcessors/TVOneCorio.cs @@ -133,7 +133,6 @@ namespace PepperDash.Essentials.Devices.Common /// void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) { - Debug.Console(2, this, "TVOneCurio RX: '{0}'", args.Text); try { if (args.Text.IndexOf("login") > -1) @@ -148,11 +147,7 @@ namespace PepperDash.Essentials.Devices.Common Debug.Console(1, this, "Preset Parse: {0}", presetNumberParse); CurrentPreset = ushort.Parse(presetNumberParse); PresetFeedback.FireUpdate(); - - - } - - + } } catch (Exception e) { @@ -168,7 +163,6 @@ namespace PepperDash.Essentials.Devices.Common /// Command to send public void SendLine(string s) { - Debug.Console(1, this, "TVOne Cusio TX: '{0}'", s); Communication.SendText(s + "\x0d\x0a"); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs index 2a079c97..ee33b5e6 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Power Controllers/Digitallogger.cs @@ -219,8 +219,6 @@ namespace PepperDash.Essentials.Devices.Common string url = string.Format("http://{0}{1}", this.address, s); request.Url = new UrlParser(url); HttpClientResponse response = WebClient.Dispatch(request); - - Debug.Console(2, this, "DigitalLogger TX:\n'{0}'\nRX:\n'{1}'", url, response.ContentString); return response.ContentString; } /// @@ -236,9 +234,6 @@ namespace PepperDash.Essentials.Devices.Common request.Url = new UrlParser(url); HttpClientResponse response = WebClient.Dispatch(request); - - Debug.Console(2, this, "DigitalLogger TX:\n'{0}'\nRX:\n'{1}'", url, response.ContentString); - } public void CycleCircuit(uint circuit) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index af7233fb..5e2b647e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -637,7 +637,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { if (CommDebuggingIsOn) { - if(!JsonFeedbackMessageIsIncoming) + if (!JsonFeedbackMessageIsIncoming) Debug.Console(1, this, "RX: '{0}'", args.Text); } From 846e905ae1b7277caabb6d274a124ea6ed9e0532 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 12 Mar 2021 14:18:03 -0700 Subject: [PATCH 162/480] Removes check from scheduler method that was functioning incorrectly. --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index b8bbc081..232ab83c 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -183,11 +183,12 @@ namespace PepperDash.Essentials var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key]; - if (!SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) && - !SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days)) - { - return; - } + //if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) && + // SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days)) + //{ + // Debug.Console(1, this, "Existing event matches new event properties. Nothing to update"); + // return; + //} Debug.Console(1, this, "Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration", From 4a9b1514e3f60adc7f2c82e52f24baab954d591c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 12 Mar 2021 15:46:08 -0700 Subject: [PATCH 163/480] fix old/wrong namespace versions --- .../JoinMaps/GlsPartitionSensorJoinMap.cs | 127 ++- .../JoinMaps/VideoCodecControllerJoinMap.cs | 885 +++++++++++++++++- .../DeviceTypeInterfaces/IHasBranding.cs | 5 +- .../DeviceTypeInterfaces/IHasPhoneDialing.cs | 9 +- .../ILanguageDefinition.cs | 11 +- .../DeviceTypeInterfaces/ILanguageProvider.cs | 5 +- .../DeviceTypeInterfaces/LanguageLabel.cs | 6 +- .../Factory/ReadyEventArgs.cs | 11 +- .../Queues/ComsMessage.cs | 50 +- .../Queues/GenericQueue.cs | 150 ++- .../PepperDashEssentialsBase/Queues/IQueue.cs | 4 +- .../Queues/IQueueMessage.cs | 3 +- .../Queues/ProcessStringMessage.cs | 31 +- .../Queues/StringResponseProcessor.cs | 4 +- 14 files changed, 1274 insertions(+), 27 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs index b7af7cdf..3854a4fb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs @@ -146,16 +146,139 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps /// /// [Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")] - public class GlsPartitionSensorJoinMap : PepperDash.Essentials.Core.Bridges.JoinMaps.GlsPartitionSensorJoinMap + public class GlsPartitionSensorJoinMap:JoinMapBaseAdvanced { + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("Enable")] + public JoinDataComplete Enable = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Enable", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PartitionSensed")] + public JoinDataComplete PartitionSensed = new JoinDataComplete( + new JoinData + { + JoinNumber = 3, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Partition Sensed", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PartitionNotSensed")] + public JoinDataComplete PartitionNotSensed = new JoinDataComplete( + new JoinData + { + JoinNumber = 4, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Partition Not Sensed", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncreaseSensitivity")] + public JoinDataComplete IncreaseSensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 6, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Increase Sensitivity", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DecreaseSensitivity")] + public JoinDataComplete DecreaseSensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 7, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Decrease Sensitivity", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Sensitivity")] + public JoinDataComplete Sensitivity = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Sensitivity", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + /// + /// Constructor to use when instantiating this Join Map without inheriting from it + /// + /// Join this join map will start at public GlsPartitionSensorJoinMap(uint joinStart) : this(joinStart, typeof(GlsPartitionSensorJoinMap)) { } - protected GlsPartitionSensorJoinMap(uint joinStart, Type type) : base(joinStart, type) + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + protected GlsPartitionSensorJoinMap(uint joinStart, Type type) + : base(joinStart, type) { + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 2651f929..284b8043 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -895,15 +895,892 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps namespace PepperDash_Essentials_Core.Bridges.JoinMaps { [Obsolete("Use PepperDash.Essentials.Core.Bridges.JoinMaps")] - public class VideoCodecControllerJoinMap : PepperDash.Essentials.Core.Bridges.JoinMaps.VideoCodecControllerJoinMap + public class VideoCodecControllerJoinMap :JoinMapBaseAdvanced { - public VideoCodecControllerJoinMap(uint joinStart) : this(joinStart, typeof (VideoCodecControllerJoinMap)) + #region Status + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Device is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Direction", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = + new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Layout Toggle", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraLayoutStringFb")] + public JoinDataComplete CameraLayoutStringFb = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Layout Fb", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = + new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Auto", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = + new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Manual", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = + new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = + new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Number Select/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = + new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Left", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = + new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Right", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPresetNames")] + public JoinDataComplete CameraPresetNames = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Names - XSIG, max of 15", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraPresetSelect")] + public JoinDataComplete CameraPresetSelect = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Select", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPresetSave")] + public JoinDataComplete CameraPresetSave = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Save Selected Preset", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Self View Toggle/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = + new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Auto Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = + new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Off Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = + new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = + new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = + new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom In", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = + new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom Out", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallData = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Dial String", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentParticipants")] + public JoinDataComplete CurrentParticipants = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata() + { + Description = "Current Participants XSig", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentSource")] + public JoinDataComplete CurrentSource = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Source", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DialMeeting1")] + public JoinDataComplete DialMeeting1 = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join first meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting2")] + public JoinDataComplete DialMeeting2 = + new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join second meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting3")] + public JoinDataComplete DialMeeting3 = + new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join third meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = + new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial selected directory line", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntries")] + public JoinDataComplete DirectoryEntries = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Entries - XSig, 255 entries", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Selected Entry Is Contact FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = + new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = + new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = + new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go back one directory level", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryHasChanged")] + public JoinDataComplete DirectoryHasChanged = + new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory has changed FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory is on Root FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Line Selected FB", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = + new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go to Directory Root", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Row Count FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search Busy FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Select Row", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = + new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Folder Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("0")] + public JoinDataComplete Dtmf0 = + new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 0", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("1")] + public JoinDataComplete Dtmf1 = + new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 1", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("2")] + public JoinDataComplete Dtmf2 = + new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 2", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("3")] + public JoinDataComplete Dtmf3 = + new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 3", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("4")] + public JoinDataComplete Dtmf4 = + new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 4", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("5")] + public JoinDataComplete Dtmf5 = + new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 5", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("6")] + public JoinDataComplete Dtmf6 = + new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 6", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("7")] + public JoinDataComplete Dtmf7 = + new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 7", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("8")] + public JoinDataComplete Dtmf8 = + new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 8", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("9")] + public JoinDataComplete Dtmf9 = + new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 9", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("#")] + public JoinDataComplete DtmfPound = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF #", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("*")] + public JoinDataComplete DtmfStar = + new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF *", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndCall")] + public JoinDataComplete EndCall = + new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("HookState")] + public JoinDataComplete HookState = + new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Hook State", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Answer Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = + new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Reject Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("ManualDial")] + public JoinDataComplete ManualDial = + new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial manual string", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Meeting Count Fb")] + public JoinDataComplete MeetingCount = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Meeting Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteToggle")] + public JoinDataComplete MicMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MinutesBeforeMeetingStart")] + public JoinDataComplete MinutesBeforeMeetingStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Minutes before meeting start that a meeting is joinable", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ParticipantCount")] + public JoinDataComplete ParticipantCount = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Participant Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("Schedule")] + public JoinDataComplete Schedule = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Schedule Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("AutoShareWhileInCall")] + public JoinDataComplete SourceShareAutoStart = + new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, + new JoinMetadata + { + Description = "When high, will autostart sharing when a call is joined", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareEnd")] + public JoinDataComplete SourceShareEnd = + new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Stop Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareStart")] + public JoinDataComplete SourceShareStart = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Start Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("RecievingContent")] + public JoinDataComplete RecievingContent = + new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Recieving content from the far end", + JoinType = eJoinType.Digital, + JoinCapabilities = eJoinCapabilities.ToSIMPL + }); + + [JoinName("SelfviewPosition")] + public JoinDataComplete SelfviewPosition = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SelfviewPositionFb")] + public JoinDataComplete SelfviewPositionFb = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, + new JoinMetadata + { + Description = "Speed Dial", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("UpdateMeetings")] + public JoinDataComplete UpdateMeetings = + new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Update Meetings", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeDown")] + public JoinDataComplete VolumeDown = + new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeLevel")] + public JoinDataComplete VolumeLevel = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Level", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("VolumeMuteOff")] + public JoinDataComplete VolumeMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOn")] + public JoinDataComplete VolumeMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteToggle")] + public JoinDataComplete VolumeMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeUp")] + public JoinDataComplete VolumeUp = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialPhoneCall")] + public JoinDataComplete DialPhone = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneHookState")] + public JoinDataComplete PhoneHookState = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndPhoneCall")] + public JoinDataComplete HangUpPhone = + new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up PHone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneString")] + public JoinDataComplete PhoneDialString = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Phone Dial String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + public VideoCodecControllerJoinMap(uint joinStart) + : base(joinStart, typeof(VideoCodecControllerJoinMap)) { } - public VideoCodecControllerJoinMap(uint joinStart, Type type) : base(joinStart, type) + public VideoCodecControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) { } } -} \ No newline at end of file + } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs index 5eac89ed..63f4917a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasBranding.cs @@ -12,8 +12,9 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface IHasBranding:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasBranding + public interface IHasBranding { - + bool BrandingEnabled { get; } + void InitializeBranding(string roomKey); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs index 60d60636..7f75adec 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IHasPhoneDialing.cs @@ -1,4 +1,5 @@ using System; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { @@ -16,7 +17,13 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface IHasPhoneDialing:PepperDash.Essentials.Core.DeviceTypeInterfaces.IHasPhoneDialing + public interface IHasPhoneDialing { + BoolFeedback PhoneOffHookFeedback { get; } + StringFeedback CallerIdNameFeedback { get; } + StringFeedback CallerIdNumberFeedback { get; } + void DialPhoneCall(string number); + void EndPhoneCall(); + void SendDtmfToPhone(string digit); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs index cbc7aa5c..abf138a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageDefinition.cs @@ -20,7 +20,16 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface ILanguageDefinition:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageDefinition + public interface ILanguageDefinition { + string LocaleName { get; set; } + string FriendlyName { get; set; } + bool Enable { get; set; } + List UiLabels { get; set; } + List Sources { get; set; } + List Destinations { get; set; } + List SourceGroupNames { get; set; } + List DestinationGroupNames { get; set; } + List RoomNames { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs index f0c1e334..dd48723d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/ILanguageProvider.cs @@ -15,8 +15,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public interface ILanguageProvider:PepperDash.Essentials.Core.DeviceTypeInterfaces.ILanguageProvider + public interface ILanguageProvider { + ILanguageDefinition CurrentLanguage { get; set; } + + event EventHandler CurrentLanguageChanged; } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs index a6143665..c7d26722 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/LanguageLabel.cs @@ -15,7 +15,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash_Essentials_Core.DeviceTypeInterfaces { [Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")] - public class LanguageLabel: PepperDash.Essentials.Core.DeviceTypeInterfaces.LanguageLabel + public class LanguageLabel { + public string Key { get; set; } + public string Description { get; set; } + public string DisplayText { get; set; } + public uint JoinNumber { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs index eceefff5..3c107f6e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/ReadyEventArgs.cs @@ -27,15 +27,20 @@ namespace PepperDash.Essentials.Core namespace PepperDash_Essentials_Core { [Obsolete("Use PepperDash.Essentials.Core")] - public class IsReadyEventArgs : PepperDash.Essentials.Core.IsReadyEventArgs + public class IsReadyEventArgs : EventArgs { - public IsReadyEventArgs(bool data) : base(data) + public bool IsReady { get; set; } + + public IsReadyEventArgs(bool data) { + IsReady = data; } } [Obsolete("Use PepperDash.Essentials.Core")] - public interface IHasReady: PepperDash.Essentials.Core.IHasReady + public interface IHasReady { + event EventHandler IsReadyEvent; + bool IsReady { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs index acf3bbea..3c01032e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ComsMessage.cs @@ -78,15 +78,23 @@ namespace PepperDash_Essentials_Core.Queues /// IBasicCommunication Message for IQueue /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class ComsMessage : PepperDash.Essentials.Core.Queues.ComsMessage + public class ComsMessage : IQueueMessage { + private readonly byte[] _bytes; + private readonly IBasicCommunication _coms; + private readonly string _string; + private readonly bool _isByteMessage; + /// /// Constructor for a string message /// /// IBasicCommunication to send the message /// Message to send - public ComsMessage(IBasicCommunication coms, string message):base(coms, message) + public ComsMessage(IBasicCommunication coms, string message) { + Validate(coms, message); + _coms = coms; + _string = message; } /// @@ -94,8 +102,44 @@ namespace PepperDash_Essentials_Core.Queues /// /// IBasicCommunication to send the message /// Message to send - public ComsMessage(IBasicCommunication coms, byte[] message):base(coms, message) + public ComsMessage(IBasicCommunication coms, byte[] message) { + Validate(coms, message); + _coms = coms; + _bytes = message; + _isByteMessage = true; + } + + private void Validate(IBasicCommunication coms, object message) + { + if (coms == null) + throw new ArgumentNullException("coms"); + + if (message == null) + throw new ArgumentNullException("message"); + } + + /// + /// Dispatchs the string/byte[] to the IBasicCommunication specified + /// + public void Dispatch() + { + if (_isByteMessage) + { + _coms.SendBytes(_bytes); + } + else + { + _coms.SendText(_string); + } + } + + /// + /// Shows either the byte[] or string to be sent + /// + public override string ToString() + { + return _bytes != null ? _bytes.ToString() : _string; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index c2a46d62..66a1faf9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -254,14 +254,44 @@ namespace PepperDash_Essentials_Core.Queues /// Threadsafe processing of queued items with pacing if required /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class GenericQueue : PepperDash.Essentials.Core.Queues.GenericQueue + public class GenericQueue : IQueue { + private readonly string _key; + protected readonly CrestronQueue _queue; + protected readonly Thread _worker; + protected readonly CEvent _waitHandle = new CEvent(); + private bool _delayEnabled; private int _delayTime; private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority; - + /// + /// If the instance has been disposed. + /// + public bool Disposed { get; private set; } + + /// + /// Returns the capacity of the CrestronQueue (fixed Size property) + /// + public int QueueCapacity + { + get + { + return _queue.Size; + } + } + + /// + /// Returns the number of elements currently in the CrestronQueue + /// + public int QueueCount + { + get + { + return _queue.Count; + } + } /// /// Constructor with no thread priority @@ -344,8 +374,122 @@ namespace PepperDash_Essentials_Core.Queues /// /// /// - private GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing):base(key, priority, capacity, pacing) + protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing) { + _key = key; + int cap = 25; // sets default + if (capacity > 0) + { + cap = capacity; // overrides default + } + _queue = new CrestronQueue(cap); + _worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running) + { + Priority = priority + }; + + SetDelayValues(pacing); + } + + private void SetDelayValues(int pacing) + { + _delayEnabled = pacing > 0; + _delayTime = pacing; + + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; + + Dispose(); + }; + } + + /// + /// Thread callback + /// + /// The action used to process dequeued items + /// Null when the thread is exited + private object ProcessQueue(object obj) + { + while (true) + { + IQueueMessage item = null; + + if (_queue.Count > 0) + { + item = _queue.Dequeue(); + if (item == null) + break; + } + if (item != null) + { + try + { + Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString()); + item.Dispatch(); + + if (_delayEnabled) + Thread.Sleep(_delayTime); + } + catch (Exception ex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace); + } + } + else _waitHandle.Wait(); + } + + return null; + } + + public void Enqueue(IQueueMessage item) + { + _queue.Enqueue(item); + _waitHandle.Set(); + } + + /// + /// Disposes the thread and cleans up resources. Thread cannot be restarted once + /// disposed. + /// + public void Dispose() + { + Dispose(true); + CrestronEnvironment.GC.SuppressFinalize(this); + } + + /// + /// Actually does the disposing. If you override this method, be sure to either call the base implementation + /// or clean up all the resources yourself. + /// + /// set to true unless called from finalizer + protected void Dispose(bool disposing) + { + if (Disposed) + return; + + if (disposing) + { + Enqueue(null); + _worker.Join(); + _waitHandle.Close(); + } + + Disposed = true; + } + + ~GenericQueue() + { + Dispose(false); + } + + /// + /// Key + /// + public string Key + { + get { return _key; } } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs index c5198245..15803330 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueue.cs @@ -17,7 +17,9 @@ namespace PepperDash.Essentials.Core.Queues namespace PepperDash_Essentials_Core.Queues { [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public interface IQueue : PepperDash.Essentials.Core.Queues.IQueue where T: class + public interface IQueue : IKeyed, IDisposable where T : class { + void Enqueue(T item); + bool Disposed { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs index 0758e1d8..8ffd4d96 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/IQueueMessage.cs @@ -11,7 +11,8 @@ namespace PepperDash.Essentials.Core.Queues namespace PepperDash_Essentials_Core.Queues { [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public interface IQueueMessage:PepperDash.Essentials.Core.Queues.IQueueMessage + public interface IQueueMessage { + void Dispatch(); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs index 65f02801..d8ea4ada 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/ProcessStringMessage.cs @@ -49,13 +49,40 @@ namespace PepperDash_Essentials_Core.Queues /// Message class for processing strings via an IQueue /// [Obsolete("Use PepperDash.Essentials.Core.Queues")] - public class ProcessStringMessage : PepperDash.Essentials.Core.Queues.ProcessStringMessage + public class ProcessStringMessage : IQueueMessage { + private readonly Action _action; + private readonly string _message; + /// /// Constructor /// /// Message to be processed /// Action to invoke on the message - public ProcessStringMessage(string message, Action action) : base(message, action){} + public ProcessStringMessage(string message, Action action) + { + _message = message; + _action = action; + } + + /// + /// Processes the string with the given action + /// + public void Dispatch() + { + if (_action == null || String.IsNullOrEmpty(_message)) + return; + + _action(_message); + } + + /// + /// To string + /// + /// The current message + public override string ToString() + { + return _message ?? String.Empty; + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs index 6ae61a53..e2db5d72 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/StringResponseProcessor.cs @@ -111,14 +111,14 @@ namespace PepperDash_Essentials_Core.Queues public sealed class StringResponseProcessor : IKeyed, IDisposable { private readonly Action _processStringAction; - private readonly PepperDash.Essentials.Core.Queues.IQueue _queue; + private readonly IQueue _queue; private readonly IBasicCommunication _coms; private readonly CommunicationGather _gather; private StringResponseProcessor(string key, Action processStringAction) { _processStringAction = processStringAction; - _queue = new PepperDash.Essentials.Core.Queues.GenericQueue(key); + _queue = new GenericQueue(key); CrestronEnvironment.ProgramStatusEventHandler += programEvent => { From 8572191c1e9c2ee391bd6dc12eb72ed893ff85c6 Mon Sep 17 00:00:00 2001 From: Jonathan Arndt Date: Fri, 12 Mar 2021 14:57:05 -0800 Subject: [PATCH 164/480] Removed the ._packages.config file from the repo. --- ._packages.config | Bin 4096 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 ._packages.config diff --git a/._packages.config b/._packages.config deleted file mode 100644 index fb4e4d515a152bb29b45da17229b4f7d3f5ffea2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103vTE(|} z0z?PH0-$mMG%bukK2%&PIX_n~v7jI)RWB#8xTLf=H6ukeOGKnpcvUpO=`EQ>l=XnpUEal#`g34eSd;bq#3>)&Fp>$S}zL G{|^B4Fe-BZ From 4e15d7fe5aba51ac6d9338953f910e3670a8a1b5 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 16 Mar 2021 15:36:14 -0600 Subject: [PATCH 165/480] Adds necessary config properteis --- .../Room/Config/EssentialsRoomConfig.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 7c7e4c49..6a59cc56 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -200,7 +200,16 @@ namespace PepperDash.Essentials.Room.Config public string DestinationListKey { get; set; } [JsonProperty("defaultSourceItem")] public string DefaultSourceItem { get; set; } - + /// + /// Indicates if the room supports advanced sharing + /// + [JsonProperty("supportsAdvancedSharing")] + public bool SupportsAdvancedSharing { get; set; } + /// + /// Indicates if non-tech users can change the share mode + /// + [JsonProperty("userCanChangeShareMode")] + public bool UserCanChangeShareMode { get; set; } } public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig From 6ab4d4d090448d5f8e2d84165bf1ba0b51d90653 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Mar 2021 10:52:17 -0600 Subject: [PATCH 166/480] #658 Initializes config properties in constructor(s) --- .../PepperDashEssentialsBase/Config/BasicConfig.cs | 10 ++++++++++ .../Config/Essentials/EssentialsConfig.cs | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs index dfab0e09..f44f6000 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/BasicConfig.cs @@ -29,6 +29,16 @@ namespace PepperDash.Essentials.Core.Config [JsonProperty("joinMaps")] public Dictionary JoinMaps { get; set; } + public BasicConfig() + { + Info = new InfoConfig(); + Devices = new List(); + SourceLists = new Dictionary>(); + DestinationLists = new Dictionary>(); + TieLines = new List(); + JoinMaps = new Dictionary(); + } + /// /// Checks SourceLists for a given list and returns it if found. Otherwise, returns null /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs index cc3375e2..1e819414 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/EssentialsConfig.cs @@ -51,6 +51,13 @@ namespace PepperDash.Essentials.Core.Config [JsonProperty("rooms")] public List Rooms { get; set; } + + + public EssentialsConfig() + : base() + { + Rooms = new List(); + } } /// From 840fb21e153923a07811f35d4f2c446d458a889e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Mar 2021 12:42:29 -0600 Subject: [PATCH 167/480] Added console command to list events for a group --- .../Global/Scheduler.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index fb305172..e07ef496 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -24,6 +24,10 @@ namespace PepperDash.Essentials.Core CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup", + "Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator); + } /// @@ -49,6 +53,33 @@ namespace PepperDash.Essentials.Core } } + static void ListAllEventsForGroup(string args) + { + Debug.Console(0, "Getting events for group {0}...", args); + + ScheduledEventGroup group; + + if (!EventGroups.TryGetValue(args, out group)) + { + Debug.Console(0, "Unabled to get event group for key {0}", args); + return; + } + + foreach (var evt in group.ScheduledEvents) + { + Debug.Console(0, + @" +****Event key {0}**** +Event date/time: {1} +Persistent: {2} +Acknowlegable: {3} +Recurrence: {4} +Recurrence Days: {5} +********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable, + evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays); + } + } + /// /// Adds the event group to the global list /// From a9fce3237cb2db50cb4b2c73b758f3aedf45a712 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Mar 2021 12:43:29 -0600 Subject: [PATCH 168/480] Added check for key to Clear command If the key was wrong or wasn't in the group, a `KeyNotFoundException` was thrown. Also added acknowledgment of a successful deletion --- .../PepperDashEssentialsBase/Global/Scheduler.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index e07ef496..928f5557 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -36,12 +36,26 @@ namespace PepperDash.Essentials.Core /// static void ClearEventsFromGroup(string groupName) { + if (!EventGroups.ContainsKey(groupName)) + { + Debug.Console(0, + "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", + groupName); + return + } + var group = EventGroups[groupName]; if (group != null) + { group.ClearAllEvents(); + + Debug.Console(0, "[Scheduler]: All events deleted from group '{0}'", groupName); + } else - Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName); + Debug.Console(0, + "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", + groupName); } static void ListAllEventGroups(string command) From 085ba134c46109b8d737008d5976f13a2a28397c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Mar 2021 12:44:20 -0600 Subject: [PATCH 169/480] Set event to not be acknowledgable Added logic to acknowledge event Added debug statement to show that event was being fired --- .../Behaviours/RoomOnToDefaultSourceWhenOccupied.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs index 11debb03..f24daf82 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs @@ -169,10 +169,15 @@ namespace PepperDash.Essentials.Core void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type) { + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "{0}:{1} @ {2}", SchEvent.Name, type, DateTime.Now); + if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration) { + SchEvent.Acknowledge(); + if (SchEvent.Name == FeatureEnableEventName) { + if (PropertiesConfig.EnableRoomOnWhenOccupied) FeatureEnabled = true; @@ -248,9 +253,8 @@ namespace PepperDash.Essentials.Core schEvent = new ScheduledEvent(name, FeatureEventGroup); // Set up its initial properties - - if(!schEvent.Acknowledgeable) - schEvent.Acknowledgeable = true; + + schEvent.Acknowledgeable = false; if(!schEvent.Persistent) schEvent.Persistent = true; @@ -287,7 +291,7 @@ namespace PepperDash.Essentials.Core Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString()); - CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime); + //CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime); schEvent.Recurrence.Weekly(eventRecurrennce); From 0228fd1c0f857406c1d4249d36446ece0281d506 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 18 Mar 2021 16:27:08 -0600 Subject: [PATCH 170/480] fix a ; --- .../PepperDashEssentialsBase/Global/Scheduler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 928f5557..960a56ef 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -41,7 +41,7 @@ namespace PepperDash.Essentials.Core Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName); - return + return; } var group = EventGroups[groupName]; From da63d0917ea6a3592ccb148efb1f6d2c06d3646e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 19 Mar 2021 09:03:05 -0600 Subject: [PATCH 171/480] Updates to test new builder image this build WILL fail --- .github/workflows/docker.yml | 2 +- .../PepperDashEssentialsBase/Global/Scheduler.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d429cdc0..1700b2e3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,7 +58,7 @@ jobs: - name: Build Solution shell: powershell run: | - Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder:dev c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" # Zip up the output files as needed - name: Zip Build Output shell: powershell diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 960a56ef..928f5557 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -41,7 +41,7 @@ namespace PepperDash.Essentials.Core Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName); - return; + return } var group = EventGroups[groupName]; From 61b4002e5ad5f2f1add9790de0b5685fa700fe33 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 19 Mar 2021 09:22:21 -0600 Subject: [PATCH 172/480] Fix to test build image again --- .../PepperDashEssentialsBase/Global/Scheduler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs index 928f5557..960a56ef 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Scheduler.cs @@ -41,7 +41,7 @@ namespace PepperDash.Essentials.Core Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName); - return + return; } var group = EventGroups[groupName]; From c4a6d20791149d4171447499cc814dd0fd052818 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Mar 2021 09:23:07 -0600 Subject: [PATCH 173/480] fixing a nullref issue with cisco spark --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index af7233fb..21e5bd3a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -368,21 +368,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecSchedule = new CodecScheduleAwareness(); //Set Feedback Actions - CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; - CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; - CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; - CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate; - CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; - CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; - CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate; - CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate; - CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; - CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; - CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; + SetFeedbackActions(); - CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video, + CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this); @@ -418,7 +406,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco _brandingUrl = props.UiBranding.BrandingUrl; } - /// + private void SetFeedbackActions() + { + CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; + CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; + CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; + CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate; + CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; + CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; + CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate; + CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate; + CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; + CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; + CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; + CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; + try + { + CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; + } + catch (Exception ex) + { + Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex); + + if (ex.InnerException != null) + { + Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex); + } + } + } + + /// /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input /// to enable routing /// From 008279e8677abe120824062f4204fa8fb3cbef6e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Mar 2021 09:39:08 -0600 Subject: [PATCH 174/480] Initialize some properties that were causing a nullRef --- .../VideoCodec/CiscoCodec/xStatus.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 7fa4e655..676737c4 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; +using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { @@ -1680,6 +1681,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public MainVideoSource MainVideoSource { get; set; } public MainVideoMute MainVideoMute { get; set; } public List Source { get; set; } + + public Input2() + { + MainVideoMute = new MainVideoMute(); + } } public class Local : ValueProperty @@ -1875,6 +1881,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { Selfview = new Selfview(); Layout = new Layout(); + Input = new Input2(); } } From 6443e004282a0662cc4604186c35c638332217af Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 22 Mar 2021 09:48:23 -0600 Subject: [PATCH 175/480] update back to latest builder image --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1700b2e3..d429cdc0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,7 +58,7 @@ jobs: - name: Build Solution shell: powershell run: | - Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder:dev c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" # Zip up the output files as needed - name: Zip Build Output shell: powershell From 139e5370ea80491956db92651c6fe1f444fe98f7 Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Mon, 29 Mar 2021 09:42:31 -0400 Subject: [PATCH 176/480] added a Disposed check and Debug Message to prevent enqueing messages after the Generic Queue has been disposed; typically happens at program stop --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 66a1faf9..693c39e5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -199,6 +199,12 @@ namespace PepperDash.Essentials.Core.Queues public void Enqueue(IQueueMessage item) { + if (Disposed) + { + Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?"); + return; + } + _queue.Enqueue(item); _waitHandle.Set(); } From 7fbbc9f2b8a792d3e18dc3942ab3b70dec2273aa Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 29 Mar 2021 12:50:43 -0600 Subject: [PATCH 177/480] Fix LinkToApi methods for chassis to use ExecuteNumericSwitch --- .../Chassis/DmBladeChassisController.cs | 2 +- .../Chassis/DmChassisController.cs | 18 +++++++++--------- .../Chassis/DmpsRoutingController.cs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index 97140f0e..3a4f55c0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -671,7 +671,7 @@ namespace PepperDash.Essentials.DM { var ioSlotJoin = ioSlot - 1; // Control - trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); if (TxDictionary.ContainsKey(ioSlot)) { diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 4d5826b5..72f84f48 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1,7 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using Crestron.SimplSharp; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; @@ -1184,7 +1185,6 @@ namespace PepperDash.Essentials.DM "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, outputSelector); return; - } // Check to see if there's an off timer waiting on this and if so, cancel @@ -1643,13 +1643,13 @@ namespace PepperDash.Essentials.DM { // Routing Control trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); - trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); - trilist.SetUShortSigAction(joinMap.OutputUsb.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput)); - trilist.SetUShortSigAction(joinMap.InputUsb.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput)); + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio)); + trilist.SetUShortSigAction(joinMap.OutputUsb.JoinNumber + ioSlotJoin, + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbOutput)); + trilist.SetUShortSigAction(joinMap.InputUsb.JoinNumber + ioSlotJoin, + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbInput)); //Routing Feedbacks VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index d88af7f4..484293eb 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -228,9 +228,9 @@ namespace PepperDash.Essentials.DM // Control trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, - o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio)); trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s => { From 0f28d46f344474006aecde7205612fad7c993960 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 30 Mar 2021 15:53:10 -0600 Subject: [PATCH 178/480] #671 Calls the private dispose method on program stop --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 693c39e5..36f69e0f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -155,7 +155,7 @@ namespace PepperDash.Essentials.Core.Queues if (programEvent != eProgramStatusEventType.Stopping) return; - Dispose(); + Dispose(true); }; } @@ -407,7 +407,7 @@ namespace PepperDash_Essentials_Core.Queues if (programEvent != eProgramStatusEventType.Stopping) return; - Dispose(); + Dispose(true); }; } From 955d68b3f3632835c6249ecb107db887fdee0cc1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 30 Mar 2021 15:56:05 -0600 Subject: [PATCH 179/480] #671 switches to private Dispose() on program stop --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 693c39e5..36f69e0f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -155,7 +155,7 @@ namespace PepperDash.Essentials.Core.Queues if (programEvent != eProgramStatusEventType.Stopping) return; - Dispose(); + Dispose(true); }; } @@ -407,7 +407,7 @@ namespace PepperDash_Essentials_Core.Queues if (programEvent != eProgramStatusEventType.Stopping) return; - Dispose(); + Dispose(true); }; } From 33a1b1697a6502d238829d3b1ed7ce056d99e604 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 31 Mar 2021 15:29:55 -0600 Subject: [PATCH 180/480] Removes call to dispose on program stop event. Adds debug statement in Dispose() --- .../Queues/GenericQueue.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 36f69e0f..a8b839f4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -150,13 +150,13 @@ namespace PepperDash.Essentials.Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; + //CrestronEnvironment.ProgramStatusEventHandler += programEvent => + //{ + // if (programEvent != eProgramStatusEventType.Stopping) + // return; - Dispose(true); - }; + // Dispose(true); + //}; } /// @@ -231,6 +231,8 @@ namespace PepperDash.Essentials.Core.Queues if (disposing) { + Debug.Console(2, this, "Disposing..."); + _queue.Clear(); Enqueue(null); _worker.Join(); _waitHandle.Close(); @@ -402,13 +404,13 @@ namespace PepperDash_Essentials_Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; + //CrestronEnvironment.ProgramStatusEventHandler += programEvent => + //{ + // if (programEvent != eProgramStatusEventType.Stopping) + // return; - Dispose(true); - }; + // Dispose(true); + //}; } /// @@ -477,6 +479,8 @@ namespace PepperDash_Essentials_Core.Queues if (disposing) { + Debug.Console(2, this, "Disposing..."); + _queue.Clear(); Enqueue(null); _worker.Join(); _waitHandle.Close(); From 2feec6205285d82a961eb9c64ec908b4255cd8d5 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 31 Mar 2021 16:35:33 -0600 Subject: [PATCH 181/480] Removes explicit call to dispose when program stops. Clears queue in dispose --- .../Queues/GenericQueue.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 36f69e0f..f2e8000d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -150,13 +150,13 @@ namespace PepperDash.Essentials.Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; + //CrestronEnvironment.ProgramStatusEventHandler += programEvent => + //{ + // if (programEvent != eProgramStatusEventType.Stopping) + // return; - Dispose(true); - }; + // Dispose(true); + //}; } /// @@ -231,6 +231,8 @@ namespace PepperDash.Essentials.Core.Queues if (disposing) { + Debug.Console(2, this, "Disposing..."); + _queue.Clear(); Enqueue(null); _worker.Join(); _waitHandle.Close(); @@ -402,13 +404,13 @@ namespace PepperDash_Essentials_Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - CrestronEnvironment.ProgramStatusEventHandler += programEvent => - { - if (programEvent != eProgramStatusEventType.Stopping) - return; + //CrestronEnvironment.ProgramStatusEventHandler += programEvent => + //{ + // if (programEvent != eProgramStatusEventType.Stopping) + // return; - Dispose(true); - }; + // Dispose(true); + //}; } /// @@ -477,6 +479,8 @@ namespace PepperDash_Essentials_Core.Queues if (disposing) { + Debug.Console(2, this, "Disposing..."); + _queue.Clear(); Enqueue(null); _worker.Join(); _waitHandle.Close(); From dd0f7a586e8f04806643db079637b2bdbdb0d143 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 2 Apr 2021 09:03:39 -0600 Subject: [PATCH 182/480] fix Console statement and add help --- .../PepperDashEssentialsBase/Devices/DeviceManager.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index 55bc523a..cb8c89db 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -387,6 +387,15 @@ namespace PepperDash.Essentials.Core /// public static void SetDeviceStreamDebugging(string s) { + if (String.IsNullOrEmpty(s) || s.Contains("?")) + { + Debug.Console(0, + @"SETDEVICESTREAMDEBUG [{deviceKey}] [OFF |TX | RX | BOTH] [timeOutInMinutes] + {deviceKey} [OFF | TX | RX | BOTH] - Device to set stream debugging on, and which setting to use + timeOutInMinutes - Set timeout for stream debugging. Default is 30 minutes"); + return; + } + var args = s.Split(' '); var deviceKey = args[0]; @@ -437,7 +446,7 @@ namespace PepperDash.Essentials.Core else { device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting); - Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting); + Debug.Console(0, "Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting); } } From 252d0373802814c663c9ae1125d5bac53a6571f5 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 2 Apr 2021 09:09:13 -0600 Subject: [PATCH 183/480] change to method signature instead of lambda --- .../PepperDashEssentialsBase/Devices/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index cb8c89db..b8e20e9b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -46,7 +46,7 @@ namespace PepperDash.Essentials.Core CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive", "Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator); - CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator); + CrestronConsole.AddNewConsoleCommand(SetDeviceStreamDebugging, "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator); } From e832566168aa59a7bfcf5051b42c4319cef5638b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 2 Apr 2021 09:44:02 -0600 Subject: [PATCH 184/480] change to CrestronConsole.ConsoleCommandResponse for help text --- .../PepperDashEssentialsBase/Devices/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index b8e20e9b..cca16ec7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -389,7 +389,7 @@ namespace PepperDash.Essentials.Core { if (String.IsNullOrEmpty(s) || s.Contains("?")) { - Debug.Console(0, + CrestronConsole.ConsoleCommandResponse( @"SETDEVICESTREAMDEBUG [{deviceKey}] [OFF |TX | RX | BOTH] [timeOutInMinutes] {deviceKey} [OFF | TX | RX | BOTH] - Device to set stream debugging on, and which setting to use timeOutInMinutes - Set timeout for stream debugging. Default is 30 minutes"); From e327d2d359d40049d1c7388a3abf7e529bcd88e1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 2 Apr 2021 16:09:54 -0600 Subject: [PATCH 185/480] passes true when disposing of generic queue in deconstructor --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index a8b839f4..6759d32b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -243,7 +243,7 @@ namespace PepperDash.Essentials.Core.Queues ~GenericQueue() { - Dispose(false); + Dispose(true); } /// @@ -491,7 +491,7 @@ namespace PepperDash_Essentials_Core.Queues ~GenericQueue() { - Dispose(false); + Dispose(true); } /// From 037f8ed043fc66eb8f49b306048365ec842399ae Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 2 Apr 2021 17:07:06 -0600 Subject: [PATCH 186/480] #671 Updates to GenericQueue to resolve issues when stopping program --- .../Queues/GenericQueue.cs | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 6759d32b..e382d16f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -150,13 +150,13 @@ namespace PepperDash.Essentials.Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - //CrestronEnvironment.ProgramStatusEventHandler += programEvent => - //{ - // if (programEvent != eProgramStatusEventType.Stopping) - // return; + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; - // Dispose(true); - //}; + Dispose(true); + }; } /// @@ -232,9 +232,20 @@ namespace PepperDash.Essentials.Core.Queues if (disposing) { Debug.Console(2, this, "Disposing..."); - _queue.Clear(); - Enqueue(null); - _worker.Join(); + if (_queue != null && !_queue.Disposed) + { + _queue.Clear(); + Enqueue(null); + } + //else + //{ + // if (_queue == null) + // Debug.Console(2, this, "_queue is null"); + // else + // Debug.Console(2, this, "_queue disposed: {0}", _queue.Disposed); + //} + //_worker.Join(); + _worker.Abort(); _waitHandle.Close(); } @@ -404,13 +415,13 @@ namespace PepperDash_Essentials_Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - //CrestronEnvironment.ProgramStatusEventHandler += programEvent => - //{ - // if (programEvent != eProgramStatusEventType.Stopping) - // return; + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; - // Dispose(true); - //}; + Dispose(true); + }; } /// @@ -480,9 +491,20 @@ namespace PepperDash_Essentials_Core.Queues if (disposing) { Debug.Console(2, this, "Disposing..."); - _queue.Clear(); - Enqueue(null); - _worker.Join(); + if (_queue != null && !_queue.Disposed) + { + _queue.Clear(); + Enqueue(null); + } + //else + //{ + // if (_queue == null) + // Debug.Console(2, this, "_queue is null"); + // else + // Debug.Console(2, this, "_queue disposed: {0}", _queue.Disposed); + //} + //_worker.Join(); + _worker.Abort(); _waitHandle.Close(); } From 1e755df9bb78a5b9e5a02bb8d6e54a4c569c58d4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 5 Apr 2021 17:01:34 -0600 Subject: [PATCH 187/480] #675 Adds UserPromptedForCode event and method to show code on CiscoSparkCodec --- .../DeviceTypeInterfaces/IMobileControl.cs | 2 ++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index 2dfa7c41..257d58e1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -20,6 +20,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces { event EventHandler UserCodeChanged; + event EventHandler UserPromptedForCode; + string UserCode { get; } string QrCodeUrl { get; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 1cf6ade0..99c47a26 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -490,11 +490,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco Debug.Console(2, this, "Setting QR code URL: {0}", mcBridge.QrCodeUrl); mcBridge.UserCodeChanged += (o, a) => SendMcBrandingUrl(mcBridge); + mcBridge.UserPromptedForCode += (o, a) => DisplayUserCode(mcBridge.UserCode); SendMcBrandingUrl(mcBridge); } } + /// + /// Displays the code for the specified duration + /// + /// Mobile Control user code + private void DisplayUserCode(string code) + { + SendText(string.Format("xcommand userinterface message alert display title:\"Mobile Control User Code:\" text:\"{0}\" duration: 30")); + } + private void SendMcBrandingUrl(IMobileControlRoomBridge mcBridge) { if (mcBridge == null) From ba247ee8d64abf1c8c0438df9709af6872d5aad1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 10:36:03 -0600 Subject: [PATCH 188/480] removes commented code for clarity --- .../Queues/GenericQueue.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index e382d16f..5b737ad4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -237,14 +237,6 @@ namespace PepperDash.Essentials.Core.Queues _queue.Clear(); Enqueue(null); } - //else - //{ - // if (_queue == null) - // Debug.Console(2, this, "_queue is null"); - // else - // Debug.Console(2, this, "_queue disposed: {0}", _queue.Disposed); - //} - //_worker.Join(); _worker.Abort(); _waitHandle.Close(); } @@ -496,14 +488,6 @@ namespace PepperDash_Essentials_Core.Queues _queue.Clear(); Enqueue(null); } - //else - //{ - // if (_queue == null) - // Debug.Console(2, this, "_queue is null"); - // else - // Debug.Console(2, this, "_queue disposed: {0}", _queue.Disposed); - //} - //_worker.Join(); _worker.Abort(); _waitHandle.Close(); } From 200080247a4e23b42cacc28def902752ca48572f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 10:38:39 -0600 Subject: [PATCH 189/480] closes #671 and changes to aborting thread in Dispose instead of attempting to join --- .../Queues/GenericQueue.cs | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index f2e8000d..a5def83d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -14,7 +14,7 @@ namespace PepperDash.Essentials.Core.Queues protected readonly CrestronQueue _queue; protected readonly Thread _worker; protected readonly CEvent _waitHandle = new CEvent(); - + private bool _delayEnabled; private int _delayTime; @@ -150,15 +150,15 @@ namespace PepperDash.Essentials.Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - //CrestronEnvironment.ProgramStatusEventHandler += programEvent => - //{ - // if (programEvent != eProgramStatusEventType.Stopping) - // return; + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; - // Dispose(true); - //}; + Dispose(true); + }; } - + /// /// Thread callback /// @@ -231,10 +231,13 @@ namespace PepperDash.Essentials.Core.Queues if (disposing) { - Debug.Console(2, this, "Disposing..."); - _queue.Clear(); - Enqueue(null); - _worker.Join(); + Debug.Console(2, this, "Disposing..."); + if (_queue != null && !_queue.Disposed) + { + _queue.Clear(); + Enqueue(null); + } + _worker.Abort(); _waitHandle.Close(); } @@ -243,7 +246,7 @@ namespace PepperDash.Essentials.Core.Queues ~GenericQueue() { - Dispose(false); + Dispose(true); } /// @@ -404,13 +407,13 @@ namespace PepperDash_Essentials_Core.Queues _delayEnabled = pacing > 0; _delayTime = pacing; - //CrestronEnvironment.ProgramStatusEventHandler += programEvent => - //{ - // if (programEvent != eProgramStatusEventType.Stopping) - // return; + CrestronEnvironment.ProgramStatusEventHandler += programEvent => + { + if (programEvent != eProgramStatusEventType.Stopping) + return; - // Dispose(true); - //}; + Dispose(true); + }; } /// @@ -479,10 +482,13 @@ namespace PepperDash_Essentials_Core.Queues if (disposing) { - Debug.Console(2, this, "Disposing..."); - _queue.Clear(); - Enqueue(null); - _worker.Join(); + Debug.Console(2, this, "Disposing..."); + if (_queue != null && !_queue.Disposed) + { + _queue.Clear(); + Enqueue(null); + } + _worker.Abort(); _waitHandle.Close(); } @@ -491,7 +497,7 @@ namespace PepperDash_Essentials_Core.Queues ~GenericQueue() { - Dispose(false); + Dispose(true); } /// From cf8e6736773126ad7520b90e99d334e9b104b4bf Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 12:25:33 -0600 Subject: [PATCH 190/480] Adds ClientJoined event --- .../DeviceTypeInterfaces/IMobileControl.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index 257d58e1..c87e7865 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -22,6 +22,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces event EventHandler UserPromptedForCode; + event EventHandler ClientJoined; + string UserCode { get; } string QrCodeUrl { get; } From 22e7f004a5149dc1dfd1ab5a0e4b28a8d90c81b0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 18:06:15 -0600 Subject: [PATCH 191/480] adds missing code parameter --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 99c47a26..09f3e37f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -502,7 +502,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// Mobile Control user code private void DisplayUserCode(string code) { - SendText(string.Format("xcommand userinterface message alert display title:\"Mobile Control User Code:\" text:\"{0}\" duration: 30")); + SendText(string.Format("xcommand userinterface message alert display title:\"Mobile Control User Code:\" text:\"{0}\" duration: 30", code)); } private void SendMcBrandingUrl(IMobileControlRoomBridge mcBridge) From 1849d118b407598cf90ac0b750d1be175361db40 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 18:15:37 -0600 Subject: [PATCH 192/480] gets rid of console print when queue items are processed. --- .../PepperDashEssentialsBase/Queues/GenericQueue.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs index 5b737ad4..651aab77 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs @@ -180,7 +180,7 @@ namespace PepperDash.Essentials.Core.Queues { try { - Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString()); + //Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString()); item.Dispatch(); if (_delayEnabled) From 6c2abc7abd4c11ceac4bf32800ec20770257edd6 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 19:54:01 -0600 Subject: [PATCH 193/480] Adds missing space in video mute command --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 09f3e37f..d354eebc 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -2021,7 +2021,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void CameraMuteOn() { - SendText("xCommand Video InputMainVideo Mute"); + SendText("xCommand Video Input MainVideo Mute"); } /// @@ -2029,7 +2029,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void CameraMuteOff() { - SendText("xCommand Video InputMainVideo Unmute"); + SendText("xCommand Video Input MainVideo Unmute"); } /// From 7640b9570129ea7fb6ed52952fcbdb89a0282b82 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 6 Apr 2021 20:08:59 -0600 Subject: [PATCH 194/480] Clears camera mute mode when turning camera auto mode off --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index d354eebc..a0d4fb74 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -571,6 +571,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Status/Standby" + Delimiter + prefix + "/Status/Video/Selfview" + Delimiter + prefix + "/Status/Video/Layout" + Delimiter + + prefix + "/Status/Video/Input/MainVideoMute" + Delimiter + prefix + "/Bookings" + Delimiter + prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/Bookings" + Delimiter + @@ -1660,12 +1661,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public void CameraAutoModeOn() { + if (CameraIsOffFeedback.BoolValue) + { + CameraMuteOff(); + } + SendText("xCommand Cameras SpeakerTrack Activate"); - CameraMuteOff(); } public void CameraAutoModeOff() { + if (CameraIsOffFeedback.BoolValue) + { + CameraMuteOff(); + } + SendText("xCommand Cameras SpeakerTrack Deactivate"); } From 6ddfdc4b38c280995637bb42802db03198e7c6ce Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 8 Apr 2021 13:54:06 -0600 Subject: [PATCH 195/480] Updating plugin loading mechanism to provide better feedback --- .../Plugins/PluginLoader.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index 01da1c54..c0aac87d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -363,9 +363,10 @@ namespace PepperDash.Essentials { try { - if (typeof(IPluginDeviceFactory).IsAssignableFrom(type)) + if (typeof (IPluginDeviceFactory).IsAssignableFrom(type)) { - var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + var plugin = + (IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); LoadCustomPlugin(plugin, loadedAssembly); } else @@ -378,18 +379,30 @@ namespace PepperDash.Essentials } } } + catch (NotSupportedException e) + { + //this happens for dlls that aren't PD dlls, like ports of Mono classes into S#. Swallowing. + + } catch (Exception e) { Debug.Console(2, "Load Plugin not found. {0}.{2} is not a plugin factory. Exception: {1}", - loadedAssembly.Name, e, type.Name); - continue; + loadedAssembly.Name, e.Message, type.Name); } } } + catch (TypeLoadException e) + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "Unable to load assembly {0}: {1}", + loadedAssembly.Name, e.Message); + Debug.Console(2, e.StackTrace); + } catch (Exception e) { - Debug.Console(2, "Error Loading Assembly: {0} Exception: {1} ", loadedAssembly.Name, e); + Debug.Console(0, Debug.ErrorLogLevel.Warning, "Error Loading assembly {0}: {1}", + loadedAssembly.Name, e.Message); + Debug.Console(2, "{0}", e.StackTrace); continue; } } From 8cfd58bb7e25c4476d21cee2d06e4420022b02e7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 8 Apr 2021 14:21:32 -0600 Subject: [PATCH 196/480] Fix error printing for plugin loading --- .../Plugins/PluginLoader.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index c0aac87d..7192c667 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -358,7 +358,19 @@ namespace PepperDash.Essentials try { var assy = loadedAssembly.Assembly; - var types = assy.GetTypes(); + CType[] types = {}; + try + { + types = assy.GetTypes(); + } + catch (TypeLoadException e) + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "Unable to get types for assembly {0}: {1}", + loadedAssembly.Name, e.Message); + Debug.Console(2, e.StackTrace); + continue; + } + foreach (var type in types) { try @@ -382,7 +394,7 @@ namespace PepperDash.Essentials catch (NotSupportedException e) { //this happens for dlls that aren't PD dlls, like ports of Mono classes into S#. Swallowing. - + } catch (Exception e) { @@ -392,12 +404,6 @@ namespace PepperDash.Essentials } } - catch (TypeLoadException e) - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "Unable to load assembly {0}: {1}", - loadedAssembly.Name, e.Message); - Debug.Console(2, e.StackTrace); - } catch (Exception e) { Debug.Console(0, Debug.ErrorLogLevel.Warning, "Error Loading assembly {0}: {1}", From 19e070ed765f81579c2eaa33ed1b1291799c7997 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 9 Apr 2021 16:36:11 -0600 Subject: [PATCH 197/480] add flags on both ends to prevent input switching loop --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 15 ++++++++++++--- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 7 ++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index d6b58e5b..85cfe90f 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -19,7 +19,8 @@ namespace PepperDash.Essentials { public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback - { + { + private bool _codecExternalSourceChange; public event EventHandler CurrentVolumeDeviceChange; public event SourceInfoChangeHandler CurrentSourceChange; @@ -178,10 +179,12 @@ namespace PepperDash.Essentials handler(_CurrentSourceInfo, ChangeType.DidChange); var vc = VideoCodec as IHasExternalSourceSwitching; - if (vc != null) + if (vc != null && !_codecExternalSourceChange) { vc.SetSelectedSource(CurrentSourceInfoKey); } + + _codecExternalSourceChange = false; } } SourceListItem _CurrentSourceInfo; @@ -421,6 +424,12 @@ namespace PepperDash.Essentials return true; } + public void RunRouteActionCodec(string routeKey, string sourceListKey) + { + _codecExternalSourceChange = true; + RunRouteAction(routeKey, sourceListKey); + } + /// /// /// @@ -750,7 +759,7 @@ namespace PepperDash.Essentials x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort; videoCodecWithExternalSwitching.ClearExternalSources(); - videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction; + videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec; var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ; foreach (var kvp in srcList) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index a0d4fb74..a7be2443 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -30,6 +30,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute { + private bool _externalSourceChangeRequested; + public event EventHandler DirectoryResultReturned; private CTimer _brandingTimer; @@ -961,10 +963,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco JsonConvert.PopulateObject(response, eventReceived); Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value); - if (RunRouteAction != null) + if (RunRouteAction != null && !_externalSourceChangeRequested) { RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null); } + + _externalSourceChangeRequested = false; } } else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1) @@ -1994,6 +1998,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public void SetSelectedSource(string key) { SendText(string.Format("xCommand UserInterface Presentation ExternalSource Select SourceIdentifier: {0}", key)); + _externalSourceChangeRequested = true; } /// From 0a4ff82af0f98ecf4ead70ce43a85bb91fec3d7d Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 15 Apr 2021 13:47:46 -0500 Subject: [PATCH 198/480] Added SecretsManager Added ISecrets Added ISecretsProvider --- PepperDashEssentials/ControlSystem.cs | 1 + .../Comm and IR/GenericComm.cs | 1 + .../Config/DeviceConfig.cs | 14 +- .../Factory/DeviceFactory.cs | 98 ++++++-- .../PepperDash_Essentials_Core.csproj | 4 + .../Secrets/CrestronSecretsProvider.cs | 84 +++++++ .../Secrets/Interfaces.cs | 18 ++ .../Secrets/SecretsManager.cs | 220 ++++++++++++++++++ .../Secrets/SecretsPropertiesConfig.cs | 17 ++ 9 files changed, 438 insertions(+), 19 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 5df5c1a2..37ef79a8 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -36,6 +36,7 @@ namespace PepperDash.Essentials Thread.MaxNumberOfUserThreads = 400; Global.ControlSystem = this; DeviceManager.Initialize(this); + SecretsManager.Initialize(); SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs index 8380a290..7648a379 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/GenericComm.cs @@ -25,6 +25,7 @@ namespace PepperDash.Essentials.Core public GenericComm(DeviceConfig config) : base(config) { + PropertiesConfig = CommFactory.GetControlPropertiesConfig(config); var commPort = CommFactory.CreateCommForDevice(config); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/DeviceConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/DeviceConfig.cs index bb95da01..1d9ed1c2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/DeviceConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/DeviceConfig.cs @@ -30,7 +30,19 @@ namespace PepperDash.Essentials.Core.Config [JsonProperty("properties")] [JsonConverter(typeof(DevicePropertiesConverter))] - public JToken Properties { get; set; } + public JToken Properties { get; set; } + + public DeviceConfig(DeviceConfig dc) + { + Key = dc.Key; + Uid = dc.Uid; + Name = dc.Name; + Group = dc.Group; + Type = dc.Type; + Properties = JToken.FromObject(dc.Properties); + } + + public DeviceConfig() {} } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index 3f38e2d5..a0108490 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -7,6 +7,8 @@ using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.GeneralIO; using Crestron.SimplSharp.Reflection; using PepperDash.Core; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; @@ -91,24 +93,84 @@ namespace PepperDash.Essentials.Core /// /// /// - public static IKeyed GetDevice(DeviceConfig dc) - { - var key = dc.Key; - var name = dc.Name; - var type = dc.Type; - var properties = dc.Properties; - - var typeName = dc.Type.ToLower(); - - // Check for types that have been added by plugin dlls. - if (FactoryMethods.ContainsKey(typeName)) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type); - return FactoryMethods[typeName].FactoryMethod(dc); - } - - return null; - } + public static IKeyed GetDevice(DeviceConfig dc) + { + try + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type); + + var localDc = new DeviceConfig(dc); + + var key = localDc.Key; + var name = localDc.Name; + var type = localDc.Type; + var properties = localDc.Properties; + + + + var typeName = localDc.Type.ToLower(); + + Debug.Console(2, "typeName = {0}", typeName); + // Check for types that have been added by plugin dlls. + if (FactoryMethods.ContainsKey(typeName)) + { + //look for secret in username + var userSecretToken = properties["control"]["tcpSshProperties"]["username"]["secret"]; + + if (userSecretToken != null) + { + Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); + var userSecretResult = + JsonConvert.DeserializeObject(userSecretToken.ToString()); + var userProvider = SecretsManager.GetSecretProviderByKey(userSecretResult.Provider); + if (userProvider != null) + { + var user = userProvider.GetSecret(userSecretResult.Key); + if (user == null) + { + Debug.Console(1, + "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); + return null; + } + properties["control"]["tcpSshProperties"]["username"] = (string) user.Value; + } + } + + //look for secret in password + var passwordSecretToken = properties["control"]["tcpSshProperties"]["password"]["secret"]; + + if (passwordSecretToken != null) + { + Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); + + var passwordSecretResult = + JsonConvert.DeserializeObject(passwordSecretToken.ToString()); + var passwordProvider = SecretsManager.GetSecretProviderByKey(passwordSecretResult.Provider); + if (passwordProvider != null) + { + var password = passwordProvider.GetSecret(passwordSecretResult.Key); + if (password == null) + { + Debug.Console(1, + "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); + return null; + } + properties["control"]["tcpSshProperties"]["password"] = (string) password.Value; + } + } + + Debug.Console(0, "{0}", localDc.Properties.ToString()); + + return FactoryMethods[typeName].FactoryMethod(localDc); + } + return null; + } + catch (Exception ex) + { + Debug.Console(2, "Issue with getting device - {0}", ex.Message); + return null; + } + } /// /// Prints the type names and associated metadata from the FactoryMethods collection. diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index e4c775d0..f202434e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -320,6 +320,10 @@ + + + + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs new file mode 100644 index 00000000..54a3f3c8 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs @@ -0,0 +1,84 @@ +using System; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronDataStore; +using PepperDash.Core; + + +namespace PepperDash.Essentials.Core +{ + public class CrestronSecretsProvider : ISecretProvider + { + public string Key { get; set; } + //Added for reference + //private readonly bool _secureSupported; + public CrestronSecretsProvider(string key) + { + Key = key; + //Added for future encrypted reference + //_secureSupported = CrestronSecureStorage.Supported; + + //if (_secureSupported) + //{ + // return; + //} + CrestronDataStoreStatic.InitCrestronDataStore(); + + } + + + public void SetSecret(string key, object value) + { + var secret = value as string; + if (String.IsNullOrEmpty(secret)) + { + Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key); + return; + } + Debug.Console(2, this, "Attempting to set Secret to {0}", secret); + var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); + switch (setErrorCode) + { + case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: + Debug.Console(2, this,"Secret Successfully Set for {0}:{1}", Key, key); + break; + default: + Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString()); + break; + } + } + + public ISecret GetSecret(string key) + { + string mySecret; + var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret); + + switch (getErrorCode) + { + case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: + Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); + Debug.Console(2, this, "Retreived Secret = {0}", mySecret); + return new CrestronSecret(key, mySecret, this); + default: + Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", + Key, key, getErrorCode.ToString()); + return null; + } + } + } + + public class CrestronSecret : ISecret + { + public ISecretProvider Provider { get; private set; } + public string Key { get; private set; } + + public object Value { get; private set; } + + public CrestronSecret(string key, string value, ISecretProvider provider) + { + Key = key; + Value = value; + Provider = provider; + } + + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs new file mode 100644 index 00000000..51b0b389 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs @@ -0,0 +1,18 @@ +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + public interface ISecretProvider : IKeyed + { + void SetSecret(string key, object value); + + ISecret GetSecret(string key); + } + + public interface ISecret + { + ISecretProvider Provider { get; } + string Key { get; } + object Value { get; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs new file mode 100644 index 00000000..c14bfdc6 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Crestron.SimplSharp; +using PepperDash.Core; + + +namespace PepperDash.Essentials.Core +{ + public static class SecretsManager + { + public static List Secrets { get; set; } + + public static void Initialize() + { + Secrets = new List {new CrestronSecretsProvider("default")}; + + CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret", + "Adds secrets to secret provider", + ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret", + "Updates secrets in secret provider", + ConsoleAccessLevelEnum.AccessAdministrator); + + CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret", + "Deletes secrets in secret provider", + ConsoleAccessLevelEnum.AccessAdministrator); + + + } + + public static ISecretProvider GetSecretProviderByKey(string key) + { + var secret = Secrets.FirstOrDefault(o => o.Key == key); + if (secret == null) + { + Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key); + } + return secret; + } + + private static void SetSecretProcess(string cmd) + { + string response; + var args = cmd.Split(' '); + + if (args.Length == 0) + { + //some Instructional Text + response = "Adds secrets to secret provider. Format 'setsecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + if (args.Length == 1 && args[0] == "?") + { + response = "Adds secrets to secret provider. Format 'setsecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + if (args.Length < 3) + { + response = "Improper number of arguments"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + + if (provider == null) + { + //someFail + response = "Provider key invalid"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var key = args[1]; + var secret = args[2]; + + if (provider.GetSecret(key) == null) + { + provider.SetSecret(key, secret); + response = + String.Format( + "Secret successfully set for {0}:{1}", + provider.Key, key); + CrestronConsole.ConsoleCommandResponse(response); + return; + } + response = + String.Format( + "Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it"); + CrestronConsole.ConsoleCommandResponse(response); + } + + private static void UpdateSecretProcess(string cmd) + { + string response; + var args = cmd.Split(' '); + + if (args.Length == 0) + { + //some Instructional Text + response = "Updates secrets in secret provider. Format 'updatesecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + if (args.Length == 1 && args[0] == "?") + { + response = "Updates secrets in secret provider. Format 'updatesecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + + if (args.Length < 3) + { + //someFail + response = "Improper number of arguments"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + + if (provider == null) + { + //someFail + response = "Provider key invalid"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var key = args[1]; + var secret = args[2]; + + if (provider.GetSecret(key) != null) + { + provider.SetSecret(key, secret); + response = + String.Format( + "Secret successfully updated for {0}:{1}", + provider.Key, key); + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + response = + String.Format( + "Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to create a new secret"); + CrestronConsole.ConsoleCommandResponse(response); + } + + private static void DeleteSecretProcess(string cmd) + { + string response; + var args = cmd.Split(' '); + + if (args.Length == 0) + { + //some Instructional Text + response = "Deletes secrets in secret provider. Format 'deletesecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + if (args.Length == 1 && args[0] == "?") + { + response = "Deletes secrets in secret provider. Format 'deletesecret "; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + + + if (args.Length < 2) + { + //someFail + response = "Improper number of arguments"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + + if (provider == null) + { + //someFail + response = "Provider key invalid"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + var key = args[1]; + + + provider.SetSecret(key, ""); + response = + String.Format( + "Secret successfully deleted for {0}:{1}", + provider.Key, key); + CrestronConsole.ConsoleCommandResponse(response); + + + } + } + + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs new file mode 100644 index 00000000..b17b9000 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core +{ + public class SecretsPropertiesConfig + { + [JsonProperty("provider")] + public string Provider { get; set; } + [JsonProperty("key")] + public string Key { get; set; } + } +} \ No newline at end of file From babc3e4f1a9cf46e8bfdf0d5677a285f350f477d Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 15 Apr 2021 14:36:43 -0500 Subject: [PATCH 199/480] fixed minor registration error --- .../Extensions/JsonExtensions.cs | 42 ++++++++ .../Factory/DeviceFactory.cs | 99 ++++++++++--------- .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 94 insertions(+), 48 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/JsonExtensions.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/JsonExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/JsonExtensions.cs new file mode 100644 index 00000000..cdf723ea --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/JsonExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace PepperDash.Essentials.Core +{ + public static class JsonExtensions + { + public static List FindTokens(this JToken containerToken, string name) + { + List matches = new List(); + FindTokens(containerToken, name, matches); + return matches; + } + + private static void FindTokens(JToken containerToken, string name, List matches) + { + if (containerToken.Type == JTokenType.Object) + { + foreach (JProperty child in containerToken.Children()) + { + if (child.Name == name) + { + matches.Add(child.Value); + } + FindTokens(child.Value, name, matches); + } + } + else if (containerToken.Type == JTokenType.Array) + { + foreach (JToken child in containerToken.Children()) + { + FindTokens(child, name, matches); + } + } + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index a0108490..cb7dd0b7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -105,65 +105,68 @@ namespace PepperDash.Essentials.Core var name = localDc.Name; var type = localDc.Type; var properties = localDc.Properties; - - + //var propRecurse = properties; var typeName = localDc.Type.ToLower(); Debug.Console(2, "typeName = {0}", typeName); // Check for types that have been added by plugin dlls. - if (FactoryMethods.ContainsKey(typeName)) + if (!FactoryMethods.ContainsKey(typeName)) return null; + + /*foreach (var obj in (propRecurse as JObject).FindTokens("secret").OfType()) + { + Debug.Console(2, obj.ToString()); + }*/ + + + //look for secret in username + var userSecretToken = properties["control"]["tcpSshProperties"]["username"]["secret"]; + + if (userSecretToken != null) { - //look for secret in username - var userSecretToken = properties["control"]["tcpSshProperties"]["username"]["secret"]; - - if (userSecretToken != null) + Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); + var userSecretResult = + JsonConvert.DeserializeObject(userSecretToken.ToString()); + var userProvider = SecretsManager.GetSecretProviderByKey(userSecretResult.Provider); + if (userProvider != null) { - Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); - var userSecretResult = - JsonConvert.DeserializeObject(userSecretToken.ToString()); - var userProvider = SecretsManager.GetSecretProviderByKey(userSecretResult.Provider); - if (userProvider != null) + var user = userProvider.GetSecret(userSecretResult.Key); + if (user == null) { - var user = userProvider.GetSecret(userSecretResult.Key); - if (user == null) - { - Debug.Console(1, - "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); - return null; - } - properties["control"]["tcpSshProperties"]["username"] = (string) user.Value; + Debug.Console(1, + "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); + return null; } + properties["control"]["tcpSshProperties"]["username"] = (string) user.Value; } - - //look for secret in password - var passwordSecretToken = properties["control"]["tcpSshProperties"]["password"]["secret"]; - - if (passwordSecretToken != null) - { - Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); - - var passwordSecretResult = - JsonConvert.DeserializeObject(passwordSecretToken.ToString()); - var passwordProvider = SecretsManager.GetSecretProviderByKey(passwordSecretResult.Provider); - if (passwordProvider != null) - { - var password = passwordProvider.GetSecret(passwordSecretResult.Key); - if (password == null) - { - Debug.Console(1, - "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); - return null; - } - properties["control"]["tcpSshProperties"]["password"] = (string) password.Value; - } - } - - Debug.Console(0, "{0}", localDc.Properties.ToString()); - - return FactoryMethods[typeName].FactoryMethod(localDc); } - return null; + + //look for secret in password + var passwordSecretToken = properties["control"]["tcpSshProperties"]["password"]["secret"]; + + if (passwordSecretToken != null) + { + Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); + + var passwordSecretResult = + JsonConvert.DeserializeObject(passwordSecretToken.ToString()); + var passwordProvider = SecretsManager.GetSecretProviderByKey(passwordSecretResult.Provider); + if (passwordProvider != null) + { + var password = passwordProvider.GetSecret(passwordSecretResult.Key); + if (password == null) + { + Debug.Console(1, + "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); + return null; + } + properties["control"]["tcpSshProperties"]["password"] = (string)password.Value; + } + } + + Debug.Console(0, "{0}", localDc.Properties.ToString()); + + return FactoryMethods[typeName].FactoryMethod(localDc); } catch (Exception ex) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index f202434e..e65b081b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -209,6 +209,7 @@ + From 2787c7fc523551eb76d05d75aefd33f63c7a99c0 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 15 Apr 2021 18:47:13 -0500 Subject: [PATCH 200/480] Close #685 Adds support for Secrets --- .../Factory/DeviceFactory.cs | 147 ++++++++---------- .../Secrets/CrestronSecretsProvider.cs | 16 +- .../Secrets/Interfaces.cs | 6 + .../Secrets/SecretsManager.cs | 8 + .../Secrets/SecretsPropertiesConfig.cs | 3 + 5 files changed, 95 insertions(+), 85 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index cb7dd0b7..66bf5d2b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -85,96 +85,79 @@ namespace PepperDash.Essentials.Core var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; DeviceFactory.FactoryMethods.Add(typeName, wrapper); - } - - /// - /// The factory method for Core "things". Also iterates the Factory methods that have - /// been loaded from plugins - /// - /// - /// - public static IKeyed GetDevice(DeviceConfig dc) - { - try - { + } + + private static void CheckForSecrets(IEnumerable obj) + { + foreach (var prop in obj.Where(prop => prop.Value as JObject != null)) + { + if (prop.Name.ToLower() == "secret") + { + var secret = GetSecret(JsonConvert.DeserializeObject(prop.Children().First().ToString())); + prop.Parent.Replace(secret); + } + var recurseProp = prop.Value as JObject; + if (recurseProp == null) return; + CheckForSecrets(recurseProp.Properties()); + } + } + + private static string GetSecret(SecretsPropertiesConfig data) + { + var secretProvider = SecretsManager.GetSecretProviderByKey(data.Provider); + if (secretProvider == null) return null; + var secret = secretProvider.GetSecret(data.Key); + if (secret != null) return (string) secret.Value; + Debug.Console(1, + "Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider", + data.Provider, data.Key); + return null; + } + + + /// + /// The factory method for Core "things". Also iterates the Factory methods that have + /// been loaded from plugins + /// + /// + /// + public static + IKeyed GetDevice(DeviceConfig dc) + { + try + { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type); - var localDc = new DeviceConfig(dc); + var localDc = new DeviceConfig(dc); - var key = localDc.Key; - var name = localDc.Name; - var type = localDc.Type; + var key = localDc.Key; + var name = localDc.Name; + var type = localDc.Type; var properties = localDc.Properties; - //var propRecurse = properties; + //var propRecurse = properties; - var typeName = localDc.Type.ToLower(); + var typeName = localDc.Type.ToLower(); + + + var jObject = properties as JObject; + if (jObject != null) + { + var jProp = jObject.Properties(); + + CheckForSecrets(jProp); + } Debug.Console(2, "typeName = {0}", typeName); - // Check for types that have been added by plugin dlls. - if (!FactoryMethods.ContainsKey(typeName)) return null; + // Check for types that have been added by plugin dlls. + return !FactoryMethods.ContainsKey(typeName) ? null : FactoryMethods[typeName].FactoryMethod(localDc); + } + catch (Exception ex) + { + Debug.Console(2, "Issue with getting device - {0}", ex.Message); + return null; + } + } - /*foreach (var obj in (propRecurse as JObject).FindTokens("secret").OfType()) - { - Debug.Console(2, obj.ToString()); - }*/ - - - //look for secret in username - var userSecretToken = properties["control"]["tcpSshProperties"]["username"]["secret"]; - - if (userSecretToken != null) - { - Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); - var userSecretResult = - JsonConvert.DeserializeObject(userSecretToken.ToString()); - var userProvider = SecretsManager.GetSecretProviderByKey(userSecretResult.Provider); - if (userProvider != null) - { - var user = userProvider.GetSecret(userSecretResult.Key); - if (user == null) - { - Debug.Console(1, - "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); - return null; - } - properties["control"]["tcpSshProperties"]["username"] = (string) user.Value; - } - } - - //look for secret in password - var passwordSecretToken = properties["control"]["tcpSshProperties"]["password"]["secret"]; - - if (passwordSecretToken != null) - { - Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name); - - var passwordSecretResult = - JsonConvert.DeserializeObject(passwordSecretToken.ToString()); - var passwordProvider = SecretsManager.GetSecretProviderByKey(passwordSecretResult.Provider); - if (passwordProvider != null) - { - var password = passwordProvider.GetSecret(passwordSecretResult.Key); - if (password == null) - { - Debug.Console(1, - "Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider"); - return null; - } - properties["control"]["tcpSshProperties"]["password"] = (string)password.Value; - } - } - - Debug.Console(0, "{0}", localDc.Properties.ToString()); - - return FactoryMethods[typeName].FactoryMethod(localDc); - } - catch (Exception ex) - { - Debug.Console(2, "Issue with getting device - {0}", ex.Message); - return null; - } - } - /// /// Prints the type names and associated metadata from the FactoryMethods collection. /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs index 54a3f3c8..87dddea7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs @@ -25,7 +25,11 @@ namespace PepperDash.Essentials.Core } - + /// + /// Set secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// Secret Value public void SetSecret(string key, object value) { var secret = value as string; @@ -34,7 +38,6 @@ namespace PepperDash.Essentials.Core Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key); return; } - Debug.Console(2, this, "Attempting to set Secret to {0}", secret); var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); switch (setErrorCode) { @@ -47,6 +50,11 @@ namespace PepperDash.Essentials.Core } } + /// + /// Retrieve secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// ISecret Object containing key, provider, and value public ISecret GetSecret(string key) { string mySecret; @@ -56,7 +64,6 @@ namespace PepperDash.Essentials.Core { case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); - Debug.Console(2, this, "Retreived Secret = {0}", mySecret); return new CrestronSecret(key, mySecret, this); default: Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", @@ -66,6 +73,9 @@ namespace PepperDash.Essentials.Core } } + /// + /// Special container class for CrestronSecret provider + /// public class CrestronSecret : ISecret { public ISecretProvider Provider { get; private set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs index 51b0b389..86ae65cf 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs @@ -2,6 +2,9 @@ namespace PepperDash.Essentials.Core { + /// + /// All ISecrecretProvider classes must implement this interface. + /// public interface ISecretProvider : IKeyed { void SetSecret(string key, object value); @@ -9,6 +12,9 @@ namespace PepperDash.Essentials.Core ISecret GetSecret(string key); } + /// + /// interface for delivering secrets in Essentials. + /// public interface ISecret { ISecretProvider Provider { get; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs index c14bfdc6..f50051da 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs @@ -11,6 +11,9 @@ namespace PepperDash.Essentials.Core { public static List Secrets { get; set; } + /// + /// Initialize the SecretsManager + /// public static void Initialize() { Secrets = new List {new CrestronSecretsProvider("default")}; @@ -30,6 +33,11 @@ namespace PepperDash.Essentials.Core } + /// + /// Method to return a ISecretProvider to Set, Get, and Delete Secrets + /// + /// Secret Provider Key + /// public static ISecretProvider GetSecretProviderByKey(string key) { var secret = Secrets.FirstOrDefault(o => o.Key == key); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs index b17b9000..68026aa1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsPropertiesConfig.cs @@ -7,6 +7,9 @@ using Newtonsoft.Json; namespace PepperDash.Essentials.Core { + /// + /// Provide a way to easily deserialize into a secret object from config + /// public class SecretsPropertiesConfig { [JsonProperty("provider")] From 8643ed2cafbd32a737019500bf2aaf82d6727477 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 15 Apr 2021 19:14:24 -0500 Subject: [PATCH 201/480] #685 - Requested Fixes per AWelker --- .../Secrets/CrestronSecretsProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs index 87dddea7..609aba64 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs @@ -66,9 +66,9 @@ namespace PepperDash.Essentials.Core Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); return new CrestronSecret(key, mySecret, this); default: - Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", Key, key, getErrorCode.ToString()); - return null; + return new CrestronSecret(key, String.Empty, this); } } } From 452d0a5a398395eff15f2145cdbdf513dfdda00d Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Apr 2021 09:59:58 -0500 Subject: [PATCH 202/480] Changed DeviceFactory.GetSecret(SecretsPropertiesConfig data) to return an empty string instead of null on a failed retrieval --- .../PepperDashEssentialsBase/Factory/DeviceFactory.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index 66bf5d2b..d4382442 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -111,7 +111,7 @@ namespace PepperDash.Essentials.Core Debug.Console(1, "Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider", data.Provider, data.Key); - return null; + return String.Empty; } @@ -121,8 +121,7 @@ namespace PepperDash.Essentials.Core /// /// /// - public static - IKeyed GetDevice(DeviceConfig dc) + public static IKeyed GetDevice(DeviceConfig dc) { try { From 3c9ca1e527b19bb72c4835ccdbd22336c1fed180 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Fri, 16 Apr 2021 12:29:41 -0500 Subject: [PATCH 203/480] Resoves #688 Added some QoL improvements to SecretsManager meant to protect the integrity of the providers dictionary from accidental manipulation Debug statement improvements Improvements to verbosity of console command returns for the SecretsManager --- .../Factory/DeviceFactory.cs | 7 +- .../Secrets/CrestronSecretsProvider.cs | 29 +++--- .../Secrets/Interfaces.cs | 2 +- .../Secrets/SecretsManager.cs | 97 ++++++++++++++----- 4 files changed, 97 insertions(+), 38 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index d4382442..ec041853 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -93,7 +93,8 @@ namespace PepperDash.Essentials.Core { if (prop.Name.ToLower() == "secret") { - var secret = GetSecret(JsonConvert.DeserializeObject(prop.Children().First().ToString())); + var secret = GetSecret(prop.Children().First().ToObject()); + //var secret = GetSecret(JsonConvert.DeserializeObject(prop.Children().First().ToString())); prop.Parent.Replace(secret); } var recurseProp = prop.Value as JObject; @@ -152,7 +153,9 @@ namespace PepperDash.Essentials.Core } catch (Exception ex) { - Debug.Console(2, "Issue with getting device - {0}", ex.Message); + Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message); + + Debug.Console(2, "{0}", ex.StackTrace); return null; } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs index 609aba64..3e0a5964 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs @@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core { public string Key { get; set; } //Added for reference - //private readonly bool _secureSupported; + private static readonly bool SecureSupported; public CrestronSecretsProvider(string key) { Key = key; + } + + static CrestronSecretsProvider() + { //Added for future encrypted reference - //_secureSupported = CrestronSecureStorage.Supported; + SecureSupported = CrestronSecureStorage.Supported; - //if (_secureSupported) - //{ - // return; - //} CrestronDataStoreStatic.InitCrestronDataStore(); - + if (SecureSupported) + { + //doThingsFuture + } } /// @@ -30,23 +33,23 @@ namespace PepperDash.Essentials.Core /// /// Secret Key /// Secret Value - public void SetSecret(string key, object value) + public bool SetSecret(string key, object value) { var secret = value as string; if (String.IsNullOrEmpty(secret)) { Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key); - return; + return false; } var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); switch (setErrorCode) { case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: - Debug.Console(2, this,"Secret Successfully Set for {0}:{1}", Key, key); - break; + Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key); + return true; default: Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString()); - break; + return false; } } @@ -68,7 +71,7 @@ namespace PepperDash.Essentials.Core default: Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", Key, key, getErrorCode.ToString()); - return new CrestronSecret(key, String.Empty, this); + return null; } } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs index 86ae65cf..43c6a230 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs @@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Core /// public interface ISecretProvider : IKeyed { - void SetSecret(string key, object value); + bool SetSecret(string key, object value); ISecret GetSecret(string key); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs index f50051da..bcb46ff5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Crestron.SimplSharp; using PepperDash.Core; @@ -9,15 +8,16 @@ namespace PepperDash.Essentials.Core { public static class SecretsManager { - public static List Secrets { get; set; } + public static Dictionary Secrets { get; private set; } /// /// Initialize the SecretsManager /// public static void Initialize() { - Secrets = new List {new CrestronSecretsProvider("default")}; - + + AddSecretProvider("default", new CrestronSecretsProvider("default")); + CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret", "Adds secrets to secret provider", ConsoleAccessLevelEnum.AccessOperator); @@ -29,18 +29,24 @@ namespace PepperDash.Essentials.Core CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret", "Deletes secrets in secret provider", ConsoleAccessLevelEnum.AccessAdministrator); - + } + static SecretsManager() + { + Secrets = new Dictionary(); } /// - /// Method to return a ISecretProvider to Set, Get, and Delete Secrets + /// Get Secret Provider from dictionary by key /// - /// Secret Provider Key - /// + /// Dictionary Key for provider + /// ISecretProvider public static ISecretProvider GetSecretProviderByKey(string key) { - var secret = Secrets.FirstOrDefault(o => o.Key == key); + ISecretProvider secret; + + Secrets.TryGetValue(key, out secret); + if (secret == null) { Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key); @@ -48,6 +54,44 @@ namespace PepperDash.Essentials.Core return secret; } + /// + /// Add secret provider to secrets dictionary + /// + /// Key of new entry + /// New Provider Entry + public static void AddSecretProvider(string key, ISecretProvider provider) + { + if (!Secrets.ContainsKey(key)) + { + Secrets.Add(key, provider); + Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key); + } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key ); + } + + /// + /// Add secret provider to secrets dictionary, with optional overwrite parameter + /// + /// Key of new entry + /// New provider entry + /// true to overwrite any existing providers in the dictionary + public static void AddSecretProvider(string key, ISecretProvider provider, bool overwrite) + { + if (!Secrets.ContainsKey(key)) + { + Secrets.Add(key, provider); + Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key); + + } + if (overwrite) + { + Secrets.Add(key, provider); + Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key); + + } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key); + } + private static void SetSecretProcess(string cmd) { string response; @@ -76,7 +120,7 @@ namespace PepperDash.Essentials.Core } - var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + var provider = GetSecretProviderByKey(args[0]); if (provider == null) { @@ -92,11 +136,14 @@ namespace PepperDash.Essentials.Core if (provider.GetSecret(key) == null) { - provider.SetSecret(key, secret); - response = - String.Format( + + response = provider.SetSecret(key, secret) + ? String.Format( "Secret successfully set for {0}:{1}", - provider.Key, key); + provider.Key, key) + : String.Format( + "Unable to set secret for {0}:{1}", + provider.Key, key); CrestronConsole.ConsoleCommandResponse(response); return; } @@ -137,7 +184,7 @@ namespace PepperDash.Essentials.Core } - var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + var provider = GetSecretProviderByKey(args[0]); if (provider == null) { @@ -153,10 +200,12 @@ namespace PepperDash.Essentials.Core if (provider.GetSecret(key) != null) { - provider.SetSecret(key, secret); - response = - String.Format( - "Secret successfully updated for {0}:{1}", + response = provider.SetSecret(key, secret) + ? String.Format( + "Secret successfully set for {0}:{1}", + provider.Key, key) + : String.Format( + "Unable to set secret for {0}:{1}", provider.Key, key); CrestronConsole.ConsoleCommandResponse(response); return; @@ -199,7 +248,7 @@ namespace PepperDash.Essentials.Core } - var provider = Secrets.FirstOrDefault(o => o.Key == args[0]); + var provider = GetSecretProviderByKey(args[0]); if (provider == null) { @@ -214,11 +263,15 @@ namespace PepperDash.Essentials.Core provider.SetSecret(key, ""); - response = - String.Format( + response = provider.SetSecret(key, "") + ? String.Format( "Secret successfully deleted for {0}:{1}", + provider.Key, key) + : String.Format( + "Unable to delete secret for {0}:{1}", provider.Key, key); CrestronConsole.ConsoleCommandResponse(response); + return; } From 685c3447850b251c2500488f2868eeeeb8a145c0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 20 Apr 2021 14:38:24 -0600 Subject: [PATCH 204/480] #690 fixes incorrect conditional check before firing feedback --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 232ab83c..d33c3707 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -107,14 +107,18 @@ namespace PepperDash.Essentials private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel) { + //Debug.Console(2, this, "TunerPresetsOnPresetRecalled"); + if (!_currentPresets.ContainsKey(device.Key)) { return; } + //Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel); + _currentPresets[device.Key] = channel; - if (!CurrentPresetsFeedbacks.ContainsKey(device.Key)) + if (CurrentPresetsFeedbacks.ContainsKey(device.Key)) { CurrentPresetsFeedbacks[device.Key].FireUpdate(); } From ae9833ffaad6e73fe59e00f72e4d4775a80067a5 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 23 Apr 2021 08:58:43 -0400 Subject: [PATCH 205/480] Changes cr to crlf for some console command responses --- PepperDashEssentials/ControlSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 5df5c1a2..aa4f43f7 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -71,7 +71,7 @@ namespace PepperDash.Essentials CrestronConsole.AddNewConsoleCommand(s => { foreach (var tl in TieLineCollection.Default) - CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); + CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl); }, "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); @@ -85,8 +85,8 @@ namespace PepperDash.Essentials CrestronConsole.AddNewConsoleCommand(s => { - CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" + - "System URL: {0}\r" + + CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" + + "System URL: {0}\r\n" + "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); From fb44a3b93ca71793bc4e84f7f293e14632466171 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 29 Apr 2021 13:44:47 -0400 Subject: [PATCH 206/480] Resolves looping in IRouting by adding the device to the tracking list before iterating down further. Adds debug statement to print when this condition occurs - "Skipping input on , this was already checked" --- .../Routing/IRoutingInputsExtensions.cs | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs index e795018a..0c375825 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs @@ -123,25 +123,34 @@ namespace PepperDash.Essentials.Core // No direct tie? Run back out on the inputs' attached devices... // Only the ones that are routing devices var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs); + + //Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration + if (alreadyCheckedDevices == null) + alreadyCheckedDevices = new List(); + alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs); + foreach (var inputTieToTry in attachedMidpoints) { - Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key); var upstreamDeviceOutputPort = inputTieToTry.SourcePort; var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs; + Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key); + // Check if this previous device has already been walked - if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice))) - { - // haven't seen this device yet. Do it. Pass the output port to the next - // level to enable switching on success - var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort, - alreadyCheckedDevices, signalType, cycle, routeTable); - if (upstreamRoutingSuccess) - { - Debug.Console(2, destination, "Upstream device route found"); - goodInputPort = inputTieToTry.DestinationPort; - break; // Stop looping the inputs in this cycle - } - } + if (alreadyCheckedDevices.Contains(upstreamRoutingDevice)) + { + Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key); + continue; + } + // haven't seen this device yet. Do it. Pass the output port to the next + // level to enable switching on success + var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort, + alreadyCheckedDevices, signalType, cycle, routeTable); + if (upstreamRoutingSuccess) + { + Debug.Console(2, destination, "Upstream device route found"); + goodInputPort = inputTieToTry.DestinationPort; + break; // Stop looping the inputs in this cycle + } } } @@ -163,10 +172,6 @@ namespace PepperDash.Essentials.Core //Debug.Console(2, destination, "Exiting cycle {0}", cycle); return true; } - - if(alreadyCheckedDevices == null) - alreadyCheckedDevices = new List(); - alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs); Debug.Console(2, destination, "No route found to {0}", source.Key); return false; From 9ea65883b77fcaf90f02f83c6026cd51dc8c379a Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Fri, 30 Apr 2021 14:58:39 -0400 Subject: [PATCH 207/480] Fixes DM Audio Routing --- .../Chassis/DmChassisController.cs | 2796 ++++++++--------- 1 file changed, 1398 insertions(+), 1398 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 72f84f48..8c6b2ced 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1,324 +1,324 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System; +using System.Collections.Generic; +using System.Linq; using Crestron.SimplSharp; using Crestron.SimplSharp.Reflection; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Cards; -using Crestron.SimplSharpPro.DM.Endpoints; -using Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.DM.Config; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.DM -{ - /// - /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions - /// - /// +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Cards; +using Crestron.SimplSharpPro.DM.Endpoints; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.DM.Config; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.DM +{ + /// + /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions + /// + /// [Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")] public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback { - private const string NonePortKey = "inputCard0--None"; - public DMChassisPropertiesConfig PropertiesConfig { get; set; } - + private const string NonePortKey = "inputCard0--None"; + public DMChassisPropertiesConfig PropertiesConfig { get; set; } + public Switch Chassis { get; private set; } //IroutingNumericEvent - public event EventHandler NumericSwitchChange; - - // Feedbacks for EssentialDM - public Dictionary VideoOutputFeedbacks { get; private set; } - public Dictionary AudioOutputFeedbacks { get; private set; } - public Dictionary VideoInputSyncFeedbacks { get; private set; } - public Dictionary InputEndpointOnlineFeedbacks { get; private set; } - public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } - public Dictionary InputNameFeedbacks { get; private set; } - public Dictionary OutputNameFeedbacks { get; private set; } - public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } - public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } - public Dictionary UsbOutputRoutedToFeebacks { get; private set; } - public Dictionary UsbInputRoutedToFeebacks { get; private set; } - public Dictionary OutputDisabledByHdcpFeedbacks { get; private set; } - - public IntFeedback SystemIdFeebdack { get; private set; } - public BoolFeedback SystemIdBusyFeedback { get; private set; } - public BoolFeedback EnableAudioBreakawayFeedback { get; private set; } - public BoolFeedback EnableUsbBreakawayFeedback { get; private set; } - + public event EventHandler NumericSwitchChange; + + // Feedbacks for EssentialDM + public Dictionary VideoOutputFeedbacks { get; private set; } + public Dictionary AudioOutputFeedbacks { get; private set; } + public Dictionary VideoInputSyncFeedbacks { get; private set; } + public Dictionary InputEndpointOnlineFeedbacks { get; private set; } + public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } + public Dictionary InputNameFeedbacks { get; private set; } + public Dictionary OutputNameFeedbacks { get; private set; } + public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } + public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } + public Dictionary UsbOutputRoutedToFeebacks { get; private set; } + public Dictionary UsbInputRoutedToFeebacks { get; private set; } + public Dictionary OutputDisabledByHdcpFeedbacks { get; private set; } + + public IntFeedback SystemIdFeebdack { get; private set; } + public BoolFeedback SystemIdBusyFeedback { get; private set; } + public BoolFeedback EnableAudioBreakawayFeedback { get; private set; } + public BoolFeedback EnableUsbBreakawayFeedback { get; private set; } + public Dictionary InputCardHdcpStateFeedbacks { get; private set; } public Dictionary InputStreamCardStateFeedbacks { get; private set; } - public Dictionary OutputStreamCardStateFeedbacks { get; private set; } - - public Dictionary InputCardHdcpCapabilityTypes { get; private set; } - - // Need a couple Lists of generic Backplane ports - public RoutingPortCollection InputPorts { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } - - public Dictionary TxDictionary { get; set; } - public Dictionary RxDictionary { get; set; } - - //public Dictionary InputCards { get; private set; } - //public Dictionary OutputCards { get; private set; } - - public Dictionary InputNames { get; set; } - public Dictionary OutputNames { get; set; } - public Dictionary VolumeControls { get; private set; } - - public const int RouteOffTime = 500; - Dictionary RouteOffTimers = new Dictionary(); - - /// - /// Text that represents when an output has no source routed to it - /// - public string NoRouteText = ""; - - /// - /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now - /// - public static DmChassisController GetDmChassisController(string key, string name, - string type, DMChassisPropertiesConfig properties) - { - try - { - type = type.ToLower(); - uint ipid = properties.Control.IpIdInt; - - DmMDMnxn chassis = null; - switch (type) { - case "dmmd8x8": - chassis = new DmMd8x8(ipid, Global.ControlSystem); - break; - case "dmmd8x8rps": - chassis = new DmMd8x8rps(ipid, Global.ControlSystem); - break; - case "dmmd8x8cpu3": - chassis = new DmMd8x8Cpu3(ipid, Global.ControlSystem); - break; - case "dmmd8x8cpu3rps": - chassis = new DmMd8x8Cpu3rps(ipid, Global.ControlSystem); - break; - case "dmmd16x16": - chassis = new DmMd16x16(ipid, Global.ControlSystem); - break; - case "dmmd16x16rps": - chassis = new DmMd16x16rps(ipid, Global.ControlSystem); - break; - case "dmmd16x16cpu3": - chassis = new DmMd16x16Cpu3(ipid, Global.ControlSystem); - break; - case "dmmd16x16cpu3rps": - chassis = new DmMd16x16Cpu3rps(ipid, Global.ControlSystem); - break; - case "dmmd32x32": - chassis = new DmMd32x32(ipid, Global.ControlSystem); - break; - case "dmmd32x32rps": - chassis = new DmMd32x32rps(ipid, Global.ControlSystem); - break; - case "dmmd32x32cpu3": - chassis = new DmMd32x32Cpu3(ipid, Global.ControlSystem); - break; - case "dmmd32x32cpu3rps": - chassis = new DmMd32x32Cpu3rps(ipid, Global.ControlSystem); - break; - } - - if (chassis == null) - return null; - - var controller = new DmChassisController(key, name, chassis); - + public Dictionary OutputStreamCardStateFeedbacks { get; private set; } + + public Dictionary InputCardHdcpCapabilityTypes { get; private set; } + + // Need a couple Lists of generic Backplane ports + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + public Dictionary TxDictionary { get; set; } + public Dictionary RxDictionary { get; set; } + + //public Dictionary InputCards { get; private set; } + //public Dictionary OutputCards { get; private set; } + + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } + public Dictionary VolumeControls { get; private set; } + + public const int RouteOffTime = 500; + Dictionary RouteOffTimers = new Dictionary(); + + /// + /// Text that represents when an output has no source routed to it + /// + public string NoRouteText = ""; + + /// + /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now + /// + public static DmChassisController GetDmChassisController(string key, string name, + string type, DMChassisPropertiesConfig properties) + { + try + { + type = type.ToLower(); + uint ipid = properties.Control.IpIdInt; + + DmMDMnxn chassis = null; + switch (type) { + case "dmmd8x8": + chassis = new DmMd8x8(ipid, Global.ControlSystem); + break; + case "dmmd8x8rps": + chassis = new DmMd8x8rps(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3": + chassis = new DmMd8x8Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3rps": + chassis = new DmMd8x8Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16": + chassis = new DmMd16x16(ipid, Global.ControlSystem); + break; + case "dmmd16x16rps": + chassis = new DmMd16x16rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3": + chassis = new DmMd16x16Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3rps": + chassis = new DmMd16x16Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32": + chassis = new DmMd32x32(ipid, Global.ControlSystem); + break; + case "dmmd32x32rps": + chassis = new DmMd32x32rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3": + chassis = new DmMd32x32Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3rps": + chassis = new DmMd32x32Cpu3rps(ipid, Global.ControlSystem); + break; + } + + if (chassis == null) + return null; + + var controller = new DmChassisController(key, name, chassis); + // var clearInputPort = new RoutingInputPort(NonePortKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.None, null, controller); - controller.InputPorts.Add(clearInputPort); - - // add the cards and port names - foreach (var kvp in properties.InputSlots) - controller.AddInputCard(kvp.Value, kvp.Key); - - foreach (var kvp in properties.OutputSlots) - controller.AddOutputCard(kvp.Value, kvp.Key); - - foreach (var kvp in properties.VolumeControls) - { - // get the card - // check it for an audio-compatible type - // make a something-something that will make it work - // retire to mountain village - var outNum = kvp.Key; - var card = controller.Chassis.Outputs[outNum].Card; - Audio.Output audio = null; - if (card is DmcHdo) - audio = (card as DmcHdo).Audio; - else if (card is Dmc4kHdo) - audio = (card as Dmc4kHdo).Audio; - if (audio == null) - continue; - - // wire up the audio to something here... - controller.AddVolumeControl(outNum, audio); - } - - controller.InputNames = properties.InputNames; - controller.OutputNames = properties.OutputNames; - - if (!string.IsNullOrEmpty(properties.NoRouteText)) - { - controller.NoRouteText = properties.NoRouteText; - Debug.Console(1, controller, "Setting No Route Text value to: {0}", controller.NoRouteText); - } - else - { - Debug.Console(1, controller, "NoRouteText not specified. Defaulting to blank string.", controller.NoRouteText); - } - - controller.PropertiesConfig = properties; - return controller; - } - catch (Exception e) - { - Debug.Console(0, "Error creating DM chassis:\r{0}", e); - } - - return null; - } - - /// - /// - /// - /// - /// - /// - public DmChassisController(string key, string name, DmMDMnxn chassis) - : base(key, name, chassis) + controller.InputPorts.Add(clearInputPort); + + // add the cards and port names + foreach (var kvp in properties.InputSlots) + controller.AddInputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.OutputSlots) + controller.AddOutputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.VolumeControls) + { + // get the card + // check it for an audio-compatible type + // make a something-something that will make it work + // retire to mountain village + var outNum = kvp.Key; + var card = controller.Chassis.Outputs[outNum].Card; + Audio.Output audio = null; + if (card is DmcHdo) + audio = (card as DmcHdo).Audio; + else if (card is Dmc4kHdo) + audio = (card as Dmc4kHdo).Audio; + if (audio == null) + continue; + + // wire up the audio to something here... + controller.AddVolumeControl(outNum, audio); + } + + controller.InputNames = properties.InputNames; + controller.OutputNames = properties.OutputNames; + + if (!string.IsNullOrEmpty(properties.NoRouteText)) + { + controller.NoRouteText = properties.NoRouteText; + Debug.Console(1, controller, "Setting No Route Text value to: {0}", controller.NoRouteText); + } + else + { + Debug.Console(1, controller, "NoRouteText not specified. Defaulting to blank string.", controller.NoRouteText); + } + + controller.PropertiesConfig = properties; + return controller; + } + catch (Exception e) + { + Debug.Console(0, "Error creating DM chassis:\r{0}", e); + } + + return null; + } + + /// + /// + /// + /// + /// + /// + public DmChassisController(string key, string name, DmMDMnxn chassis) + : base(key, name, chassis) { - - Chassis = chassis; - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - VolumeControls = new Dictionary(); - TxDictionary = new Dictionary(); - RxDictionary = new Dictionary(); - IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); - Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); - Chassis.DMSystemChange += new DMSystemEventHandler(Chassis_DMSystemChange); - Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); - Chassis.BaseEvent += ChassisOnBaseEvent; - VideoOutputFeedbacks = new Dictionary(); - AudioOutputFeedbacks = new Dictionary(); - UsbOutputRoutedToFeebacks = new Dictionary(); - UsbInputRoutedToFeebacks = new Dictionary(); - OutputDisabledByHdcpFeedbacks = new Dictionary(); - VideoInputSyncFeedbacks = new Dictionary(); - InputNameFeedbacks = new Dictionary(); - OutputNameFeedbacks = new Dictionary(); - OutputVideoRouteNameFeedbacks = new Dictionary(); - OutputAudioRouteNameFeedbacks = new Dictionary(); - InputEndpointOnlineFeedbacks = new Dictionary(); - OutputEndpointOnlineFeedbacks = new Dictionary(); - - SystemIdFeebdack = new IntFeedback(() => { return (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue; }); - SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; }); - EnableAudioBreakawayFeedback = - new BoolFeedback(() => (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); - EnableUsbBreakawayFeedback = - new BoolFeedback(() => (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); - + + Chassis = chassis; + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + VolumeControls = new Dictionary(); + TxDictionary = new Dictionary(); + RxDictionary = new Dictionary(); + IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); + Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); + Chassis.DMSystemChange += new DMSystemEventHandler(Chassis_DMSystemChange); + Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + Chassis.BaseEvent += ChassisOnBaseEvent; + VideoOutputFeedbacks = new Dictionary(); + AudioOutputFeedbacks = new Dictionary(); + UsbOutputRoutedToFeebacks = new Dictionary(); + UsbInputRoutedToFeebacks = new Dictionary(); + OutputDisabledByHdcpFeedbacks = new Dictionary(); + VideoInputSyncFeedbacks = new Dictionary(); + InputNameFeedbacks = new Dictionary(); + OutputNameFeedbacks = new Dictionary(); + OutputVideoRouteNameFeedbacks = new Dictionary(); + OutputAudioRouteNameFeedbacks = new Dictionary(); + InputEndpointOnlineFeedbacks = new Dictionary(); + OutputEndpointOnlineFeedbacks = new Dictionary(); + + SystemIdFeebdack = new IntFeedback(() => { return (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue; }); + SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; }); + EnableAudioBreakawayFeedback = + new BoolFeedback(() => (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); + EnableUsbBreakawayFeedback = + new BoolFeedback(() => (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); + InputCardHdcpStateFeedbacks = new Dictionary(); InputStreamCardStateFeedbacks = new Dictionary(); - OutputStreamCardStateFeedbacks = new Dictionary(); - InputCardHdcpCapabilityTypes = new Dictionary(); - - for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) - { - var tempX = x; - - if (Chassis.Outputs[tempX] != null) - { - VideoOutputFeedbacks[tempX] = new IntFeedback(() => { - if (Chassis.Outputs[tempX].VideoOutFeedback != null) - return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; - - return 0; - }); - AudioOutputFeedbacks[tempX] = new IntFeedback(() => { - if (Chassis.Outputs[tempX].AudioOutFeedback != null) - return (ushort)Chassis.Outputs[tempX].AudioOutFeedback.Number; - - return 0; - }); - UsbOutputRoutedToFeebacks[tempX] = new IntFeedback(() => { - if (Chassis.Outputs[tempX].USBRoutedToFeedback != null) - return (ushort)Chassis.Outputs[tempX].USBRoutedToFeedback.Number; - - return 0; - }); - - OutputNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Outputs[tempX].NameFeedback != null) - return Chassis.Outputs[tempX].NameFeedback.StringValue; - - return ""; - }); - OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Outputs[tempX].VideoOutFeedback != null) - return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; - - return NoRouteText; - }); - OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Outputs[tempX].AudioOutFeedback != null) - return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue; - - return NoRouteText; - }); - OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => Chassis.Outputs[tempX].EndpointOnlineFeedback); - - OutputDisabledByHdcpFeedbacks[tempX] = new BoolFeedback(() => { - var output = Chassis.Outputs[tempX]; - - var hdmiTxOutput = output as Card.HdmiTx; - if (hdmiTxOutput != null) - return hdmiTxOutput.HdmiOutput.DisabledByHdcp.BoolValue; - - var dmHdmiOutput = output as Card.DmHdmiOutput; - if (dmHdmiOutput != null) - return dmHdmiOutput.DisabledByHdcpFeedback.BoolValue; - - var dmsDmOutAdvanced = output as Card.DmsDmOutAdvanced; - if (dmsDmOutAdvanced != null) - return dmsDmOutAdvanced.DisabledByHdcpFeedback.BoolValue; - - var dmps3HdmiAudioOutput = output as Card.Dmps3HdmiAudioOutput; - if (dmps3HdmiAudioOutput != null) - return dmps3HdmiAudioOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; - - var dmps3HdmiOutput = output as Card.Dmps3HdmiOutput; - if (dmps3HdmiOutput != null) - return dmps3HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; - - var dmps3HdmiOutputBackend = output as Card.Dmps3HdmiOutputBackend; - if (dmps3HdmiOutputBackend != null) - return dmps3HdmiOutputBackend.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; - - // var hdRx4kX10HdmiOutput = output as HdRx4kX10HdmiOutput; - // if (hdRx4kX10HdmiOutput != null) - // return hdRx4kX10HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; - - // var hdMdNxMHdmiOutput = output as HdMdNxMHdmiOutput; - // if (hdMdNxMHdmiOutput != null) - // return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; - - return false; + OutputStreamCardStateFeedbacks = new Dictionary(); + InputCardHdcpCapabilityTypes = new Dictionary(); + + for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) + { + var tempX = x; + + if (Chassis.Outputs[tempX] != null) + { + VideoOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; + + return 0; + }); + AudioOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].AudioOutFeedback.Number; + + return 0; + }); + UsbOutputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Outputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + + OutputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].NameFeedback != null) + return Chassis.Outputs[tempX].NameFeedback.StringValue; + + return ""; + }); + OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => Chassis.Outputs[tempX].EndpointOnlineFeedback); + + OutputDisabledByHdcpFeedbacks[tempX] = new BoolFeedback(() => { + var output = Chassis.Outputs[tempX]; + + var hdmiTxOutput = output as Card.HdmiTx; + if (hdmiTxOutput != null) + return hdmiTxOutput.HdmiOutput.DisabledByHdcp.BoolValue; + + var dmHdmiOutput = output as Card.DmHdmiOutput; + if (dmHdmiOutput != null) + return dmHdmiOutput.DisabledByHdcpFeedback.BoolValue; + + var dmsDmOutAdvanced = output as Card.DmsDmOutAdvanced; + if (dmsDmOutAdvanced != null) + return dmsDmOutAdvanced.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiAudioOutput = output as Card.Dmps3HdmiAudioOutput; + if (dmps3HdmiAudioOutput != null) + return dmps3HdmiAudioOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutput = output as Card.Dmps3HdmiOutput; + if (dmps3HdmiOutput != null) + return dmps3HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutputBackend = output as Card.Dmps3HdmiOutputBackend; + if (dmps3HdmiOutputBackend != null) + return dmps3HdmiOutputBackend.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdRx4kX10HdmiOutput = output as HdRx4kX10HdmiOutput; + // if (hdRx4kX10HdmiOutput != null) + // return hdRx4kX10HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdMdNxMHdmiOutput = output as HdMdNxMHdmiOutput; + // if (hdMdNxMHdmiOutput != null) + // return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + return false; }); OutputStreamCardStateFeedbacks[tempX] = new IntFeedback(() => { @@ -346,105 +346,105 @@ namespace PepperDash.Essentials.DM Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding output stream card in slot: {0}. Error: {1}", tempX, iopex); return 0; } - }); - } - - if (Chassis.Inputs[tempX] != null) - { - UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { - if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) - return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; - - return 0; - }); - VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { - if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) - return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; - - return false; - }); - InputNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Inputs[tempX].NameFeedback != null) - return Chassis.Inputs[tempX].NameFeedback.StringValue; - - return ""; - }); - - InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); - - InputCardHdcpStateFeedbacks[tempX] = new IntFeedback(() => { - try - { - var inputCard = Chassis.Inputs[tempX]; - - if (inputCard.Card is DmcHd) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - if ((inputCard.Card as DmcHd).HdmiInput.HdcpSupportOnFeedback.BoolValue) - return 1; - return 0; - } - - if (inputCard.Card is DmcHdDsp) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - if ((inputCard.Card as DmcHdDsp).HdmiInput.HdcpSupportOnFeedback.BoolValue) - return 1; - return 0; - } - if (inputCard.Card is Dmc4kHdBase) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; - return (int)(inputCard.Card as Dmc4kHdBase).HdmiInput.HdcpReceiveCapability; - } - if (inputCard.Card is Dmc4kHdDspBase) - { - if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; - return (int)(inputCard.Card as Dmc4kHdDspBase).HdmiInput.HdcpReceiveCapability; - } - - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - if ((inputCard.Card as Dmc4kHdDspBase).HdmiInput.HdcpSupportOnFeedback.BoolValue) - return 1; - return 0; - } - - if (inputCard.Card is Dmc4kCBase) - { - if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - return (int)(inputCard.Card as Dmc4kCBase).DmInput.HdcpReceiveCapability; - } - - if ((inputCard.Card as Dmc4kCBase).DmInput.HdcpSupportOnFeedback.BoolValue) - return 1; - return 0; - } - if (inputCard.Card is Dmc4kCDspBase) - { - if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - return (int)(inputCard.Card as Dmc4kCDspBase).DmInput.HdcpReceiveCapability; - } - - if ((inputCard.Card as Dmc4kCDspBase).DmInput.HdcpSupportOnFeedback.BoolValue) - return 1; - - return 0; - } - return 0; - } - catch (InvalidOperationException iopex) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "The Input Card in slot: {0} supports HDCP 2. Please update the configuration value in the inputCardSupportsHdcp2 object to true. Error: {1}", tempX, iopex); - return 0; - } + }); + } + + if (Chassis.Inputs[tempX] != null) + { + UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { + if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) + return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; + + return false; + }); + InputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Inputs[tempX].NameFeedback != null) + return Chassis.Inputs[tempX].NameFeedback.StringValue; + + return ""; + }); + + InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); + + InputCardHdcpStateFeedbacks[tempX] = new IntFeedback(() => { + try + { + var inputCard = Chassis.Inputs[tempX]; + + if (inputCard.Card is DmcHd) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHd).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + + if (inputCard.Card is DmcHdDsp) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHdDsp).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kHdBase) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; + return (int)(inputCard.Card as Dmc4kHdBase).HdmiInput.HdcpReceiveCapability; + } + if (inputCard.Card is Dmc4kHdDspBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; + return (int)(inputCard.Card as Dmc4kHdDspBase).HdmiInput.HdcpReceiveCapability; + } + + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + if ((inputCard.Card as Dmc4kHdDspBase).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + + if (inputCard.Card is Dmc4kCBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kCDspBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCDspBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCDspBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + + return 0; + } + return 0; + } + catch (InvalidOperationException iopex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "The Input Card in slot: {0} supports HDCP 2. Please update the configuration value in the inputCardSupportsHdcp2 object to true. Error: {1}", tempX, iopex); + return 0; + } }); InputStreamCardStateFeedbacks[tempX] = new IntFeedback(() => { @@ -472,111 +472,111 @@ namespace PepperDash.Essentials.DM Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Error adding input stream card in slot: {0}. Error: {1}", tempX, iopex); return 0; } - }); - } - } - } - - private void ChassisOnBaseEvent(GenericBase device, BaseEventArgs args) - { - - } - - /// - /// - /// - /// - /// - public void AddInputCard(string type, uint number) - { - Debug.Console(2, this, "Adding input card '{0}', slot {1}", type, number); - - type = type.ToLower(); - + }); + } + } + } + + private void ChassisOnBaseEvent(GenericBase device, BaseEventArgs args) + { + + } + + /// + /// + /// + /// + /// + public void AddInputCard(string type, uint number) + { + Debug.Console(2, this, "Adding input card '{0}', slot {1}", type, number); + + type = type.ToLower(); + switch (type) { case "dmchd": - { - var inputCard = new DmcHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new DmcHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmchddsp": - { - var inputCard = new DmcHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new DmcHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmc4khd": - { - var inputCard = new Dmc4kHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmc4khddsp": - { - var inputCard = new Dmc4kHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmc4kzhd": - { - var inputCard = new Dmc4kzHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kzHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmc4kzhddsp": - { - var inputCard = new Dmc4kzHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kzHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); } break; case "dmcc": - { - var inputCard = new DmcC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new DmcC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmccdsp": - { - var inputCard = new DmcCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new DmcCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmc4kc": - { - var inputCard = new Dmc4kC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmc4kcdsp": - { - var inputCard = new Dmc4kCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmc4kzc": - { - var inputCard = new Dmc4kzC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kzC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmc4kzcdsp": - { - var inputCard = new Dmc4kzCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + { + var inputCard = new Dmc4kzCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); } break; case "dmccat": @@ -610,7 +610,7 @@ namespace PepperDash.Essentials.DM case "dmcsdi": new DmcSdi(number, Chassis); AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi, null); AddInCardHdmiAndAudioLoopPorts(number); break; @@ -657,324 +657,324 @@ namespace PepperDash.Essentials.DM AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); AddInCardHdmiAndAudioLoopPorts(number); break; - } - } - - void AddDmInCardPorts(uint number) - { - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); - AddInCardHdmiAndAudioLoopPorts(number); - } - - void AddDmInCardPorts(uint number, ICec cecPort) - { - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); - AddInCardHdmiAndAudioLoopPorts(number); - } - - void AddHdmiInCardPorts(uint number, ICec cecPort) - { - AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); - AddInCardHdmiAndAudioLoopPorts(number); - } - - void AddInCardHdmiAndAudioLoopPorts(uint number) - { - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null); - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "audioLoopOut", eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null); - } - - void AddInCardHdmiLoopPort(uint number) - { - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null); - } - - /// - /// - /// - /// - /// - public void AddOutputCard(string type, uint number) - { - type = type.ToLower(); - - Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); + } + } + + void AddDmInCardPorts(uint number) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddDmInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddHdmiInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddInCardHdmiAndAudioLoopPorts(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "audioLoopOut", eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null); + } + + void AddInCardHdmiLoopPort(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + } + + /// + /// + /// + /// + /// + public void AddOutputCard(string type, uint number) + { + type = type.ToLower(); + + Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); switch (type) { case "dmc4khdo": - { - var outputCard = new Dmc4kHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); + { + var outputCard = new Dmc4kHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); } break; case "dmc4kzhdo": - { - var outputCard = new Dmc4kzHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); + { + var outputCard = new Dmc4kzHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); } break; case "dmchdo": - { - var outputCard = new DmcHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); + { + var outputCard = new DmcHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); } break; case "dmc4kcohd": - { - var outputCard = new Dmc4kCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); + { + var outputCard = new Dmc4kCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); } break; case "dmc4kzcohd": - { - var outputCard = new Dmc4kzCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); + { + var outputCard = new Dmc4kzCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); } break; case "dmccohd": - { - var outputCard = new DmcCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); + { + var outputCard = new DmcCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); } break; case "dmccatohd": - { - var outputCard = new DmcCatoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); + { + var outputCard = new DmcCatoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); } break; case "dmcsohd": - { - var outputCard = new DmcSoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 1]); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 2]); + { + var outputCard = new DmcSoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[2 * (number - 1) + 2]); } break; case "dmcs2ohd": - { - var outputCard = new DmcS2oHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 1]); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 2]); + { + var outputCard = new DmcS2oHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[2 * (number - 1) + 2]); } break; case "dmcstro": - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming, Chassis.Outputs[2 * (number - 1) + 1]); break; default: Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); break; - } - } - - void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) - { - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, - Chassis.Outputs[2 * (number - 1) + 1]); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 2], cecPort2); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, - Chassis.Outputs[2 * (number - 1) + 2]); - } - - void AddDmcCoPorts(uint number, ICec cecPort1) - { - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 1]); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 2]); - } - - /// - /// Adds InputPort - /// + } + } + + void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 2], cecPort2); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + Chassis.Outputs[2 * (number - 1) + 2]); + } + + void AddDmcCoPorts(uint number, ICec cecPort1) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 1]); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, Chassis.Outputs[2 * (number - 1) + 1], cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, Chassis.Outputs[2 * (number - 1) + 2]); + } + + /// + /// Adds InputPort + /// void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { AddInputPortWithDebug(cardNum, portName, sigType, portType, null); - } - - /// - /// Adds InputPort and sets Port as ICec object - /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) - { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); + } + + /// + /// Adds InputPort and sets Port as ICec object + /// + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) + { + var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding input port '{0}'", portKey); var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) { FeedbackMatchObject = Chassis.Inputs[cardNum] - }; ; - - if (cecPort != null) - inputPort.Port = cecPort; - + }; ; + + if (cecPort != null) + inputPort.Port = cecPort; + InputPorts.Add(inputPort); - } - - /// - /// Adds OutputPort - /// + } + + /// + /// Adds OutputPort + /// void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { AddOutputPortWithDebug(cardName, portName, sigType, portType, selector, null); - } - - /// - /// Adds OutputPort and sets Port as ICec object - /// - void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) - { - var portKey = string.Format("{0}--{1}", cardName, portName); + } + + /// + /// Adds OutputPort and sets Port as ICec object + /// + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) + { + var portKey = string.Format("{0}--{1}", cardName, portName); Debug.Console(2, this, "Adding output port '{0}'", portKey); var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0) { outputPort.FeedbackMatchObject = selector; - } - if (cecPort != null) - outputPort.Port = cecPort; - + } + if (cecPort != null) + outputPort.Port = cecPort; + OutputPorts.Add(outputPort); - } - - /// - /// - /// - void AddVolumeControl(uint number, Audio.Output audio) - { - VolumeControls.Add(number, new DmCardAudioOutputController(audio)); - } - - //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) - //{ - - //} - - void Chassis_DMSystemChange(Switch device, DMSystemEventArgs args) - { - switch (args.EventId) - { - case DMSystemEventIds.SystemIdEventId: - { - Debug.Console(2, this, "SystemIdEvent Value: {0}", (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue); - SystemIdFeebdack.FireUpdate(); - break; - } - case DMSystemEventIds.SystemIdBusyEventId: - { - Debug.Console(2, this, "SystemIdBusyEvent State: {0}", (Chassis as DmMDMnxn).SystemIdBusy.BoolValue); - SystemIdBusyFeedback.FireUpdate(); - break; - } - case DMSystemEventIds.AudioBreakawayEventId: - { - Debug.Console(2, this, "AudioBreakaway Event: value: {0}", - (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); - EnableAudioBreakawayFeedback.FireUpdate(); - break; - } - case DMSystemEventIds.USBBreakawayEventId: - { - Debug.Console(2, this, "USBBreakaway Event: value: {0}", - (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); - EnableUsbBreakawayFeedback.FireUpdate(); - break; - } - } - } - - void Chassis_DMInputChange(Switch device, DMInputEventArgs args) - { - try - { - switch (args.EventId) - { - case DMInputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); - InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); - InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.VideoDetectedEventId: - { - Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); - VideoInputSyncFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.InputNameEventId: - { - Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); - InputNameFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.UsbRoutedToEventId: - { - Debug.Console(2, this, "DM Input {0} UsbRoutedToEventId", args.Number); - if (UsbInputRoutedToFeebacks[args.Number] != null) - UsbInputRoutedToFeebacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in UsbInputRoutedToFeedbacks"); - break; - } - case DMInputEventIds.HdcpCapabilityFeedbackEventId: - { - Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); - if (InputCardHdcpStateFeedbacks[args.Number] != null) - InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); - break; - } - case DMInputEventIds.HdcpSupportOffEventId: - { - Debug.Console(2, this, "DM Input {0} HdcpSupportOffEventId", args.Number); - if (InputCardHdcpStateFeedbacks[args.Number] != null) - InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); - break; - } - case DMInputEventIds.HdcpSupportOnEventId: - { - Debug.Console(2, this, "DM Input {0} HdcpSupportOnEventId", args.Number); - if (InputCardHdcpStateFeedbacks[args.Number] != null) - InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); - break; + } + + /// + /// + /// + void AddVolumeControl(uint number, Audio.Output audio) + { + VolumeControls.Add(number, new DmCardAudioOutputController(audio)); + } + + //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) + //{ + + //} + + void Chassis_DMSystemChange(Switch device, DMSystemEventArgs args) + { + switch (args.EventId) + { + case DMSystemEventIds.SystemIdEventId: + { + Debug.Console(2, this, "SystemIdEvent Value: {0}", (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue); + SystemIdFeebdack.FireUpdate(); + break; + } + case DMSystemEventIds.SystemIdBusyEventId: + { + Debug.Console(2, this, "SystemIdBusyEvent State: {0}", (Chassis as DmMDMnxn).SystemIdBusy.BoolValue); + SystemIdBusyFeedback.FireUpdate(); + break; + } + case DMSystemEventIds.AudioBreakawayEventId: + { + Debug.Console(2, this, "AudioBreakaway Event: value: {0}", + (Chassis as DmMDMnxn).EnableAudioBreakawayFeedback.BoolValue); + EnableAudioBreakawayFeedback.FireUpdate(); + break; + } + case DMSystemEventIds.USBBreakawayEventId: + { + Debug.Console(2, this, "USBBreakaway Event: value: {0}", + (Chassis as DmMDMnxn).EnableUSBBreakawayFeedback.BoolValue); + EnableUsbBreakawayFeedback.FireUpdate(); + break; + } + } + } + + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { + try + { + switch (args.EventId) + { + case DMInputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); + VideoInputSyncFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.InputNameEventId: + { + Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); + InputNameFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Input {0} UsbRoutedToEventId", args.Number); + if (UsbInputRoutedToFeebacks[args.Number] != null) + UsbInputRoutedToFeebacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in UsbInputRoutedToFeedbacks"); + break; + } + case DMInputEventIds.HdcpCapabilityFeedbackEventId: + { + Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); + if (InputCardHdcpStateFeedbacks[args.Number] != null) + InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); + break; + } + case DMInputEventIds.HdcpSupportOffEventId: + { + Debug.Console(2, this, "DM Input {0} HdcpSupportOffEventId", args.Number); + if (InputCardHdcpStateFeedbacks[args.Number] != null) + InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); + break; + } + case DMInputEventIds.HdcpSupportOnEventId: + { + Debug.Console(2, this, "DM Input {0} HdcpSupportOnEventId", args.Number); + if (InputCardHdcpStateFeedbacks[args.Number] != null) + InputCardHdcpStateFeedbacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); + break; } case DMInputEventIds.StartEventId: case DMInputEventIds.StopEventId: @@ -988,18 +988,18 @@ namespace PepperDash.Essentials.DM else Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks"); break; - } - default: - { - Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); - break; - } - } - } - catch (Exception ex) - { - Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Chassis_DMInputChange: {0}", ex); - } + } + default: + { + Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + catch (Exception ex) + { + Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Chassis_DMInputChange: {0}", ex); + } } /// @@ -1011,42 +1011,42 @@ namespace PepperDash.Essentials.DM { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } - - /// - /// - void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) - { - var output = args.Number; - - switch (args.EventId) - { - case DMOutputEventIds.VolumeEventId: - { - if (VolumeControls.ContainsKey(output)) - { - VolumeControls[args.Number].VolumeEventFromChassis(); - } - - break; - } - case DMOutputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, - Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, - Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } + } + + /// + /// + void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) + { + var output = args.Number; + + switch (args.EventId) + { + case DMOutputEventIds.VolumeEventId: + { + if (VolumeControls.ContainsKey(output)) + { + VolumeControls[args.Number].VolumeEventFromChassis(); + } + + break; + } + case DMOutputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } case DMOutputEventIds.VideoOutEventId: - { - + { + var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis. Outputs[output].VideoOutFeedback.Number; @@ -1067,11 +1067,11 @@ namespace PepperDash.Essentials.DM eRoutingSignalType.Video)); } - if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) - OutputVideoRouteNameFeedbacks[output].FireUpdate(); - - break; - } + if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) + OutputVideoRouteNameFeedbacks[output].FireUpdate(); + + break; + } case DMOutputEventIds.AudioOutEventId: { var inputNumber = Chassis.Outputs[output].AudioOutFeedback == null ? 0 : Chassis. @@ -1097,25 +1097,25 @@ namespace PepperDash.Essentials.DM if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) OutputAudioRouteNameFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.OutputNameEventId: - { - Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); - OutputNameFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.UsbRoutedToEventId: - { - Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); - UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); - break; - } - case DMOutputEventIds.DisabledByHdcpEventId: - { - Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); - OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); - break; + break; + } + case DMOutputEventIds.OutputNameEventId: + { + Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); + OutputNameFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); + UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); + break; + } + case DMOutputEventIds.DisabledByHdcpEventId: + { + Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); + OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); + break; } case DMOutputEventIds.StartEventId: case DMOutputEventIds.StopEventId: @@ -1129,50 +1129,50 @@ namespace PepperDash.Essentials.DM else Debug.Console(2, this, "No index of {0} found in OutputStreamCardStateFeedbacks"); break; - } - default: - { - Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); - break; - } - } - } - - /// - /// - /// - /// - void StartOffTimer(PortNumberType pnt) - { - if (RouteOffTimers.ContainsKey(pnt)) - return; - RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); - } - - // Send out sigs when coming online - void IsOnline_OutputChange(object sender, EventArgs e) - { - if (IsOnline.BoolValue) - { - (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; - (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; - - - EnableAudioBreakawayFeedback.FireUpdate(); - EnableUsbBreakawayFeedback.FireUpdate(); - - if (InputNames != null) - foreach (var kvp in InputNames) - Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; - if (OutputNames != null) - foreach (var kvp in OutputNames) - Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; - } - } - - #region IRouting Members - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) - { + } + default: + { + Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + + /// + /// + /// + /// + void StartOffTimer(PortNumberType pnt) + { + if (RouteOffTimers.ContainsKey(pnt)) + return; + RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); + } + + // Send out sigs when coming online + void IsOnline_OutputChange(object sender, EventArgs e) + { + if (IsOnline.BoolValue) + { + (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; + (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; + + + EnableAudioBreakawayFeedback.FireUpdate(); + EnableUsbBreakawayFeedback.FireUpdate(); + + if (InputNames != null) + foreach (var kvp in InputNames) + Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; + if (OutputNames != null) + foreach (var kvp in OutputNames) + Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; + } + } + + #region IRouting Members + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) + { Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); var input = inputSelector as DMInput;//Input Selector could be null... @@ -1185,34 +1185,34 @@ namespace PepperDash.Essentials.DM "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, outputSelector); return; - } - - // Check to see if there's an off timer waiting on this and if so, cancel - var key = new PortNumberType(output, sigType); - if (input == null) - { - StartOffTimer(key); - } - else - { - if (RouteOffTimers.ContainsKey(key)) - { - Debug.Console(2, this, "{0} cancelling route off due to new source", output); - RouteOffTimers[key].Stop(); - RouteOffTimers.Remove(key); - } - } - - //var inCard = input == 0 ? null : Chassis.Inputs[input]; - //var outCard = input == 0 ? null : Chassis.Outputs[output]; - - // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES - if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) - { + } + + // Check to see if there's an off timer waiting on this and if so, cancel + var key = new PortNumberType(output, sigType); + if (input == null) + { + StartOffTimer(key); + } + else + { + if (RouteOffTimers.ContainsKey(key)) + { + Debug.Console(2, this, "{0} cancelling route off due to new source", output); + RouteOffTimers[key].Stop(); + RouteOffTimers.Remove(key); + } + } + + //var inCard = input == 0 ? null : Chassis.Inputs[input]; + //var outCard = input == 0 ? null : Chassis.Outputs[output]; + + // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES + if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) + { Chassis.VideoEnter.BoolValue = true; output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard; - } - + } + if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) { var dmMdMnxn = Chassis as DmMDMnxn; @@ -1220,7 +1220,7 @@ namespace PepperDash.Essentials.DM { dmMdMnxn.AudioEnter.BoolValue = true; } - output.VideoOut = input; + output.AudioOut = input; //Chassis.Outputs[output].AudioOut = inCard; } @@ -1228,13 +1228,13 @@ namespace PepperDash.Essentials.DM { Chassis.USBEnter.BoolValue = true; output.USBRoutedTo = input; - } - - } - #endregion - - #region IRoutingNumeric Members - + } + + } + #endregion + + #region IRoutingNumeric Members + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) { var chassisSize = (uint)Chassis.NumberOfInputs; //need this to determine USB routing values 8x8 -> 1-8 is inputs 1-8, 17-24 is outputs 1-8 @@ -1303,37 +1303,37 @@ namespace PepperDash.Essentials.DM } var inputCard = inputSelector == 0 ? null : Chassis.Inputs[inputSelector]; - var outputCard = Chassis.Outputs[outputSelector]; - - ExecuteSwitch(inputCard, outputCard, sigType); - } - - #endregion - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = GetJoinMap(joinStart, joinMapKey, bridge); - - Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - LinkChassisToApi(trilist, joinMap); - - // Link up inputs & outputs - for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) - { - var ioSlot = i; - var ioSlotJoin = ioSlot - 1; - - LinkRoutingJoinsToApi(trilist, joinMap, ioSlotJoin, ioSlot); - - if (TxDictionary.ContainsKey(ioSlot)) - { - LinkTxToApi(trilist, ioSlot, joinMap, ioSlotJoin); - } - else - { + var outputCard = Chassis.Outputs[outputSelector]; + + ExecuteSwitch(inputCard, outputCard, sigType); + } + + #endregion + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = GetJoinMap(joinStart, joinMapKey, bridge); + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + LinkChassisToApi(trilist, joinMap); + + // Link up inputs & outputs + for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) + { + var ioSlot = i; + var ioSlotJoin = ioSlot - 1; + + LinkRoutingJoinsToApi(trilist, joinMap, ioSlotJoin, ioSlot); + + if (TxDictionary.ContainsKey(ioSlot)) + { + LinkTxToApi(trilist, ioSlot, joinMap, ioSlotJoin); + } + else + { LinkHdmiInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); - LinkStreamInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); + LinkStreamInputToApi(trilist, ioSlot, joinMap, ioSlotJoin); } if (RxDictionary.ContainsKey(ioSlot)) @@ -1341,53 +1341,53 @@ namespace PepperDash.Essentials.DM LinkRxToApi(trilist, ioSlot, joinMap, ioSlotJoin); } else - LinkStreamOutputToApi(trilist, ioSlot, joinMap, ioSlotJoin); - } - } - - private void LinkHdmiInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) - { - VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - - var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort == null) - { - return; - } - - Debug.Console(1, "Port value for input card {0} is set", ioSlot); - var port = inputPort.Port; - - if (port == null) - { - return; - } - if (!(port is HdmiInputWithCEC)) - { - Debug.Console(0, this, "HDMI Input port on card {0} does not support HDCP settings.", ioSlot); - return; - } - - Debug.Console(1, "Port is HdmiInputWithCec"); - - var hdmiInPortWCec = port as HdmiInputWithCEC; - - - SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], hdmiInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - - - InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( - trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - - if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - { - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = - (ushort)InputCardHdcpCapabilityTypes[ioSlot]; - } - else - { - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; - } + LinkStreamOutputToApi(trilist, ioSlot, joinMap, ioSlotJoin); + } + } + + private void LinkHdmiInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) + { + VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + + var inputPort = InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort == null) + { + return; + } + + Debug.Console(1, "Port value for input card {0} is set", ioSlot); + var port = inputPort.Port; + + if (port == null) + { + return; + } + if (!(port is HdmiInputWithCEC)) + { + Debug.Console(0, this, "HDMI Input port on card {0} does not support HDCP settings.", ioSlot); + return; + } + + Debug.Console(1, "Port is HdmiInputWithCec"); + + var hdmiInPortWCec = port as HdmiInputWithCEC; + + + SetHdcpStateAction(PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], hdmiInPortWCec, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + + + InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( + trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + { + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = + (ushort)InputCardHdcpCapabilityTypes[ioSlot]; + } + else + { + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; + } } private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) @@ -1468,448 +1468,448 @@ namespace PepperDash.Essentials.DM OutputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]); trilist.UShortInput[join].UShortValue = OutputStreamCardStateFeedbacks[ioSlot].UShortValue; - } - - private void LinkRxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) - { - Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); - var rxKey = RxDictionary[ioSlot]; - var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; - var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; - if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps - || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps - || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) - { - OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( - trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); - } - else if (rxDevice != null) - { - rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); - } - } - - private void LinkTxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) - { - Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); - VideoInputSyncFeedbacks[ioSlot].LinkInputSig( - trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - - Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); - var txKey = TxDictionary[ioSlot]; - var txDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; - - if (txDevice == null) - { - return; - } - - LinkTxOnlineFeedbackToApi(trilist, ioSlot, joinMap, ioSlotJoin, txDevice); - - LinkBasicTxToApi(trilist, joinMap, ioSlot, ioSlotJoin, txDevice); - - LinkAdvancedTxToApi(trilist, joinMap, ioSlot, ioSlotJoin, txDevice); - } - - private void LinkBasicTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, uint ioSlot, - uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) - { - var advTx = basicTransmitter as DmTxControllerBase; - - if (advTx != null) - { - return; - } - var inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; - - if (inputPort == null) - { - return; - } - var port = inputPort.Port; - - if (!(port is DMInputPortWithCec)) - { - Debug.Console(0, this, "DM Input port on card {0} does not support HDCP settings.", ioSlot); - return; - } - Debug.Console(1, "Port is DMInputPortWithCec"); - - var dmInPortWCec = port as DMInputPortWithCec; - - bool supportsHdcp2; - - //added in case the InputSlotSupportsHdcp2 section isn't included in the config, or this slot is left out. - //if the key isn't in the dictionary, supportsHdcp2 will be false - - if(!PropertiesConfig.InputSlotSupportsHdcp2.TryGetValue(ioSlot, out supportsHdcp2)) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Warning, - "Input Slot Supports HDCP2 setting not found for slot {0}. Setting to false. Program may not function as intended.", - ioSlot); - } - - SetHdcpStateAction(supportsHdcp2, dmInPortWCec, - joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - - InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( - trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - - if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - { - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = - (ushort) InputCardHdcpCapabilityTypes[ioSlot]; - } - else - { - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; - } - } - - private void LinkAdvancedTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, - uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) - { - var transmitter = basicTransmitter as DmTxControllerBase; - if (transmitter == null) return; - - trilist.BooleanInput[joinMap.TxAdvancedIsPresent.JoinNumber + ioSlotJoin].BoolValue = true; - - transmitter.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig( - trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); - - var txRoutingInputs = transmitter as IRoutingInputs; - - if (txRoutingInputs == null) return; - - var inputPorts = txRoutingInputs.InputPorts.Where((p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList(); - - if (inputPorts.Count == 0) - { - Debug.Console(1, this, "No HDCP-capable input ports found on transmitter for slot {0}", ioSlot); - return; - } - - bool supportsHdcp2; - - if (!PropertiesConfig.InputSlotSupportsHdcp2.TryGetValue(ioSlot, out supportsHdcp2)) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Warning, - "Input Slot Supports HDCP2 setting not found for slot {0}. Setting to false. Program may not function as intended.", - ioSlot); - } - - SetHdcpStateAction(supportsHdcp2, inputPorts, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); - - if (transmitter.HdcpStateFeedback != null) - { - transmitter.HdcpStateFeedback.LinkInputSig( - trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - } - else - { - Debug.Console(2, this, "Transmitter Hdcp Feedback null. Linking to card's feedback"); - InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( - trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); - } - - trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = - (ushort) transmitter.HdcpSupportCapability; - } - - private void LinkTxOnlineFeedbackToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, - uint ioSlotJoin, BasicDmTxControllerBase txDevice) - { - var advancedTxDevice = txDevice as DmTxControllerBase; - - if ((Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps - || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps - || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps) || - advancedTxDevice == null) - { - Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); - InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( - trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); - return; - } - - Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); - - advancedTxDevice.IsOnline.LinkInputSig( - trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); - } - - private void LinkRoutingJoinsToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, uint ioSlotJoin, - uint ioSlot) - { - // Routing Control - trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, - o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); + } + + private void LinkRxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) + { + Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); + var rxKey = RxDictionary[ioSlot]; + var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; + var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; + if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) + { + OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( + trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); + } + else if (rxDevice != null) + { + rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); + } + } + + private void LinkTxToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) + { + Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); + VideoInputSyncFeedbacks[ioSlot].LinkInputSig( + trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + + Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + var txKey = TxDictionary[ioSlot]; + var txDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; + + if (txDevice == null) + { + return; + } + + LinkTxOnlineFeedbackToApi(trilist, ioSlot, joinMap, ioSlotJoin, txDevice); + + LinkBasicTxToApi(trilist, joinMap, ioSlot, ioSlotJoin, txDevice); + + LinkAdvancedTxToApi(trilist, joinMap, ioSlot, ioSlotJoin, txDevice); + } + + private void LinkBasicTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, uint ioSlot, + uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) + { + var advTx = basicTransmitter as DmTxControllerBase; + + if (advTx != null) + { + return; + } + var inputPort = InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; + + if (inputPort == null) + { + return; + } + var port = inputPort.Port; + + if (!(port is DMInputPortWithCec)) + { + Debug.Console(0, this, "DM Input port on card {0} does not support HDCP settings.", ioSlot); + return; + } + Debug.Console(1, "Port is DMInputPortWithCec"); + + var dmInPortWCec = port as DMInputPortWithCec; + + bool supportsHdcp2; + + //added in case the InputSlotSupportsHdcp2 section isn't included in the config, or this slot is left out. + //if the key isn't in the dictionary, supportsHdcp2 will be false + + if(!PropertiesConfig.InputSlotSupportsHdcp2.TryGetValue(ioSlot, out supportsHdcp2)) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Input Slot Supports HDCP2 setting not found for slot {0}. Setting to false. Program may not function as intended.", + ioSlot); + } + + SetHdcpStateAction(supportsHdcp2, dmInPortWCec, + joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + + InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( + trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + + if (InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + { + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = + (ushort) InputCardHdcpCapabilityTypes[ioSlot]; + } + else + { + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; + } + } + + private void LinkAdvancedTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, + uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) + { + var transmitter = basicTransmitter as DmTxControllerBase; + if (transmitter == null) return; + + trilist.BooleanInput[joinMap.TxAdvancedIsPresent.JoinNumber + ioSlotJoin].BoolValue = true; + + transmitter.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); + + var txRoutingInputs = transmitter as IRoutingInputs; + + if (txRoutingInputs == null) return; + + var inputPorts = txRoutingInputs.InputPorts.Where((p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList(); + + if (inputPorts.Count == 0) + { + Debug.Console(1, this, "No HDCP-capable input ports found on transmitter for slot {0}", ioSlot); + return; + } + + bool supportsHdcp2; + + if (!PropertiesConfig.InputSlotSupportsHdcp2.TryGetValue(ioSlot, out supportsHdcp2)) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Input Slot Supports HDCP2 setting not found for slot {0}. Setting to false. Program may not function as intended.", + ioSlot); + } + + SetHdcpStateAction(supportsHdcp2, inputPorts, joinMap.HdcpSupportState.JoinNumber + ioSlotJoin, trilist); + + if (transmitter.HdcpStateFeedback != null) + { + transmitter.HdcpStateFeedback.LinkInputSig( + trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + } + else + { + Debug.Console(2, this, "Transmitter Hdcp Feedback null. Linking to card's feedback"); + InputCardHdcpStateFeedbacks[ioSlot].LinkInputSig( + trilist.UShortInput[joinMap.HdcpSupportState.JoinNumber + ioSlotJoin]); + } + + trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = + (ushort) transmitter.HdcpSupportCapability; + } + + private void LinkTxOnlineFeedbackToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, + uint ioSlotJoin, BasicDmTxControllerBase txDevice) + { + var advancedTxDevice = txDevice as DmTxControllerBase; + + if ((Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps + || Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps + || Chassis is DmMd32x32Cpu3 || Chassis is DmMd32x32Cpu3rps) || + advancedTxDevice == null) + { + Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); + InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( + trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); + return; + } + + Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); + + advancedTxDevice.IsOnline.LinkInputSig( + trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); + } + + private void LinkRoutingJoinsToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, uint ioSlotJoin, + uint ioSlot) + { + // Routing Control + trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, - o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio)); + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Audio)); trilist.SetUShortSigAction(joinMap.OutputUsb.JoinNumber + ioSlotJoin, - o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbOutput)); + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbOutput)); trilist.SetUShortSigAction(joinMap.InputUsb.JoinNumber + ioSlotJoin, - o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbInput)); - - //Routing Feedbacks - VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); - AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]); - UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb.JoinNumber + ioSlotJoin]); - UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb.JoinNumber + ioSlotJoin]); - - OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); - InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); - OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig( - trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); - OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig( - trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]); - - OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig( - trilist.BooleanInput[joinMap.OutputDisabledByHdcp.JoinNumber + ioSlotJoin]); - } - - private void LinkChassisToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap) - { - var chassis = Chassis as DmMDMnxn; - - IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - - trilist.SetUShortSigAction(joinMap.SystemId.JoinNumber, o => - { - if (chassis != null) - { - chassis.SystemId.UShortValue = o; - } - }); - - trilist.SetSigTrueAction(joinMap.SystemId.JoinNumber, () => - { - if (chassis != null) - { - chassis.ApplySystemId(); - } - }); - - SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId.JoinNumber]); - SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId.JoinNumber]); - - EnableAudioBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAudioBreakaway.JoinNumber]); - EnableUsbBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsbBreakaway.JoinNumber]); - - trilist.OnlineStatusChange += (o, a) => - { - if (!a.DeviceOnLine) - { - return; - } - - EnableAudioBreakawayFeedback.FireUpdate(); - EnableUsbBreakawayFeedback.FireUpdate(); - SystemIdBusyFeedback.FireUpdate(); - SystemIdFeebdack.FireUpdate(); - }; - } - - private DmChassisControllerJoinMap GetJoinMap(uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new DmChassisControllerJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - { - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - } - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, - "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - return joinMap; - } - - private void SetHdcpStateAction(bool supportsHdcp2, HdmiInputWithCEC port, uint join, BasicTriList trilist) - { - if (!supportsHdcp2) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to off", join, s); - port.HdcpSupportOff(); - } - else if (s > 0) - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to on", join, s); - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpReceiveCapability to: {2}", join, u, (eHdcpCapabilityType)u); - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - }); - } - } - - private void SetHdcpStateAction(bool supportsHdcp2, EndpointHdmiInput port, uint join, BasicTriList trilist) - { - if (!supportsHdcp2) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to off", join, s); - port.HdcpSupportOff(); - } - else if (s > 0) - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to on", join, s); - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - Debug.Console(2, this, "Join {0} value {1} Setting HdcpReceiveCapability to: {2}", join, u, (eHdcpCapabilityType)u); - port.HdcpCapability = (eHdcpCapabilityType)u; - }); - } - } - - private void SetHdcpStateAction(bool supportsHdcp2, List ports, uint join, - BasicTriList triList) - { - if (!supportsHdcp2) - { - triList.SetUShortSigAction(join, a => - { - foreach (var tempPort in ports.Select(port => port.Port).OfType()) - { - if (a == 0) - { - tempPort.HdcpSupportOff(); - } - else if (a > 0) - { - tempPort.HdcpSupportOn(); - } - } - }); - } - else - { - triList.SetUShortSigAction(join, a => - { - foreach (var tempPort in ports.Select(port => port.Port).OfType()) - { - tempPort.HdcpCapability = (eHdcpCapabilityType) a; - } - }); - } - } - - private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) - { - if (!supportsHdcp2) - { - trilist.SetUShortSigAction(join, - s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - }); - } - else - { - trilist.SetUShortSigAction(join, - u => - { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - }); - } - } - } - - public struct PortNumberType - { - public uint Number { get; private set; } - public object Selector { get; private set; } - public eRoutingSignalType Type { get; private set; } - - public PortNumberType(object selector, eRoutingSignalType type) - : this() - { - Selector = selector; + o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.UsbInput)); + + //Routing Feedbacks + VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); + AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]); + UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb.JoinNumber + ioSlotJoin]); + UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb.JoinNumber + ioSlotJoin]); + + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); + OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig( + trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); + OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig( + trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]); + + OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig( + trilist.BooleanInput[joinMap.OutputDisabledByHdcp.JoinNumber + ioSlotJoin]); + } + + private void LinkChassisToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap) + { + var chassis = Chassis as DmMDMnxn; + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + + trilist.SetUShortSigAction(joinMap.SystemId.JoinNumber, o => + { + if (chassis != null) + { + chassis.SystemId.UShortValue = o; + } + }); + + trilist.SetSigTrueAction(joinMap.SystemId.JoinNumber, () => + { + if (chassis != null) + { + chassis.ApplySystemId(); + } + }); + + SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId.JoinNumber]); + SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId.JoinNumber]); + + EnableAudioBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAudioBreakaway.JoinNumber]); + EnableUsbBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsbBreakaway.JoinNumber]); + + trilist.OnlineStatusChange += (o, a) => + { + if (!a.DeviceOnLine) + { + return; + } + + EnableAudioBreakawayFeedback.FireUpdate(); + EnableUsbBreakawayFeedback.FireUpdate(); + SystemIdBusyFeedback.FireUpdate(); + SystemIdFeebdack.FireUpdate(); + }; + } + + private DmChassisControllerJoinMap GetJoinMap(uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmChassisControllerJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + { + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, + "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + return joinMap; + } + + private void SetHdcpStateAction(bool supportsHdcp2, HdmiInputWithCEC port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to off", join, s); + port.HdcpSupportOff(); + } + else if (s > 0) + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to on", join, s); + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpReceiveCapability to: {2}", join, u, (eHdcpCapabilityType)u); + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to off", join, s); + port.HdcpSupportOff(); + } + else if (s > 0) + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpSupport to on", join, s); + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + Debug.Console(2, this, "Join {0} value {1} Setting HdcpReceiveCapability to: {2}", join, u, (eHdcpCapabilityType)u); + port.HdcpCapability = (eHdcpCapabilityType)u; + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, List ports, uint join, + BasicTriList triList) + { + if (!supportsHdcp2) + { + triList.SetUShortSigAction(join, a => + { + foreach (var tempPort in ports.Select(port => port.Port).OfType()) + { + if (a == 0) + { + tempPort.HdcpSupportOff(); + } + else if (a > 0) + { + tempPort.HdcpSupportOn(); + } + } + }); + } + else + { + triList.SetUShortSigAction(join, a => + { + foreach (var tempPort in ports.Select(port => port.Port).OfType()) + { + tempPort.HdcpCapability = (eHdcpCapabilityType) a; + } + }); + } + } + + private void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + }); + } + else + { + trilist.SetUShortSigAction(join, + u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + }); + } + } + } + + public struct PortNumberType + { + public uint Number { get; private set; } + public object Selector { get; private set; } + public eRoutingSignalType Type { get; private set; } + + public PortNumberType(object selector, eRoutingSignalType type) + : this() + { + Selector = selector; Type = type; if (Selector is DMOutput) { Number = (selector as DMOutput).Number; - } + } else if (Selector is uint) { Number = (uint) selector; - } - } - } - - public class DmChassisControllerFactory : EssentialsDeviceFactory - { - public DmChassisControllerFactory() - { - TypeNames = new List() { "dmmd8x8", "dmmd8x8rps", "dmmd8x8cpu3", "dmmd8x8cpu3rps", - "dmmd16x16", "dmmd16x16rps", "dmmd16x16cpu3", "dmmd16x16cpu3rps", - "dmmd32x32", "dmmd32x32rps", "dmmd32x32cpu3", "dmmd32x32cpu3rps", - "dmmd64x64", "dmmd128x128" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - var type = dc.Type.ToLower(); - - Debug.Console(1, "Factory Attempting to create new DmChassisController Device"); - - if (type.StartsWith("dmmd8x") || type.StartsWith("dmmd16x") || type.StartsWith("dmmd32x")) - { - - var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmChassisController. - GetDmChassisController(dc.Key, dc.Name, type, props); - } - else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) - { - var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmBladeChassisController. - GetDmChassisController(dc.Key, dc.Name, type, props); - } - - return null; - } - } - + } + } + } + + public class DmChassisControllerFactory : EssentialsDeviceFactory + { + public DmChassisControllerFactory() + { + TypeNames = new List() { "dmmd8x8", "dmmd8x8rps", "dmmd8x8cpu3", "dmmd8x8cpu3rps", + "dmmd16x16", "dmmd16x16rps", "dmmd16x16cpu3", "dmmd16x16cpu3rps", + "dmmd32x32", "dmmd32x32rps", "dmmd32x32cpu3", "dmmd32x32cpu3rps", + "dmmd64x64", "dmmd128x128" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + var type = dc.Type.ToLower(); + + Debug.Console(1, "Factory Attempting to create new DmChassisController Device"); + + if (type.StartsWith("dmmd8x") || type.StartsWith("dmmd16x") || type.StartsWith("dmmd32x")) + { + + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) + { + var props = JsonConvert.DeserializeObject + (dc.Properties.ToString()); + return PepperDash.Essentials.DM.DmBladeChassisController. + GetDmChassisController(dc.Key, dc.Name, type, props); + } + + return null; + } + } + } \ No newline at end of file From d6445861f59efc98aeecf13f6ea8e5b77e4ba5c2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 5 May 2021 21:55:28 -0600 Subject: [PATCH 208/480] Adds IHasZoomRoomLayouts interface. Update zStatus.Layout class to extend NotifiableObject --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 22 +++ .../VideoCodec/ZoomRoom/ResponseObjects.cs | 172 +++++++++++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 39 ++++ 3 files changed, 226 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 131d610f..139935c0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -19,4 +19,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void LocalLayoutToggleSingleProminent(); void MinMaxLayoutToggle(); } + + /// + /// Defines the requirements for Zoom Room layout control + /// + public interface IHasZoomRoomLayouts : IHasCodecLayouts + { + BoolFeedback LayoutViewIsOnFirstPage { get; } + BoolFeedback LayoutViewIsOnLastPage { get; } + BoolFeedback CanSwitchWallView { get; } + BoolFeedback CanSwitchSpeakerView { get; } + BoolFeedback CanSwitchShareOnAllScreens { get; } + BoolFeedback CanSwapContentWithThumbnail { get; } + + List AvailableLayouts { get; } + + void GetLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout + void SetLayout(ZoomRoom.eZoomRoomLayoutStyle layoutStyle); + void SwapContentWithThumbnail(); + + void LayoutTurnNextPage(); + void LayoutTurnPreviousPage(); + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 36cce89f..a3ad932c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -23,6 +23,46 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom zCommand } + /// + /// The available layout styles + /// + public enum eZoomRoomLayoutStyle + { + Gallery, + Speaker, + Strip, + ShareAll + } + + /// + /// The avaliable layout positions for the thumbnails + /// + public enum eZoomRoomLayoutPosition + { + Center, + Up, + Right, + UpRight, + Down, + DownRight, + Left, + UpLeft, + DownLeft + } + + /// + /// The available layout sizes + /// + public enum eZoomRoomLayoutSize + { + Off, + Size1, + Size2, + Size3, + Strip + } + + public abstract class NotifiableObject : INotifyPropertyChanged { #region INotifyPropertyChanged Members @@ -551,18 +591,136 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } - public class Layout + public class Layout : NotifiableObject { + // backer variables + private bool _can_Switch_Speaker_View; + private bool _can_Switch_Wall_View; + private bool _can_Switch_Share_On_All_Screens; + private bool _is_In_First_Page; + private bool _is_In_Last_Page; + private string _video_type; + + public bool can_Adjust_Floating_Video { get; set; } public bool can_Switch_Floating_Share_Content { get; set; } - public bool can_Switch_Share_On_All_Screens { get; set; } - public bool can_Switch_Speaker_View { get; set; } - public bool can_Switch_Wall_View { get; set; } - public bool is_In_First_Page { get; set; } - public bool is_In_Last_Page { get; set; } + + /// + /// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails. + /// + [JsonProperty("can_Switch_Share_On_All_Screens")] + public bool can_Switch_Share_On_All_Screens + { + get + { + return _can_Switch_Share_On_All_Screens; + } + set + { + if (value != _can_Switch_Share_On_All_Screens) + { + _can_Switch_Share_On_All_Screens = value; + NotifyPropertyChanged("can_Switch_Share_On_All_Screens"); + } + } + } + + /// + /// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails. + /// + [JsonProperty("can_Switch_Speaker_View")] + public bool can_Switch_Speaker_View + { + get + { + return _can_Switch_Speaker_View; + } + set + { + if (value != _can_Switch_Speaker_View) + { + _can_Switch_Speaker_View = value; + NotifyPropertyChanged("can_Switch_Speaker_View"); + } + } + } + + /// + /// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page. + /// + [JsonProperty("can_Switch_Wall_View")] + public bool can_Switch_Wall_View + { + get + { + return _can_Switch_Wall_View; + } + set + { + if (value != _can_Switch_Wall_View) + { + _can_Switch_Wall_View = value; + NotifyPropertyChanged("can_Switch_Wall_View"); + } + } + } + + [JsonProperty("is_In_First_Page")] + public bool is_In_First_Page + { + get + { + return _is_In_First_Page; + } + set + { + if (value != _is_In_First_Page) + { + _is_In_First_Page = value; + NotifyPropertyChanged("is_In_First_Page"); + } + } + } + + [JsonProperty("is_In_Last_Page")] + public bool is_In_Last_Page + { + get + { + return _is_In_Last_Page; + } + set + { + if (value != _is_In_Last_Page) + { + _is_In_Last_Page = value; + NotifyPropertyChanged("is_In_Last_Page"); + } + } + } + public bool is_supported { get; set; } public int video_Count_In_Current_Page { get; set; } - public string video_type { get; set; } + + /// + /// [Gallery | Strip] Indicates which mode applies: Strip or Gallery. + /// + [JsonProperty("video_type")] + public string video_type + { + get + { + return _video_type; + } + set + { + if (value != _video_type) + { + _video_type = value; + NotifyPropertyChanged("video_type"); + } + } + } } public class CallRecordInfo diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 42a389a7..905957f2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -542,6 +542,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; } }; + + Status.Layout.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "can_Switch_Speaker_View": + { + // TODO: #697 Fire appropriate feedback(s) + break; + } + case "can_Switch_Wall_View": + { + // #697 TODO: Fire appropriate feedback(s) + break; + } + case "can_Switch_Share_On_All_Screens": + { + // #697 TODO: Fire appropriate feedback(s) + break; + } + case "is_In_First_Page": + { + // TODO: #697 Fire appropriate feedback(s) + // + break; + } + case "is_In_Last_Page": + { + // TODO: #697 Fire appropriate feedback(s) + break; + } + case "video_type": + { + // TODO: #697 Fire appropriate feedback(s) + // LocalLayoutFeedback.FireUpdate(); + break; + } + } + }; } private void SetUpDirectory() From e4a39337434ed896f5dab3801187adb735e341e4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 May 2021 16:54:41 -0600 Subject: [PATCH 209/480] Mostly coded. Needs join numbers for ZoomRoomJoinMap values --- .../Essentials Devices Common.csproj | 1 + .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 24 +- .../VideoCodec/VideoCodecBase.cs | 273 ++++++++++-------- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 114 ++++---- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 258 +++++++++++++++-- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 141 +++++++++ 6 files changed, 592 insertions(+), 219 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 6586bd41..3d9e5d30 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -176,6 +176,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 139935c0..8ba3d139 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -25,20 +25,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasZoomRoomLayouts : IHasCodecLayouts { - BoolFeedback LayoutViewIsOnFirstPage { get; } - BoolFeedback LayoutViewIsOnLastPage { get; } - BoolFeedback CanSwitchWallView { get; } - BoolFeedback CanSwitchSpeakerView { get; } - BoolFeedback CanSwitchShareOnAllScreens { get; } - BoolFeedback CanSwapContentWithThumbnail { get; } + event EventHandler AvailableLayoutsChanged; - List AvailableLayouts { get; } + BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func + BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func + BoolFeedback CanSwapContentWithThumbnailFeedback { get; } + BoolFeedback ContentSwappedWithThumbnailFeedback { get; } - void GetLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout - void SetLayout(ZoomRoom.eZoomRoomLayoutStyle layoutStyle); + ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } + ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } + + void GetAvailableLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout + void SetLayout(ZoomRoom.zConfiguration.eLayoutStyle layoutStyle); void SwapContentWithThumbnail(); void LayoutTurnNextPage(); void LayoutTurnPreviousPage(); } + + public class LayoutInfoChangedEventArgs : EventArgs + { + public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; } + } } \ No newline at end of file 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 1a755cef..7b2f7f42 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 @@ -271,6 +271,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + /// + /// Use this method when using a plain VideoCodecControllerJoinMap + /// + /// + /// + /// + /// + /// protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { @@ -288,136 +296,145 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec bridge.AddJoinMap(Key, joinMap); } - Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); - - - - LinkVideoCodecDtmfToApi(trilist, joinMap); - - LinkVideoCodecCallControlsToApi(trilist, joinMap); - - LinkVideoCodecContentSharingToApi(trilist, joinMap); - - LinkVideoCodecPrivacyToApi(trilist, joinMap); - - LinkVideoCodecVolumeToApi(trilist, joinMap); - - if (codec is ICommunicationMonitor) - { - LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); - } - - if (codec is IHasCodecCameras) - { - LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); - } - - if (codec is IHasCodecSelfView) - { - LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); - LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); - } - - if (codec is IHasCameraOff) - { - trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); - LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); - } - - if (codec is IHasCodecLayouts) - { - LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); - } - - if (codec is IHasSelfviewPosition) - { - LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); - } - - if (codec is IHasDirectory) - { - LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); - } - - if (codec is IHasScheduleAwareness) - { - LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); - } - - if (codec is IHasParticipants) - { - LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); - } - - if (codec is IHasFarEndContentStatus) - { - (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); - } - - if (codec is IHasPhoneDialing) - { - LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); - } - - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; - - if (codec is IHasDirectory) - { - (codec as IHasDirectory).SetCurrentDirectoryToRoot(); - } - - if (codec is IHasScheduleAwareness) - { - (codec as IHasScheduleAwareness).GetSchedule(); - } - - if (codec is IHasParticipants) - { - UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); - - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCodecSelfView) - { - (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraAutoMode) - { - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraOff) - { - (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); - } - - if (codec is IHasPhoneDialing) - { - (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); - } - - SharingContentIsOnFeedback.FireUpdate(); - - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; + LinkVideoCodecToApi(codec, trilist, joinMap); } + /// + /// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap + /// + /// + /// + /// + protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); + + LinkVideoCodecDtmfToApi(trilist, joinMap); + + LinkVideoCodecCallControlsToApi(trilist, joinMap); + + LinkVideoCodecContentSharingToApi(trilist, joinMap); + + LinkVideoCodecPrivacyToApi(trilist, joinMap); + + LinkVideoCodecVolumeToApi(trilist, joinMap); + + if (codec is ICommunicationMonitor) + { + LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); + } + + if (codec is IHasCodecCameras) + { + LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); + } + + if (codec is IHasCodecSelfView) + { + LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); + LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); + } + + if (codec is IHasCameraOff) + { + trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); + LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); + } + + if (codec is IHasCodecLayouts) + { + LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); + } + + if (codec is IHasSelfviewPosition) + { + LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); + } + + if (codec is IHasDirectory) + { + LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); + } + + if (codec is IHasScheduleAwareness) + { + LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); + } + + if (codec is IHasParticipants) + { + LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); + } + + if (codec is IHasFarEndContentStatus) + { + (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); + } + + if (codec is IHasPhoneDialing) + { + LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); + } + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + if (codec is IHasDirectory) + { + (codec as IHasDirectory).SetCurrentDirectoryToRoot(); + } + + if (codec is IHasScheduleAwareness) + { + (codec as IHasScheduleAwareness).GetSchedule(); + } + + if (codec is IHasParticipants) + { + UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); + + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCodecSelfView) + { + (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraAutoMode) + { + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraOff) + { + (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); + } + + if (codec is IHasPhoneDialing) + { + (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); + } + + SharingContentIsOnFeedback.FireUpdate(); + + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } + private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index a3ad932c..6720d4fc 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -23,46 +23,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom zCommand } - /// - /// The available layout styles - /// - public enum eZoomRoomLayoutStyle - { - Gallery, - Speaker, - Strip, - ShareAll - } - - /// - /// The avaliable layout positions for the thumbnails - /// - public enum eZoomRoomLayoutPosition - { - Center, - Up, - Right, - UpRight, - Down, - DownRight, - Left, - UpLeft, - DownLeft - } - - /// - /// The available layout sizes - /// - public enum eZoomRoomLayoutSize - { - Off, - Size1, - Size2, - Size3, - Strip - } - - public abstract class NotifiableObject : INotifyPropertyChanged { #region INotifyPropertyChanged Members @@ -606,7 +566,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public bool can_Switch_Floating_Share_Content { get; set; } /// - /// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails. + /// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors. /// [JsonProperty("can_Switch_Share_On_All_Screens")] public bool can_Switch_Share_On_All_Screens @@ -993,12 +953,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + [Flags] public enum eLayoutStyle { - Gallery, - Speaker, - Strip, - ShareAll + None = 0, + Gallery = 1, + Speaker = 2, + Strip = 4, + ShareAll = 8, } public enum eLayoutSize @@ -1023,20 +985,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom DownLeft } - public class Layout:NotifiableObject + public class Layout : NotifiableObject { - public bool ShareThumb { get; set; } - public eLayoutStyle Style { get; set; } - public eLayoutSize Size { get; set; } - + private bool _shareThumb; + private eLayoutStyle _style; + private eLayoutSize _size; private eLayoutPosition _position; - public eLayoutPosition Position { + + public bool ShareThumb + { + get { return _shareThumb; } + set + { + if (value != _shareThumb) + { + _shareThumb = value; + NotifyPropertyChanged("ShareThumb"); + } + } + } + + public eLayoutStyle Style + { + get { return _style; } + set + { + if (value != _style) + { + _style = value; + NotifyPropertyChanged("Style"); + } + } + } + + public eLayoutSize Size + { + get { return _size; } + set + { + if (value != _size) + { + _size = value; + NotifyPropertyChanged("Size"); + } + } + } + + public eLayoutPosition Position + { get { return _position; } set { - _position = value; - NotifyPropertyChanged("Position"); - } } + if (value != _position) + { + _position = value; + NotifyPropertyChanged("Position"); + } + } + } } public class Lock diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 905957f2..da8f0d67 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, - IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing + IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts { private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; @@ -121,6 +121,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc); CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc); CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc); + + LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); + + LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); + + LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); + + CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); + + ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); + } public CommunicationGather PortGather { get; private set; } @@ -216,11 +227,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } - protected Func LocalLayoutFeedbackFunc - { - get { return () => ""; } - } - protected Func LocalLayoutIsProminentFeedbackFunc { get { return () => false; } @@ -484,11 +490,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Configuration.Call.Layout.PropertyChanged += (o, a) => { - if (a.PropertyName != "Position") return; + switch (a.PropertyName) + { + case "Position": + { + ComputeSelfviewPipStatus(); - ComputeSelfviewPipStatus(); + SelfviewPipPositionFeedback.FireUpdate(); - SelfviewPipPositionFeedback.FireUpdate(); + break; + } + case "ShareThumb": + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } + case "Style": + { + LocalLayoutFeedback.FireUpdate(); + break; + } + + } }; Status.Call.Sharing.PropertyChanged += (o, a) => @@ -548,37 +571,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (a.PropertyName) { case "can_Switch_Speaker_View": - { - // TODO: #697 Fire appropriate feedback(s) - break; - } case "can_Switch_Wall_View": - { - // #697 TODO: Fire appropriate feedback(s) - break; - } case "can_Switch_Share_On_All_Screens": { - // #697 TODO: Fire appropriate feedback(s) + // #697 TODO: Calls the method to compute the available layouts and set the value of AvailableLayouts enum + ComputeAvailableLayouts(); break; } case "is_In_First_Page": { - // TODO: #697 Fire appropriate feedback(s) - // + // TODO: #697 Fires appropriate feedback + LayoutViewIsOnFirstPageFeedback.FireUpdate(); break; } case "is_In_Last_Page": { - // TODO: #697 Fire appropriate feedback(s) - break; - } - case "video_type": - { - // TODO: #697 Fire appropriate feedback(s) - // LocalLayoutFeedback.FireUpdate(); + // TODO: #697 Fires appropriate feedback + LayoutViewIsOnLastPageFeedback.FireUpdate(); break; } + //case "video_type": + // { + // // TODO: #697 It appears as though the actual value we want to watch is Configuration.Call.Layout.Style + // LocalLayoutFeedback.FireUpdate(); + // break; + // } } }; } @@ -1639,7 +1656,75 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { - LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge); + var joinMap = new ZoomRoomJoinMap(joinStart); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + LinkVideoCodecToApi(this, trilist, joinMap); + + LinkZoomRoomToApi(trilist, joinMap); + } + + /// + /// Links all the specific Zoom functionality to the API bridge + /// + /// + /// + public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap) + { + var codec = this as IHasZoomRoomLayouts; + + if (codec != null) + { + codec.AvailableLayoutsChanged += (o, a) => + { + trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, a.AvailableLayouts + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); + trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, a.AvailableLayouts + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); + trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, a.AvailableLayouts + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); + trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, a.AvailableLayouts + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); + }; + + codec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); + trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => codec.SwapContentWithThumbnail()); + codec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); + + codec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); + codec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); + trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => codec.LayoutTurnNextPage() ); + trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => codec.LayoutTurnPreviousPage()); + + + trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => + { + try + { + var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true); + SetLayout(style); + } + catch (Exception e) + { + Debug.Console(2, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); + } + }); + + codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + + + } } public override void ExecuteSwitch(object selector) @@ -1938,6 +2023,123 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion + + #region IHasZoomRoomLayouts Members + + public event EventHandler AvailableLayoutsChanged; + + private Func LayoutViewIsOnFirstPageFeedbackFunc {get {return () => Status.Layout.is_In_First_Page; } } + private Func LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } } + private Func CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } } + private Func ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } } + + public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; } + + public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; } + + public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; } + + public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; } + + + public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; } + + public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; } + + /// + /// Reads individual properties to determine if which layouts are avalailable + /// + private void ComputeAvailableLayouts() + { + zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; + //TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts + if (Status.Layout.can_Switch_Wall_View) + { + availableLayouts |= zConfiguration.eLayoutStyle.Gallery; + } + + if (Status.Layout.can_Switch_Speaker_View) + { + availableLayouts |= zConfiguration.eLayoutStyle.Speaker; + } + + if (Status.Layout.can_Switch_Share_On_All_Screens) + { + availableLayouts |= zConfiguration.eLayoutStyle.ShareAll; + } + + // There is no property that directly reports if strip mode is valid, but API stipulates + // that strip mode is available if the number of screens is 1 + if (Status.NumberOfScreens.NumOfScreens == 1) + { + availableLayouts |= zConfiguration.eLayoutStyle.Strip; + } + + var handler = AvailableLayoutsChanged; + if (handler != null) + { + handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts }); + } + + AvailableLayouts = availableLayouts; + } + + public void GetAvailableLayouts() + { + SendText("zStatus Call Layout"); + } + + public void SetLayout(zConfiguration.eLayoutStyle layoutStyle) + { + LastSelectedLayout = layoutStyle; + SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString())); + } + + public void SwapContentWithThumbnail() + { + if (CanSwapContentWithThumbnailFeedback.BoolValue) + { + var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state + // TODO: #697 Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback + // to toggle the state + SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); + } + } + + public void LayoutTurnNextPage() + { + SendText("zCommand Call Layout TurnPage Forward: On"); + } + + public void LayoutTurnPreviousPage() + { + SendText("zCommand Call Layout TurnPage Forward: Off"); + } + + #endregion + + #region IHasCodecLayouts Members + + private Func LocalLayoutFeedbackFunc { get { return () => Configuration.Call.Layout.Style.ToString(); } } + + public StringFeedback LocalLayoutFeedback { get; private set; } + + public void LocalLayoutToggle() + { + throw new NotImplementedException(); + } + + public void LocalLayoutToggleSingleProminent() + { + throw new NotImplementedException(); + } + + public void MinMaxLayoutToggle() + { + throw new NotImplementedException(); + } + + #endregion } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs new file mode 100644 index 00000000..49b22ae4 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -0,0 +1,141 @@ +using System; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges.JoinMaps; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom +{ + public class ZoomRoomJoinMap : VideoCodecControllerJoinMap + { + // TODO: #697 Set join numbers + + [JoinName("LayoutIsOnFirstPage")] + public JoinDataComplete LayoutIsOnFirstPage = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutIsOnLastPage")] + public JoinDataComplete LayoutIsOnLastPage = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutTurnToNextPage")] + public JoinDataComplete LayoutTurnToNextPage = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Turns layout view to next page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutTurnToPreviousPage")] + public JoinDataComplete LayoutTurnToPreviousPage = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Turns layout view to previous page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CanSwapContentWithThumbnail")] + public JoinDataComplete CanSwapContentWithThumbnail = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "FB Indicates if content can be swapped with thumbnail", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SwapContentWithThumbnail")] + public JoinDataComplete SwapContentWithThumbnail = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Pulse to swap content with thumbnail. FB reports current state", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("GetSetCurrentLayout")] + public JoinDataComplete GetSetCurrentLayout = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("GetAvailableLayouts")] + public JoinDataComplete GetAvailableLayouts = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("LayoutGalleryIsAvailable")] + public JoinDataComplete LayoutGalleryIsAvailable = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Gallery' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutSpeakerIsAvailable")] + public JoinDataComplete LayoutSpeakerIsAvailable = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Speaker' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutStripIsAvailable")] + public JoinDataComplete LayoutStripIsAvailable = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Strip' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutShareAllIsAvailable")] + public JoinDataComplete LayoutShareAllIsAvailable = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "FB Indicates if layout 'ShareAll' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + public ZoomRoomJoinMap(uint joinStart) + : base(joinStart, typeof(ZoomRoomJoinMap)) + { + } + + public ZoomRoomJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file From 2d7ad8ba2a08b53f6d7b4811a1c99de78f767493 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 7 May 2021 18:07:25 -0600 Subject: [PATCH 210/480] #698 Updates to add participant hand raised and pin/unpin --- .../VideoCodec/Interfaces/IHasParticipants.cs | 47 +++- .../VideoCodec/VideoCodecBase.cs | 20 +- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 30 ++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 200 ++++++++++++++++-- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 20 ++ 5 files changed, 284 insertions(+), 33 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index e0f1d1a3..f03c1984 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -1,13 +1,20 @@ using System; using System.Collections.Generic; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { + /// + /// Describes a device that has call participants + /// public interface IHasParticipants { CodecParticipants Participants { get; } } + /// + /// Describes the ability to mute and unmute a participant's video in a meeting + /// public interface IHasParticipantVideoMute:IHasParticipants { void MuteVideoForParticipant(int userId); @@ -15,13 +22,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces void ToggleVideoForParticipant(int userId); } - public interface IHasParticipantAudioMute:IHasParticipantVideoMute + /// + /// Describes the ability to mute and unmute a participant's audio in a meeting + /// + public interface IHasParticipantAudioMute : IHasParticipantVideoMute { void MuteAudioForParticipant(int userId); void UnmuteAudioForParticipant(int userId); void ToggleAudioForParticipant(int userId); } + /// + /// Describes the ability to pin and unpin a participant in a meeting + /// + public interface IHasParticipantPinUnpin : IHasParticipants + { + IntFeedback NumberOfScreensFeedback { get; } + int ScreenIndexToPinUserTo { get; } + + void PinParticipant(int userId, int screenIndex); + void UnPinParticipant(int userId); + void ToggleParticipantPinState(int userId, int screenIndex); + } + public class CodecParticipants { private List _currentParticipants; @@ -31,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces set { _currentParticipants = value; - var handler = ParticipantsListHasChanged; - - if(handler == null) return; - - handler(this, new EventArgs()); + OnParticipantsChanged(); } } @@ -45,15 +64,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { _currentParticipants = new List(); } + + public void OnParticipantsChanged() + { + var handler = ParticipantsListHasChanged; + + if (handler == null) return; + + handler(this, new EventArgs()); + } } + /// + /// Represents a call participant + /// public class Participant { + public int UserId { get; set; } public bool IsHost { get; set; } public string Name { get; set; } public bool CanMuteVideo { get; set; } public bool CanUnmuteVideo { get; set; } public bool VideoMuteFb { get; set; } public bool AudioMuteFb { get; set; } + public bool HandIsRaisedFb { get; set; } + public bool IsPinnedFb { get; set; } + public int ScreenIndexIsPinnedToFb { get; set; } } } \ No newline at end of file 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 7b2f7f42..1cdb6bc7 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 @@ -547,16 +547,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); }; + + // TODO: #698 Figure out how to decode xsig data and trigger actions based on values from SIMPL + // trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, // add method here to decode the xsig info and trigger actions } private string UpdateParticipantsXSig(List currentParticipants) { const int maxParticipants = 50; - const int maxDigitals = 5; + const int maxDigitals = 7; const int maxStrings = 1; + const int maxAnalogs = 1; const int offset = maxDigitals + maxStrings; var digitalIndex = maxStrings * maxParticipants; //15 var stringIndex = 0; + var analogIndex = 0; var meetingIndex = 0; var tokenArray = new XSigToken[maxParticipants * offset]; @@ -571,29 +576,42 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); + tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 6, participant.IsPinnedFb); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); + //analogs + tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb); + digitalIndex += maxDigitals; meetingIndex += offset; stringIndex += maxStrings; + analogIndex += maxAnalogs; } while (meetingIndex < maxParticipants * offset) { + //digitals tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); + tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + //analogs + tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0); + digitalIndex += maxDigitals; meetingIndex += offset; stringIndex += maxStrings; + analogIndex += maxAnalogs; } return GetXSigString(tokenArray); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 6720d4fc..c8bfd5bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -480,12 +480,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public string wifiName { get; set; } } - public class NumberOfScreens + public class NumberOfScreens : NotifiableObject { + private int _numOfScreens; + [JsonProperty("NumberOfCECScreens")] public int NumOfCECScreens { get; set; } [JsonProperty("NumberOfScreens")] - public int NumOfScreens { get; set; } + public int NumOfScreens + { + get + { + return _numOfScreens; + } + set + { + if (value != _numOfScreens) + { + _numOfScreens = value; + NotifyPropertyChanged("NumberOfScreens"); + } + } + } } /// @@ -803,6 +819,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public class PinStatusOfScreenNotification { + + [JsonProperty("can_be_pinned")] public bool CanBePinned { get; set; } [JsonProperty("can_pin_share")] @@ -1301,8 +1319,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { [JsonProperty("is_raise_hand")] public bool IsRaiseHand { get; set; } - [JsonProperty("optimize_vis_validideo_sharing")] - public string IsValid { get; set; } + [JsonProperty("is_valid")] + public bool IsValid { get; set; } [JsonProperty("time_stamp")] public string TimeStamp { get; set; } } @@ -1377,12 +1395,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom p => new Participant { + UserId = p.UserId, Name = p.UserName, IsHost = p.IsHost, CanMuteVideo = p.IsVideoCanMuteByHost, CanUnmuteVideo = p.IsVideoCanUnmuteByHost, AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", - VideoMuteFb = p.VideoStatusIsSending + VideoMuteFb = p.VideoStatusIsSending, + HandIsRaisedFb = p.HandStatus.IsValid && p.HandStatus.IsRaiseHand, }).ToList(); } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index da8f0d67..a0a8158c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, - IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts + IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute { private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; @@ -125,13 +125,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); - LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); - CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); - ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); + NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); + } public CommunicationGather PortGather { get; private set; } @@ -574,30 +573,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "can_Switch_Wall_View": case "can_Switch_Share_On_All_Screens": { - // #697 TODO: Calls the method to compute the available layouts and set the value of AvailableLayouts enum ComputeAvailableLayouts(); break; } case "is_In_First_Page": { - // TODO: #697 Fires appropriate feedback LayoutViewIsOnFirstPageFeedback.FireUpdate(); break; } case "is_In_Last_Page": { - // TODO: #697 Fires appropriate feedback LayoutViewIsOnLastPageFeedback.FireUpdate(); break; } //case "video_type": // { - // // TODO: #697 It appears as though the actual value we want to watch is Configuration.Call.Layout.Style + // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style // LocalLayoutFeedback.FireUpdate(); // break; // } } }; + + Status.NumberOfScreens.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "NumberOfScreens": + { + NumberOfScreensFeedback.FireUpdate(); + break; + } + } + }; } private void SetUpDirectory() @@ -1278,6 +1286,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall); break; } + case "pinstatusofscreennotification": + { + var status = responseObj.ToObject(); + + var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); + + if (participant != null) + { + participant.IsPinnedFb = true; + participant.ScreenIndexIsPinnedToFb = status.ScreenIndex; + } + else + { + participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + if (participant == null) + { + Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); + return; + } + else + { + participant.IsPinnedFb = false; + participant.ScreenIndexIsPinnedToFb = -1; + } + } + + // fire the event as we've modified the participants list + Participants.OnParticipantsChanged(); + + break; + } default: { break; @@ -1682,11 +1722,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap) { - var codec = this as IHasZoomRoomLayouts; + var layoutsCodec = this as IHasZoomRoomLayouts; - if (codec != null) + if (layoutsCodec != null) { - codec.AvailableLayoutsChanged += (o, a) => + layoutsCodec.AvailableLayoutsChanged += (o, a) => { trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, a.AvailableLayouts == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); @@ -1698,14 +1738,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); }; - codec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); - trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => codec.SwapContentWithThumbnail()); - codec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); + layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); + trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); + layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); - codec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); - codec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); - trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => codec.LayoutTurnNextPage() ); - trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => codec.LayoutTurnPreviousPage()); + layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); + layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); + trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage()); + trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage()); trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => @@ -1721,9 +1761,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }); - codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + } - + var pinCodec = this as IHasParticipantPinUnpin; + + if (pinCodec != null) + { + pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]); + + // Set the value of the local property to be used when pinning a participant + trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); } } @@ -1894,6 +1942,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #endregion + #region IHasParticipantAudioMute Members + + public void MuteAudioForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId)); + } + + public void UnmuteAudioForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId)); + } + + public void ToggleAudioForParticipant(int userId) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + + if (user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } + + if (user.AudioMuteFb) + { + UnmuteAudioForParticipant(userId); + } + else + { + MuteAudioForParticipant(userId); + } + } + + #endregion + + #region IHasParticipantVideoMute Members + + public void MuteVideoForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId)); + } + + public void UnmuteVideoForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId)); + } + + public void ToggleVideoForParticipant(int userId) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + + if (user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } + + if (user.VideoMuteFb) + { + UnmuteVideoForParticipant(userId); + } + else + { + MuteVideoForParticipant(userId); + } + } + + #endregion + + #region IHasParticipantPinUnpin Members + + private Func NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } } + + public IntFeedback NumberOfScreensFeedback { get; private set; } + + public int ScreenIndexToPinUserTo { get; private set; } + + public void PinParticipant(int userId, int screenIndex) + { + SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex)); + } + + public void UnPinParticipant(int userId) + { + SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId)); + } + + public void ToggleParticipantPinState(int userId, int screenIndex) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + + if(user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } + + if (user.IsPinnedFb) + { + UnPinParticipant(userId); + } + else + { + PinParticipant(userId, screenIndex); + } + } + + #endregion + #region Implementation of IHasCameraOff public BoolFeedback CameraIsOffFeedback { get; private set; } @@ -2052,7 +2208,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void ComputeAvailableLayouts() { zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; - //TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts + // TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts + // Will need to test and confirm that this logic evaluates correctly if (Status.Layout.can_Switch_Wall_View) { availableLayouts |= zConfiguration.eLayoutStyle.Gallery; @@ -2140,6 +2297,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion + } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 49b22ae4..f4d11f14 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -128,6 +128,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); + [JoinName("ScreenIndexToPinUserTo")] + public JoinDataComplete ScreenIndexToPinUserTo = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Specifies the screen index a participant should be pinned to", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("NumberOfScreens")] + public JoinDataComplete NumberOfScreens = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Reports the number of screens connected", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + public ZoomRoomJoinMap(uint joinStart) : base(joinStart, typeof(ZoomRoomJoinMap)) { From 604f4ca22d3fed419ef791b53950895c431c8d16 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 10 May 2021 12:58:07 -0600 Subject: [PATCH 211/480] #698 Adds join objects for participants audio/video mute and pin toggle --- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index f4d11f14..fd0e9a4a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -148,6 +148,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Analog }); + [JoinName("ParticipantAudioMuteToggleStart")] + public JoinDataComplete ParticipantAudioMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Toggles the participant's audio mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ParticipantVideoMuteToggleStart")] + public JoinDataComplete ParticipantVideoMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Toggles the participant's video mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ParticipantPinToggleStart")] + public JoinDataComplete ParticipantPinToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Toggles the participant's pin status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + public ZoomRoomJoinMap(uint joinStart) : base(joinStart, typeof(ZoomRoomJoinMap)) { From d937dc14fcbfa15326ae4dfe4e80ea2c1b8a5bca Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 10 May 2021 15:09:33 -0600 Subject: [PATCH 212/480] #698 Adds actions to toggle audio/video mute and pinning for participants --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 66 +++++++++++++++++++ .../VideoCodec/VideoCodecBase.cs | 51 +++++++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 3 +- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 29 -------- 4 files changed, 117 insertions(+), 32 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 284b8043..fde2b551 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -879,6 +879,39 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Serial }); + // TODO: #698 Set Join number + [JoinName("ParticipantAudioMuteToggleStart")] + public JoinDataComplete ParticipantAudioMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's audio mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #698 Set Join number + [JoinName("ParticipantVideoMuteToggleStart")] + public JoinDataComplete ParticipantVideoMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's video mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #698 Set Join number + [JoinName("ParticipantPinToggleStart")] + public JoinDataComplete ParticipantPinToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's pin status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof(VideoCodecControllerJoinMap)) { @@ -1773,6 +1806,39 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Serial }); + // TODO: #698 Set Join number + [JoinName("ParticipantAudioMuteToggleStart")] + public JoinDataComplete ParticipantAudioMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's audio mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #698 Set Join number + [JoinName("ParticipantVideoMuteToggleStart")] + public JoinDataComplete ParticipantVideoMuteToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's video mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #698 Set Join number + [JoinName("ParticipantPinToggleStart")] + public JoinDataComplete ParticipantPinToggleStart = + new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinMetadata + { + Description = "Toggles the participant's pin status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof(VideoCodecControllerJoinMap)) { 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 1cdb6bc7..8ea7d86b 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 @@ -28,6 +28,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced { private const int XSigEncoding = 28591; + protected const int MaxParticipants = 50; private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); protected VideoCodecBase(DeviceConfig config) : base(config) @@ -541,6 +542,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec return; } + SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants); + participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); @@ -550,11 +553,55 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec // TODO: #698 Figure out how to decode xsig data and trigger actions based on values from SIMPL // trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, // add method here to decode the xsig info and trigger actions + } + /// + /// Sets the actions for each participant in the list + /// + private void SetParticipantActions(BasicTriList trilist, VideoCodecControllerJoinMap joinMap, List currentParticipants) + { + uint index = 0; // track the index of the participant in the + + foreach (var participant in currentParticipants) + { + var p = participant; + if (index > MaxParticipants) break; + + var audioMuteCodec = this as IHasParticipantAudioMute; + if (audioMuteCodec != null) + { + trilist.SetSigFalseAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index, + () => audioMuteCodec.ToggleAudioForParticipant(p.UserId)); + + trilist.SetSigFalseAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index, + () => audioMuteCodec.ToggleVideoForParticipant(p.UserId)); + } + + var pinCodec = this as IHasParticipantPinUnpin; + if (pinCodec != null) + { + trilist.SetSigFalseAction(joinMap.ParticipantPinToggleStart.JoinNumber + index, + () => pinCodec.ToggleParticipantPinState(p.UserId, pinCodec.ScreenIndexToPinUserTo)); + } + + index++; + } + + // Clear out any previously set actions + while (index < MaxParticipants) + { + trilist.ClearBoolSigAction(joinMap.ParticipantAudioMuteToggleStart.JoinNumber + index); + trilist.ClearBoolSigAction(joinMap.ParticipantVideoMuteToggleStart.JoinNumber + index); + trilist.ClearBoolSigAction(joinMap.ParticipantPinToggleStart.JoinNumber + index); + + index++; + } + } + private string UpdateParticipantsXSig(List currentParticipants) { - const int maxParticipants = 50; + const int maxParticipants = MaxParticipants; const int maxDigitals = 7; const int maxStrings = 1; const int maxAnalogs = 1; @@ -577,7 +624,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); - tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 6, participant.IsPinnedFb); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a0a8158c..2759e259 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1761,7 +1761,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + } var pinCodec = this as IHasParticipantPinUnpin; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index fd0e9a4a..02e04caa 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -148,35 +148,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Analog }); - [JoinName("ParticipantAudioMuteToggleStart")] - public JoinDataComplete ParticipantAudioMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's audio mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("ParticipantVideoMuteToggleStart")] - public JoinDataComplete ParticipantVideoMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's video mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("ParticipantPinToggleStart")] - public JoinDataComplete ParticipantPinToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's pin status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); public ZoomRoomJoinMap(uint joinStart) : base(joinStart, typeof(ZoomRoomJoinMap)) From a06333e1c36e32b32b44f57acf0dda989caa2292 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 10 May 2021 15:38:33 -0600 Subject: [PATCH 213/480] Adds temp join numbers for participant actions --- .../Bridges/JoinMaps/VideoCodecControllerJoinMap.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index fde2b551..28abed79 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -882,7 +882,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps // TODO: #698 Set Join number [JoinName("ParticipantAudioMuteToggleStart")] public JoinDataComplete ParticipantAudioMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinDataComplete(new JoinData { JoinNumber = 2001, JoinSpan = 50 }, new JoinMetadata { Description = "Toggles the participant's audio mute status", @@ -893,7 +893,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps // TODO: #698 Set Join number [JoinName("ParticipantVideoMuteToggleStart")] public JoinDataComplete ParticipantVideoMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinDataComplete(new JoinData { JoinNumber = 2101, JoinSpan = 50 }, new JoinMetadata { Description = "Toggles the participant's video mute status", @@ -904,7 +904,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps // TODO: #698 Set Join number [JoinName("ParticipantPinToggleStart")] public JoinDataComplete ParticipantPinToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 50 }, + new JoinDataComplete(new JoinData { JoinNumber = 2201, JoinSpan = 50 }, new JoinMetadata { Description = "Toggles the participant's pin status", From 116abbf96276b5bb1f23cd30b4af34ae0dd28a38 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 11 May 2021 08:34:16 -0500 Subject: [PATCH 214/480] Updates ZoomRoomJoinMap.cs with join numbers. Updated VideoCodecControllerJoinMap.cs to organize the joins in a logical pattern. Update VideoCodecBase to add the maxAnalogs to the logic calculating xsig indexes and offsets. --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 3916 +++++++++-------- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 4 +- .../VideoCodec/VideoCodecBase.cs | 306 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 24 +- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 412 +- 5 files changed, 2573 insertions(+), 2089 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 284b8043..1b6d9483 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -2,1785 +2,2147 @@ using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Core.Bridges.JoinMaps { - public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced - { - #region Status - - [JoinName("IsOnline")] - public JoinDataComplete IsOnline = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Device is Online", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - #endregion - - [JoinName("CallDirection")] - public JoinDataComplete CallDirection = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Direction", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraLayout")] - public JoinDataComplete CameraLayout = - new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Layout Toggle", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraLayoutStringFb")] - public JoinDataComplete CameraLayoutStringFb = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Layout Fb", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraModeAuto")] - public JoinDataComplete CameraModeAuto = - new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Auto", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeManual")] - public JoinDataComplete CameraModeManual = - new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Manual", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeOff")] - public JoinDataComplete CameraModeOff = - new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraNumberSelect")] - public JoinDataComplete CameraNumberSelect = - new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Number Select/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPanLeft")] - public JoinDataComplete CameraPanLeft = - new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Left", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPanRight")] - public JoinDataComplete CameraPanRight = - new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Right", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPresetNames")] - public JoinDataComplete CameraPresetNames = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Names - XSIG, max of 15", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraPresetSelect")] - public JoinDataComplete CameraPresetSelect = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Select", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPresetSave")] - public JoinDataComplete CameraPresetSave = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Save Selected Preset", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSelfView")] - public JoinDataComplete CameraSelfView = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Self View Toggle/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsAutoMode")] - public JoinDataComplete CameraSupportsAutoMode = - new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Auto Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsOffMode")] - public JoinDataComplete CameraSupportsOffMode = - new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Off Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltDown")] - public JoinDataComplete CameraTiltDown = - new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltUp")] - public JoinDataComplete CameraTiltUp = - new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomIn")] - public JoinDataComplete CameraZoomIn = - new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom In", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomOut")] - public JoinDataComplete CameraZoomOut = - new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom Out", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CurrentCallName")] - public JoinDataComplete CurrentCallData = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentDialString")] - public JoinDataComplete CurrentDialString = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Dial String", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentParticipants")] - public JoinDataComplete CurrentParticipants = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata() - { - Description = "Current Participants XSig", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentSource")] - public JoinDataComplete CurrentSource = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Source", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DialMeeting1")] - public JoinDataComplete DialMeeting1 = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join first meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting2")] - public JoinDataComplete DialMeeting2 = - new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join second meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting3")] - public JoinDataComplete DialMeeting3 = - new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join third meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryDialSelectedLine")] - public JoinDataComplete DirectoryDialSelectedLine = - new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial selected directory line", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntries")] - public JoinDataComplete DirectoryEntries = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Entries - XSig, 255 entries", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntryIsContact")] - public JoinDataComplete DirectoryEntryIsContact = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Selected Entry Is Contact FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntrySelectedName")] - public JoinDataComplete DirectoryEntrySelectedName = - new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntrySelectedNumber")] - public JoinDataComplete DirectoryEntrySelectedNumber = - new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryFolderBack")] - public JoinDataComplete DirectoryFolderBack = - new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go back one directory level", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryHasChanged")] - public JoinDataComplete DirectoryHasChanged = - new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory has changed FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryIsRoot")] - public JoinDataComplete DirectoryIsRoot = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory is on Root FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryLineSelected")] - public JoinDataComplete DirectoryLineSelected = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Line Selected FB", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRoot")] - public JoinDataComplete DirectoryRoot = - new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go to Directory Root", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRowCount")] - public JoinDataComplete DirectoryRowCount = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Row Count FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySearchBusy")] - public JoinDataComplete DirectorySearchBusy = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search Busy FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectorySearchString")] - public JoinDataComplete DirectorySearchString = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectorySelectRow")] - public JoinDataComplete DirectorySelectRow = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Select Row", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySelectedFolderName")] - public JoinDataComplete DirectorySelectedFolderName = - new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Folder Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("0")] - public JoinDataComplete Dtmf0 = - new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 0", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("1")] - public JoinDataComplete Dtmf1 = - new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 1", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("2")] - public JoinDataComplete Dtmf2 = - new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 2", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("3")] - public JoinDataComplete Dtmf3 = - new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 3", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("4")] - public JoinDataComplete Dtmf4 = - new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 4", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("5")] - public JoinDataComplete Dtmf5 = - new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 5", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("6")] - public JoinDataComplete Dtmf6 = - new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 6", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("7")] - public JoinDataComplete Dtmf7 = - new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 7", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("8")] - public JoinDataComplete Dtmf8 = - new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 8", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("9")] - public JoinDataComplete Dtmf9 = - new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 9", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("#")] - public JoinDataComplete DtmfPound = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF #", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("*")] - public JoinDataComplete DtmfStar = - new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF *", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndCall")] - public JoinDataComplete EndCall = - new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Hang Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("HookState")] - public JoinDataComplete HookState = - new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Hook State", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingAnswer")] - public JoinDataComplete IncomingAnswer = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Answer Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCall")] - public JoinDataComplete IncomingCall = - new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCallName")] - public JoinDataComplete IncomingCallName = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingCallNumber")] - public JoinDataComplete IncomingCallNumber = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingReject")] - public JoinDataComplete IncomingReject = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Reject Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("ManualDial")] - public JoinDataComplete ManualDial = - new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial manual string", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Meeting Count Fb")] - public JoinDataComplete MeetingCount = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Meeting Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("MicMuteOff")] - public JoinDataComplete MicMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteOn")] - public JoinDataComplete MicMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteToggle")] - public JoinDataComplete MicMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MinutesBeforeMeetingStart")] - public JoinDataComplete MinutesBeforeMeetingStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Minutes before meeting start that a meeting is joinable", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("ParticipantCount")] - public JoinDataComplete ParticipantCount = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Participant Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("Schedule")] - public JoinDataComplete Schedule = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Schedule Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("AutoShareWhileInCall")] - public JoinDataComplete SourceShareAutoStart = - new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, - new JoinMetadata - { - Description = "When high, will autostart sharing when a call is joined", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareEnd")] - public JoinDataComplete SourceShareEnd = - new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Stop Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareStart")] - public JoinDataComplete SourceShareStart = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Start Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("RecievingContent")] - public JoinDataComplete RecievingContent = - new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Recieving content from the far end", - JoinType = eJoinType.Digital, - JoinCapabilities = eJoinCapabilities.ToSIMPL - }); - - [JoinName("SelfviewPosition")] - public JoinDataComplete SelfviewPosition = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SelfviewPositionFb")] - public JoinDataComplete SelfviewPositionFb = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("SpeedDialStart")] - public JoinDataComplete SpeedDialStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, - new JoinMetadata - { - Description = "Speed Dial", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("UpdateMeetings")] - public JoinDataComplete UpdateMeetings = - new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Update Meetings", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeDown")] - public JoinDataComplete VolumeDown = - new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeLevel")] - public JoinDataComplete VolumeLevel = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Level", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("VolumeMuteOff")] - public JoinDataComplete VolumeMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteOn")] - public JoinDataComplete VolumeMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteToggle")] - public JoinDataComplete VolumeMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeUp")] - public JoinDataComplete VolumeUp = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialPhoneCall")] - public JoinDataComplete DialPhone = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneHookState")] - public JoinDataComplete PhoneHookState = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndPhoneCall")] - public JoinDataComplete HangUpPhone = - new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Hang Up PHone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneString")] - public JoinDataComplete PhoneDialString = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Phone Dial String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - public VideoCodecControllerJoinMap(uint joinStart) - : base(joinStart, typeof(VideoCodecControllerJoinMap)) - { - } - - public VideoCodecControllerJoinMap(uint joinStart, Type type) - : base(joinStart, type) - { - } - } + public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced + { + #region Digital + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Device is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("1")] + public JoinDataComplete Dtmf1 = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 1", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("2")] + public JoinDataComplete Dtmf2 = new JoinDataComplete( + new JoinData + { + JoinNumber = 12, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 2", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("3")] + public JoinDataComplete Dtmf3 = new JoinDataComplete( + new JoinData + { + JoinNumber = 13, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 3", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("4")] + public JoinDataComplete Dtmf4 = new JoinDataComplete( + new JoinData + { + JoinNumber = 14, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 4", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("5")] + public JoinDataComplete Dtmf5 = new JoinDataComplete( + new JoinData + { + JoinNumber = 15, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 5", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("6")] + public JoinDataComplete Dtmf6 = new JoinDataComplete( + new JoinData + { + JoinNumber = 16, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 6", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("7")] + public JoinDataComplete Dtmf7 = new JoinDataComplete( + new JoinData + { + JoinNumber = 17, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 7", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("8")] + public JoinDataComplete Dtmf8 = new JoinDataComplete( + new JoinData + { + JoinNumber = 18, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 8", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("9")] + public JoinDataComplete Dtmf9 = new JoinDataComplete( + new JoinData + { + JoinNumber = 19, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 9", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("0")] + public JoinDataComplete Dtmf0 = new JoinDataComplete( + new JoinData + { + JoinNumber = 20, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF 0", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("*")] + public JoinDataComplete DtmfStar = new JoinDataComplete( + new JoinData + { + JoinNumber = 21, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF *", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("#")] + public JoinDataComplete DtmfPound = new JoinDataComplete( + new JoinData + { + JoinNumber = 22, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF #", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndCall")] + public JoinDataComplete EndCall = new JoinDataComplete( + new JoinData + { + JoinNumber = 24, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Hang Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("HookState")] + public JoinDataComplete HookState = new JoinDataComplete( + new JoinData + { + JoinNumber = 31, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Hook State", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 41, + JoinSpan = 4 + }, + new JoinMetadata + { + Description = "Speed Dial", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = new JoinDataComplete( + new JoinData + { + JoinNumber = 50, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Incoming Call", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = new JoinDataComplete( + new JoinData + { + JoinNumber = 51, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Answer Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = new JoinDataComplete( + new JoinData + { + JoinNumber = 52, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Reject Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ManualDial")] + public JoinDataComplete ManualDial = new JoinDataComplete( + new JoinData + { + JoinNumber = 71, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Dial manual string", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialPhoneCall")] + public JoinDataComplete DialPhone = new JoinDataComplete( + new JoinData + { + JoinNumber = 72, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneHookState")] + public JoinDataComplete PhoneHookState = new JoinDataComplete( + new JoinData + { + JoinNumber = 72, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndPhoneCall")] + public JoinDataComplete HangUpPhone = new JoinDataComplete( + new JoinData + { + JoinNumber = 73, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Hang Up PHone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = new JoinDataComplete( + new JoinData + { + JoinNumber = 100, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Search Busy FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Selected Entry Is Contact FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Line Selected FB", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = new JoinDataComplete( + new JoinData + { + JoinNumber = 102, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory is on Root FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryHasChanged")] + public JoinDataComplete DirectoryHasChanged = new JoinDataComplete( + new JoinData + { + JoinNumber = 103, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory has changed FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = new JoinDataComplete( + new JoinData + { + JoinNumber = 104, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Go to Directory Root", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = new JoinDataComplete( + new JoinData + { + JoinNumber = 105, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Go back one directory level", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = new JoinDataComplete( + new JoinData + { + JoinNumber = 106, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Dial selected directory line", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = new JoinDataComplete( + new JoinData + { + JoinNumber = 111, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Tilt Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = new JoinDataComplete( + new JoinData + { + JoinNumber = 112, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Tilt Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = new JoinDataComplete( + new JoinData + { + JoinNumber = 113, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Pan Left", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = new JoinDataComplete( + new JoinData + { + JoinNumber = 114, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Pan Right", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = new JoinDataComplete( + new JoinData + { + JoinNumber = 115, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Zoom In", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = new JoinDataComplete( + new JoinData + { + JoinNumber = 116, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Zoom Out", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPresetSave")] + public JoinDataComplete CameraPresetSave = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Save Selected Preset", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = new JoinDataComplete( + new JoinData + { + JoinNumber = 131, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Auto", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = new JoinDataComplete( + new JoinData + { + JoinNumber = 132, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Manual", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 133, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = new JoinDataComplete( + new JoinData + { + JoinNumber = 141, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Self View Toggle/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = new JoinDataComplete( + new JoinData + { + JoinNumber = 142, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Layout Toggle", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 143, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Supports Auto Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 144, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Supports Off Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("UpdateMeetings")] + public JoinDataComplete UpdateMeetings = new JoinDataComplete( + new JoinData + { + JoinNumber = 160, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Update Meetings", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting1")] + public JoinDataComplete DialMeeting1 = new JoinDataComplete( + new JoinData + { + JoinNumber = 161, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join first meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting2")] + public JoinDataComplete DialMeeting2 = new JoinDataComplete( + new JoinData + { + JoinNumber = 162, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join second meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting3")] + public JoinDataComplete DialMeeting3 = new JoinDataComplete( + new JoinData + { + JoinNumber = 163, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join third meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = new JoinDataComplete( + new JoinData + { + JoinNumber = 171, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 172, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteToggle")] + public JoinDataComplete MicMuteToggle = new JoinDataComplete( + new JoinData + { + JoinNumber = 173, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeUp")] + public JoinDataComplete VolumeUp = new JoinDataComplete( + new JoinData + { + JoinNumber = 174, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeDown")] + public JoinDataComplete VolumeDown = new JoinDataComplete( + new JoinData + { + JoinNumber = 175, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOn")] + public JoinDataComplete VolumeMuteOn = new JoinDataComplete( + new JoinData + { + JoinNumber = 176, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOff")] + public JoinDataComplete VolumeMuteOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 177, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteToggle")] + public JoinDataComplete VolumeMuteToggle = new JoinDataComplete( + new JoinData + { + JoinNumber = 178, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareStart")] + public JoinDataComplete SourceShareStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 201, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Start Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareEnd")] + public JoinDataComplete SourceShareEnd = new JoinDataComplete( + new JoinData + { + JoinNumber = 202, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Stop Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("AutoShareWhileInCall")] + public JoinDataComplete SourceShareAutoStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 203, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "When high, will autostart sharing when a call is joined", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("RecievingContent")] + public JoinDataComplete RecievingContent = new JoinDataComplete( + new JoinData + { + JoinNumber = 204, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Recieving content from the far end", + JoinType = eJoinType.Digital, + JoinCapabilities = eJoinCapabilities.ToSIMPL + }); + + [JoinName("SelfviewPosition")] + public JoinDataComplete SelfviewPosition = new JoinDataComplete( + new JoinData + { + JoinNumber = 211, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + #endregion + + + + #region Analog + + [JoinName("MinutesBeforeMeetingStart")] + public JoinDataComplete MinutesBeforeMeetingStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 41, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Minutes before meeting start that a meeting is joinable", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = new JoinDataComplete( + new JoinData + { + JoinNumber = 60, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Number Select/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Row Count FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Select Row", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPresetSelect")] + public JoinDataComplete CameraPresetSelect = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Preset Select", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ParticipantCount")] + public JoinDataComplete ParticipantCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 151, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Participant Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("Meeting Count Fb")] + public JoinDataComplete MeetingCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 161, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Meeting Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("VolumeLevel")] + public JoinDataComplete VolumeLevel = new JoinDataComplete( + new JoinData + { + JoinNumber = 174, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Level", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + #endregion + + + + #region Serials + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Dial String", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("PhoneString")] + public JoinDataComplete PhoneDialString = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Phone Dial String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallData = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Call Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = new JoinDataComplete( + new JoinData + { + JoinNumber = 22, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Call Direction", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = new JoinDataComplete( + new JoinData + { + JoinNumber = 51, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Incoming Call Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = new JoinDataComplete( + new JoinData + { + JoinNumber = 52, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Incoming Call Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = new JoinDataComplete( + new JoinData + { + JoinNumber = 100, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Search String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntries")] + public JoinDataComplete DirectoryEntries = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Entries - XSig, 255 entries", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("Schedule")] + public JoinDataComplete Schedule = new JoinDataComplete( + new JoinData + { + JoinNumber = 102, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Schedule Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraPresetNames")] + public JoinDataComplete CameraPresetNames = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Preset Names - XSIG, max of 15", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraLayoutStringFb")] + public JoinDataComplete CameraLayoutStringFb = new JoinDataComplete( + new JoinData + { + JoinNumber = 141, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Layout Fb", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentParticipants")] + public JoinDataComplete CurrentParticipants = new JoinDataComplete( + new JoinData + { + JoinNumber = 151, + JoinSpan = 1 + }, + new JoinMetadata() + { + Description = "Current Participants XSig", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentSource")] + public JoinDataComplete CurrentSource = new JoinDataComplete( + new JoinData + { + JoinNumber = 201, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Source", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("SelfviewPositionFb")] + public JoinDataComplete SelfviewPositionFb = new JoinDataComplete( + new JoinData + { + JoinNumber = 211, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete( + new JoinData + { + JoinNumber = 356, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Entry Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = new JoinDataComplete( + new JoinData + { + JoinNumber = 357, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Entry Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = new JoinDataComplete( + new JoinData + { + JoinNumber = 358, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Folder Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + #endregion + + public VideoCodecControllerJoinMap(uint joinStart) + : base(joinStart, typeof(VideoCodecControllerJoinMap)) + { + } + + public VideoCodecControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } } namespace PepperDash_Essentials_Core.Bridges.JoinMaps { - [Obsolete("Use PepperDash.Essentials.Core.Bridges.JoinMaps")] - public class VideoCodecControllerJoinMap :JoinMapBaseAdvanced - { - - #region Status - - [JoinName("IsOnline")] - public JoinDataComplete IsOnline = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Device is Online", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - #endregion - - [JoinName("CallDirection")] - public JoinDataComplete CallDirection = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Direction", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraLayout")] - public JoinDataComplete CameraLayout = - new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Layout Toggle", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraLayoutStringFb")] - public JoinDataComplete CameraLayoutStringFb = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Layout Fb", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraModeAuto")] - public JoinDataComplete CameraModeAuto = - new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Auto", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeManual")] - public JoinDataComplete CameraModeManual = - new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Manual", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeOff")] - public JoinDataComplete CameraModeOff = - new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraNumberSelect")] - public JoinDataComplete CameraNumberSelect = - new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Number Select/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPanLeft")] - public JoinDataComplete CameraPanLeft = - new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Left", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPanRight")] - public JoinDataComplete CameraPanRight = - new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Right", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPresetNames")] - public JoinDataComplete CameraPresetNames = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Names - XSIG, max of 15", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraPresetSelect")] - public JoinDataComplete CameraPresetSelect = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Select", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPresetSave")] - public JoinDataComplete CameraPresetSave = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Save Selected Preset", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSelfView")] - public JoinDataComplete CameraSelfView = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Self View Toggle/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsAutoMode")] - public JoinDataComplete CameraSupportsAutoMode = - new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Auto Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsOffMode")] - public JoinDataComplete CameraSupportsOffMode = - new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Off Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltDown")] - public JoinDataComplete CameraTiltDown = - new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltUp")] - public JoinDataComplete CameraTiltUp = - new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomIn")] - public JoinDataComplete CameraZoomIn = - new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom In", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomOut")] - public JoinDataComplete CameraZoomOut = - new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom Out", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CurrentCallName")] - public JoinDataComplete CurrentCallData = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentDialString")] - public JoinDataComplete CurrentDialString = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Dial String", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentParticipants")] - public JoinDataComplete CurrentParticipants = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata() - { - Description = "Current Participants XSig", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentSource")] - public JoinDataComplete CurrentSource = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Source", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DialMeeting1")] - public JoinDataComplete DialMeeting1 = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join first meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting2")] - public JoinDataComplete DialMeeting2 = - new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join second meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting3")] - public JoinDataComplete DialMeeting3 = - new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join third meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryDialSelectedLine")] - public JoinDataComplete DirectoryDialSelectedLine = - new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial selected directory line", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntries")] - public JoinDataComplete DirectoryEntries = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Entries - XSig, 255 entries", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntryIsContact")] - public JoinDataComplete DirectoryEntryIsContact = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Selected Entry Is Contact FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntrySelectedName")] - public JoinDataComplete DirectoryEntrySelectedName = - new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntrySelectedNumber")] - public JoinDataComplete DirectoryEntrySelectedNumber = - new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryFolderBack")] - public JoinDataComplete DirectoryFolderBack = - new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go back one directory level", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryHasChanged")] - public JoinDataComplete DirectoryHasChanged = - new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory has changed FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryIsRoot")] - public JoinDataComplete DirectoryIsRoot = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory is on Root FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryLineSelected")] - public JoinDataComplete DirectoryLineSelected = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Line Selected FB", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRoot")] - public JoinDataComplete DirectoryRoot = - new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go to Directory Root", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRowCount")] - public JoinDataComplete DirectoryRowCount = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Row Count FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySearchBusy")] - public JoinDataComplete DirectorySearchBusy = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search Busy FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectorySearchString")] - public JoinDataComplete DirectorySearchString = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectorySelectRow")] - public JoinDataComplete DirectorySelectRow = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Select Row", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySelectedFolderName")] - public JoinDataComplete DirectorySelectedFolderName = - new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Folder Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("0")] - public JoinDataComplete Dtmf0 = - new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 0", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("1")] - public JoinDataComplete Dtmf1 = - new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 1", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("2")] - public JoinDataComplete Dtmf2 = - new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 2", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("3")] - public JoinDataComplete Dtmf3 = - new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 3", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("4")] - public JoinDataComplete Dtmf4 = - new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 4", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("5")] - public JoinDataComplete Dtmf5 = - new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 5", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("6")] - public JoinDataComplete Dtmf6 = - new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 6", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("7")] - public JoinDataComplete Dtmf7 = - new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 7", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("8")] - public JoinDataComplete Dtmf8 = - new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 8", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("9")] - public JoinDataComplete Dtmf9 = - new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 9", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("#")] - public JoinDataComplete DtmfPound = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF #", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("*")] - public JoinDataComplete DtmfStar = - new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF *", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndCall")] - public JoinDataComplete EndCall = - new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Hang Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("HookState")] - public JoinDataComplete HookState = - new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Hook State", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingAnswer")] - public JoinDataComplete IncomingAnswer = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Answer Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCall")] - public JoinDataComplete IncomingCall = - new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCallName")] - public JoinDataComplete IncomingCallName = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingCallNumber")] - public JoinDataComplete IncomingCallNumber = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingReject")] - public JoinDataComplete IncomingReject = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Reject Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("ManualDial")] - public JoinDataComplete ManualDial = - new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial manual string", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Meeting Count Fb")] - public JoinDataComplete MeetingCount = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Meeting Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("MicMuteOff")] - public JoinDataComplete MicMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteOn")] - public JoinDataComplete MicMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteToggle")] - public JoinDataComplete MicMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MinutesBeforeMeetingStart")] - public JoinDataComplete MinutesBeforeMeetingStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Minutes before meeting start that a meeting is joinable", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("ParticipantCount")] - public JoinDataComplete ParticipantCount = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Participant Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("Schedule")] - public JoinDataComplete Schedule = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Schedule Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("AutoShareWhileInCall")] - public JoinDataComplete SourceShareAutoStart = - new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, - new JoinMetadata - { - Description = "When high, will autostart sharing when a call is joined", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareEnd")] - public JoinDataComplete SourceShareEnd = - new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Stop Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareStart")] - public JoinDataComplete SourceShareStart = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Start Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("RecievingContent")] - public JoinDataComplete RecievingContent = - new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Recieving content from the far end", - JoinType = eJoinType.Digital, - JoinCapabilities = eJoinCapabilities.ToSIMPL - }); - - [JoinName("SelfviewPosition")] - public JoinDataComplete SelfviewPosition = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SelfviewPositionFb")] - public JoinDataComplete SelfviewPositionFb = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("SpeedDialStart")] - public JoinDataComplete SpeedDialStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, - new JoinMetadata - { - Description = "Speed Dial", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("UpdateMeetings")] - public JoinDataComplete UpdateMeetings = - new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Update Meetings", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeDown")] - public JoinDataComplete VolumeDown = - new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeLevel")] - public JoinDataComplete VolumeLevel = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Level", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("VolumeMuteOff")] - public JoinDataComplete VolumeMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteOn")] - public JoinDataComplete VolumeMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteToggle")] - public JoinDataComplete VolumeMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeUp")] - public JoinDataComplete VolumeUp = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialPhoneCall")] - public JoinDataComplete DialPhone = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneHookState")] - public JoinDataComplete PhoneHookState = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial Phone", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("EndPhoneCall")] - public JoinDataComplete HangUpPhone = - new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Hang Up PHone", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("PhoneString")] - public JoinDataComplete PhoneDialString = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Phone Dial String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - public VideoCodecControllerJoinMap(uint joinStart) - : base(joinStart, typeof(VideoCodecControllerJoinMap)) - { - } - - public VideoCodecControllerJoinMap(uint joinStart, Type type) - : base(joinStart, type) - { - } - } - } + [Obsolete("Use PepperDash.Essentials.Core.Bridges.JoinMaps")] + public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced + { + + #region Status + + [JoinName("IsOnline")] + public JoinDataComplete IsOnline = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Device is Online", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Direction", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = + new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Layout Toggle", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraLayoutStringFb")] + public JoinDataComplete CameraLayoutStringFb = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Layout Fb", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = + new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Auto", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = + new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Manual", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = + new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Mode Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = + new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Number Select/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = + new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Left", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = + new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Pan Right", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPresetNames")] + public JoinDataComplete CameraPresetNames = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Names - XSIG, max of 15", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraPresetSelect")] + public JoinDataComplete CameraPresetSelect = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Preset Select", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPresetSave")] + public JoinDataComplete CameraPresetSave = + new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Save Selected Preset", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = + new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Self View Toggle/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = + new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Auto Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = + new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Supports Off Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = + new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = + new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Tilt Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = + new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom In", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = + new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Camera Zoom Out", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallData = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Call Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = + new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Dial String", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentParticipants")] + public JoinDataComplete CurrentParticipants = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata() + { + Description = "Current Participants XSig", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentSource")] + public JoinDataComplete CurrentSource = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Source", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DialMeeting1")] + public JoinDataComplete DialMeeting1 = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join first meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting2")] + public JoinDataComplete DialMeeting2 = + new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join second meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting3")] + public JoinDataComplete DialMeeting3 = + new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Join third meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = + new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial selected directory line", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntries")] + public JoinDataComplete DirectoryEntries = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Entries - XSig, 255 entries", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Selected Entry Is Contact FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = + new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = + new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Entry Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = + new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go back one directory level", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryHasChanged")] + public JoinDataComplete DirectoryHasChanged = + new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory has changed FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory is on Root FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Line Selected FB", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = + new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Go to Directory Root", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Row Count FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search Busy FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = + new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Search String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = + new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Directory Select Row", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = + new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Selected Directory Folder Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("0")] + public JoinDataComplete Dtmf0 = + new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 0", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("1")] + public JoinDataComplete Dtmf1 = + new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 1", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("2")] + public JoinDataComplete Dtmf2 = + new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 2", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("3")] + public JoinDataComplete Dtmf3 = + new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 3", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("4")] + public JoinDataComplete Dtmf4 = + new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 4", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("5")] + public JoinDataComplete Dtmf5 = + new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 5", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("6")] + public JoinDataComplete Dtmf6 = + new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 6", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("7")] + public JoinDataComplete Dtmf7 = + new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 7", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("8")] + public JoinDataComplete Dtmf8 = + new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 8", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("9")] + public JoinDataComplete Dtmf9 = + new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF 9", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("#")] + public JoinDataComplete DtmfPound = + new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF #", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("*")] + public JoinDataComplete DtmfStar = + new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, + new JoinMetadata + { + Description = "DTMF *", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndCall")] + public JoinDataComplete EndCall = + new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("HookState")] + public JoinDataComplete HookState = + new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Hook State", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Answer Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = + new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = + new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Incoming Call Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = + new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Reject Incoming Call", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("ManualDial")] + public JoinDataComplete ManualDial = + new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial manual string", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("Meeting Count Fb")] + public JoinDataComplete MeetingCount = + new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Meeting Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteToggle")] + public JoinDataComplete MicMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Mic Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MinutesBeforeMeetingStart")] + public JoinDataComplete MinutesBeforeMeetingStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Minutes before meeting start that a meeting is joinable", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ParticipantCount")] + public JoinDataComplete ParticipantCount = + new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Current Participant Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("Schedule")] + public JoinDataComplete Schedule = + new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Schedule Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("AutoShareWhileInCall")] + public JoinDataComplete SourceShareAutoStart = + new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, + new JoinMetadata + { + Description = "When high, will autostart sharing when a call is joined", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareEnd")] + public JoinDataComplete SourceShareEnd = + new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Stop Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareStart")] + public JoinDataComplete SourceShareStart = + new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Start Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("RecievingContent")] + public JoinDataComplete RecievingContent = + new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Recieving content from the far end", + JoinType = eJoinType.Digital, + JoinCapabilities = eJoinCapabilities.ToSIMPL + }); + + [JoinName("SelfviewPosition")] + public JoinDataComplete SelfviewPosition = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SelfviewPositionFb")] + public JoinDataComplete SelfviewPositionFb = + new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("SpeedDialStart")] + public JoinDataComplete SpeedDialStart = + new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, + new JoinMetadata + { + Description = "Speed Dial", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("UpdateMeetings")] + public JoinDataComplete UpdateMeetings = + new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Update Meetings", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeDown")] + public JoinDataComplete VolumeDown = + new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeLevel")] + public JoinDataComplete VolumeLevel = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Level", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("VolumeMuteOff")] + public JoinDataComplete VolumeMuteOff = + new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOn")] + public JoinDataComplete VolumeMuteOn = + new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteToggle")] + public JoinDataComplete VolumeMuteToggle = + new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeUp")] + public JoinDataComplete VolumeUp = + new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Volume Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialPhoneCall")] + public JoinDataComplete DialPhone = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneHookState")] + public JoinDataComplete PhoneHookState = + new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Dial Phone", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("EndPhoneCall")] + public JoinDataComplete HangUpPhone = + new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Hang Up PHone", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("PhoneString")] + public JoinDataComplete PhoneDialString = + new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata + { + Description = "Phone Dial String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + public VideoCodecControllerJoinMap(uint joinStart) + : base(joinStart, typeof(VideoCodecControllerJoinMap)) + { + } + + public VideoCodecControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 8ba3d139..00787a69 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -27,8 +27,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { event EventHandler AvailableLayoutsChanged; - BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func - BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func + BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func + BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } 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 1cdb6bc7..a693bb12 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 @@ -271,14 +271,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); - /// - /// Use this method when using a plain VideoCodecControllerJoinMap - /// - /// - /// - /// - /// - /// + /// + /// Use this method when using a plain VideoCodecControllerJoinMap + /// + /// + /// + /// + /// + /// protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { @@ -296,144 +296,144 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec bridge.AddJoinMap(Key, joinMap); } - LinkVideoCodecToApi(codec, trilist, joinMap); + LinkVideoCodecToApi(codec, trilist, joinMap); } - /// - /// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap - /// - /// - /// - /// - protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); + /// + /// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap + /// + /// + /// + /// + protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); - LinkVideoCodecDtmfToApi(trilist, joinMap); + LinkVideoCodecDtmfToApi(trilist, joinMap); - LinkVideoCodecCallControlsToApi(trilist, joinMap); + LinkVideoCodecCallControlsToApi(trilist, joinMap); - LinkVideoCodecContentSharingToApi(trilist, joinMap); + LinkVideoCodecContentSharingToApi(trilist, joinMap); - LinkVideoCodecPrivacyToApi(trilist, joinMap); + LinkVideoCodecPrivacyToApi(trilist, joinMap); - LinkVideoCodecVolumeToApi(trilist, joinMap); + LinkVideoCodecVolumeToApi(trilist, joinMap); - if (codec is ICommunicationMonitor) - { - LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); - } + if (codec is ICommunicationMonitor) + { + LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); + } - if (codec is IHasCodecCameras) - { - LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); - } + if (codec is IHasCodecCameras) + { + LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); + } - if (codec is IHasCodecSelfView) - { - LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); - } + if (codec is IHasCodecSelfView) + { + LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); + } - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); - LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); - } + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); + LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); + } - if (codec is IHasCameraOff) - { - trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); - LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); - } + if (codec is IHasCameraOff) + { + trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); + LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); + } - if (codec is IHasCodecLayouts) - { - LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); - } + if (codec is IHasCodecLayouts) + { + LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); + } - if (codec is IHasSelfviewPosition) - { - LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); - } + if (codec is IHasSelfviewPosition) + { + LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); + } - if (codec is IHasDirectory) - { - LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); - } + if (codec is IHasDirectory) + { + LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); + } - if (codec is IHasScheduleAwareness) - { - LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); - } + if (codec is IHasScheduleAwareness) + { + LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); + } - if (codec is IHasParticipants) - { - LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); - } + if (codec is IHasParticipants) + { + LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); + } - if (codec is IHasFarEndContentStatus) - { - (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); - } + if (codec is IHasFarEndContentStatus) + { + (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); + } - if (codec is IHasPhoneDialing) - { - LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); - } + if (codec is IHasPhoneDialing) + { + LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); + } - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; - if (codec is IHasDirectory) - { - (codec as IHasDirectory).SetCurrentDirectoryToRoot(); - } + if (codec is IHasDirectory) + { + (codec as IHasDirectory).SetCurrentDirectoryToRoot(); + } - if (codec is IHasScheduleAwareness) - { - (codec as IHasScheduleAwareness).GetSchedule(); - } + if (codec is IHasScheduleAwareness) + { + (codec as IHasScheduleAwareness).GetSchedule(); + } - if (codec is IHasParticipants) - { - UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); - } + if (codec is IHasParticipants) + { + UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); + } - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } - if (codec is IHasCodecSelfView) - { - (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); - } + if (codec is IHasCodecSelfView) + { + (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); + } - if (codec is IHasCameraAutoMode) - { - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } + if (codec is IHasCameraAutoMode) + { + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } - if (codec is IHasCameraOff) - { - (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); - } + if (codec is IHasCameraOff) + { + (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); + } - if (codec is IHasPhoneDialing) - { - (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); - } + if (codec is IHasPhoneDialing) + { + (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); + } - SharingContentIsOnFeedback.FireUpdate(); + SharingContentIsOnFeedback.FireUpdate(); - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; - } + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -548,8 +548,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); }; - // TODO: #698 Figure out how to decode xsig data and trigger actions based on values from SIMPL - // trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, // add method here to decode the xsig info and trigger actions + // TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL + // add method here to decode the xsig info and trigger actions + //trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, DecodeParticipantsXSig); } private string UpdateParticipantsXSig(List currentParticipants) @@ -557,11 +558,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec const int maxParticipants = 50; const int maxDigitals = 7; const int maxStrings = 1; - const int maxAnalogs = 1; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings * maxParticipants; //15 + const int maxAnalogs = 1; + const int offset = maxDigitals + maxStrings + maxAnalogs; + var digitalIndex = maxStrings + maxAnalogs * maxParticipants; //15 var stringIndex = 0; - var analogIndex = 0; + var analogIndex = 0; var meetingIndex = 0; var tokenArray = new XSigToken[maxParticipants * offset]; @@ -576,47 +577,88 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); - tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); - tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 6, participant.IsPinnedFb); + tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); - //analogs - tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb); + //analogs + tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb); digitalIndex += maxDigitals; meetingIndex += offset; stringIndex += maxStrings; - analogIndex += maxAnalogs; + analogIndex += maxAnalogs; } while (meetingIndex < maxParticipants * offset) { - //digitals + //digitals tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); - tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false); - tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false); + tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false); + tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false); //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - //analogs - tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0); + //analogs + tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0); digitalIndex += maxDigitals; meetingIndex += offset; stringIndex += maxStrings; - analogIndex += maxAnalogs; + analogIndex += maxAnalogs; } return GetXSigString(tokenArray); } + // TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL + private void DecodeParticipantsXSig(string xsigData) + { + if (string.IsNullOrEmpty(xsigData)) return; + var bytes = Encoding.GetEncoding(XSigEncoding).GetBytes(xsigData); + using (var xsigStream = new XSigTokenStreamReader(new MemoryStream(bytes))) + { + XSigToken token = null; + while ((token = xsigStream.ReadXSigToken()) != null) + { + switch (token.TokenType) + { + case XSigTokenType.Digital: + { + var data = token as XSigDigitalToken; + if (data == null) return; + Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", + data.TokenType, data.Index, data.Value.ToString()); + break; + } + case XSigTokenType.Analog: + { + var data = token as XSigAnalogToken; + if (data == null) return; + Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", + data.TokenType, data.Index, data.Value); + break; + } + case XSigTokenType.Serial: + { + var data = token as XSigSerialToken; + if (data == null) return; + Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", data.TokenType, data.Index, + data.Value); + break; + } + } + } + } + } + private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); @@ -882,7 +924,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); - trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); + trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); if (args.CallItem.Direction == eCodecCallDirection.Incoming) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a0a8158c..10f5929d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1723,7 +1723,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap) { var layoutsCodec = this as IHasZoomRoomLayouts; - if (layoutsCodec != null) { layoutsCodec.AvailableLayoutsChanged += (o, a) => @@ -1746,7 +1745,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage()); trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage()); - + trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts()); trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => { @@ -1757,22 +1756,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } catch (Exception e) { - Debug.Console(2, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); } }); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); } var pinCodec = this as IHasParticipantPinUnpin; + if (pinCodec != null) + { + pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]); - if (pinCodec != null) - { - pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]); - - // Set the value of the local property to be used when pinning a participant - trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); - } + // Set the value of the local property to be used when pinning a participant + trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); + } } public override void ExecuteSwitch(object selector) @@ -2208,7 +2206,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void ComputeAvailableLayouts() { zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; - // TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts + // TODO: #697 [ ] Compute the avaialble layouts and set the value of AvailableLayouts // Will need to test and confirm that this logic evaluates correctly if (Status.Layout.can_Switch_Wall_View) { @@ -2257,7 +2255,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (CanSwapContentWithThumbnailFeedback.BoolValue) { var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state - // TODO: #697 Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback + // TODO: #697 [ ] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback // to toggle the state SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index fd0e9a4a..7ceb1ba3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -4,188 +4,270 @@ using PepperDash.Essentials.Core.Bridges.JoinMaps; namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { - public class ZoomRoomJoinMap : VideoCodecControllerJoinMap - { - // TODO: #697 Set join numbers + public class ZoomRoomJoinMap : VideoCodecControllerJoinMap + { + // TODO: #697 [X] Set join numbers - [JoinName("LayoutIsOnFirstPage")] - public JoinDataComplete LayoutIsOnFirstPage = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Indicates if layout is on first page", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + #region Digital - [JoinName("LayoutIsOnLastPage")] - public JoinDataComplete LayoutIsOnLastPage = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Indicates if layout is on first page", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("CanSwapContentWithThumbnail")] + public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete( + new JoinData + { + JoinNumber = 206, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if content can be swapped with thumbnail", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutTurnToNextPage")] - public JoinDataComplete LayoutTurnToNextPage = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Turns layout view to next page", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("SwapContentWithThumbnail")] + public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete( + new JoinData + { + JoinNumber = 206, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Pulse to swap content with thumbnail. FB reports current state", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutTurnToPreviousPage")] - public JoinDataComplete LayoutTurnToPreviousPage = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Turns layout view to previous page", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("GetAvailableLayouts")] + public JoinDataComplete GetAvailableLayouts = new JoinDataComplete( + new JoinData + { + JoinNumber = 215, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("CanSwapContentWithThumbnail")] - public JoinDataComplete CanSwapContentWithThumbnail = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "FB Indicates if content can be swapped with thumbnail", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutIsOnFirstPage")] + public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 216, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("SwapContentWithThumbnail")] - public JoinDataComplete SwapContentWithThumbnail = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Pulse to swap content with thumbnail. FB reports current state", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutIsOnLastPage")] + public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 217, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("GetSetCurrentLayout")] - public JoinDataComplete GetSetCurrentLayout = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); + [JoinName("LayoutTurnToNextPage")] + public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 216, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Turns layout view to next page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("GetAvailableLayouts")] - public JoinDataComplete GetAvailableLayouts = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); + [JoinName("LayoutTurnToPreviousPage")] + public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 217, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Turns layout view to previous page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutGalleryIsAvailable")] - public JoinDataComplete LayoutGalleryIsAvailable = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Gallery' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutGalleryIsAvailable")] + public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 221, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Gallery' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutSpeakerIsAvailable")] - public JoinDataComplete LayoutSpeakerIsAvailable = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Speaker' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutSpeakerIsAvailable")] + public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 222, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Speaker' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutStripIsAvailable")] - public JoinDataComplete LayoutStripIsAvailable = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Strip' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutStripIsAvailable")] + public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 223, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Strip' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("LayoutShareAllIsAvailable")] - public JoinDataComplete LayoutShareAllIsAvailable = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "FB Indicates if layout 'ShareAll' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("LayoutShareAllIsAvailable")] + public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 224, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'ShareAll' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("ScreenIndexToPinUserTo")] - public JoinDataComplete ScreenIndexToPinUserTo = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Specifies the screen index a participant should be pinned to", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); + [JoinName("ParticipantAudioMuteToggleStart")] + public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 500, + JoinSpan = 100 + }, + new JoinMetadata + { + Description = "Toggles the participant's audio mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("NumberOfScreens")] - public JoinDataComplete NumberOfScreens = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Reports the number of screens connected", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); + [JoinName("ParticipantVideoMuteToggleStart")] + public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 800, + JoinSpan = 100 + }, + new JoinMetadata + { + Description = "Toggles the participant's video mute status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("ParticipantAudioMuteToggleStart")] - public JoinDataComplete ParticipantAudioMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's audio mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + [JoinName("ParticipantPinToggleStart")] + public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 1100, + JoinSpan = 100 + }, + new JoinMetadata + { + Description = "Toggles the participant's pin status", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); - [JoinName("ParticipantVideoMuteToggleStart")] - public JoinDataComplete ParticipantVideoMuteToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's video mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + #endregion - [JoinName("ParticipantPinToggleStart")] - public JoinDataComplete ParticipantPinToggleStart = - new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Toggles the participant's pin status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - public ZoomRoomJoinMap(uint joinStart) - : base(joinStart, typeof(ZoomRoomJoinMap)) - { - } + #region Analog - public ZoomRoomJoinMap(uint joinStart, Type type) - : base(joinStart, type) - { - } - } + [JoinName("NumberOfScreens")] + public JoinDataComplete NumberOfScreens = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Reports the number of screens connected", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ScreenIndexToPinUserTo")] + public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Specifies the screen index a participant should be pinned to", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + #endregion + + + #region Serials + + [JoinName("GetSetCurrentLayout")] + public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete( + new JoinData + { + JoinNumber = 215, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + #endregion + + public ZoomRoomJoinMap(uint joinStart) + : base(joinStart, typeof(ZoomRoomJoinMap)) + { + } + + public ZoomRoomJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } } \ No newline at end of file From 118bd5a54a5c27562938b21e4a267d4a984258b6 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 11 May 2021 11:19:33 -0500 Subject: [PATCH 215/480] Updates VideoCodecControllerJoinMap.cs to organize joins. Update to VideoCodecBase.cs UpdateParticipantsXSig. --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 1776 ++++++++++------- .../VideoCodec/VideoCodecBase.cs | 6 +- 2 files changed, 1073 insertions(+), 709 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 1b6d9483..53ed852a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -1241,6 +1241,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps #endregion + public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof(VideoCodecControllerJoinMap)) { @@ -1260,11 +1261,15 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps public class VideoCodecControllerJoinMap : JoinMapBaseAdvanced { - #region Status + #region Digital [JoinName("IsOnline")] - public JoinDataComplete IsOnline = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + public JoinDataComplete IsOnline = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, new JoinMetadata { Description = "Device is Online", @@ -1272,431 +1277,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - #endregion - - [JoinName("CallDirection")] - public JoinDataComplete CallDirection = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Direction", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraLayout")] - public JoinDataComplete CameraLayout = - new JoinDataComplete(new JoinData { JoinNumber = 142, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Layout Toggle", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraLayoutStringFb")] - public JoinDataComplete CameraLayoutStringFb = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Layout Fb", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraModeAuto")] - public JoinDataComplete CameraModeAuto = - new JoinDataComplete(new JoinData { JoinNumber = 131, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Auto", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeManual")] - public JoinDataComplete CameraModeManual = - new JoinDataComplete(new JoinData { JoinNumber = 132, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Manual", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraModeOff")] - public JoinDataComplete CameraModeOff = - new JoinDataComplete(new JoinData { JoinNumber = 133, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Mode Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraNumberSelect")] - public JoinDataComplete CameraNumberSelect = - new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Number Select/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPanLeft")] - public JoinDataComplete CameraPanLeft = - new JoinDataComplete(new JoinData { JoinNumber = 113, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Left", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPanRight")] - public JoinDataComplete CameraPanRight = - new JoinDataComplete(new JoinData { JoinNumber = 114, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Pan Right", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraPresetNames")] - public JoinDataComplete CameraPresetNames = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Names - XSIG, max of 15", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CameraPresetSelect")] - public JoinDataComplete CameraPresetSelect = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Preset Select", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("CameraPresetSave")] - public JoinDataComplete CameraPresetSave = - new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Save Selected Preset", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSelfView")] - public JoinDataComplete CameraSelfView = - new JoinDataComplete(new JoinData { JoinNumber = 141, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Self View Toggle/FB", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsAutoMode")] - public JoinDataComplete CameraSupportsAutoMode = - new JoinDataComplete(new JoinData { JoinNumber = 143, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Auto Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraSupportsOffMode")] - public JoinDataComplete CameraSupportsOffMode = - new JoinDataComplete(new JoinData { JoinNumber = 144, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Supports Off Mode FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltDown")] - public JoinDataComplete CameraTiltDown = - new JoinDataComplete(new JoinData { JoinNumber = 112, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Down", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraTiltUp")] - public JoinDataComplete CameraTiltUp = - new JoinDataComplete(new JoinData { JoinNumber = 111, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Tilt Up", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomIn")] - public JoinDataComplete CameraZoomIn = - new JoinDataComplete(new JoinData { JoinNumber = 115, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom In", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CameraZoomOut")] - public JoinDataComplete CameraZoomOut = - new JoinDataComplete(new JoinData { JoinNumber = 116, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Camera Zoom Out", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("CurrentCallName")] - public JoinDataComplete CurrentCallData = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Call Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentDialString")] - public JoinDataComplete CurrentDialString = - new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Dial String", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentParticipants")] - public JoinDataComplete CurrentParticipants = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata() - { - Description = "Current Participants XSig", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("CurrentSource")] - public JoinDataComplete CurrentSource = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Source", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DialMeeting1")] - public JoinDataComplete DialMeeting1 = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join first meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting2")] - public JoinDataComplete DialMeeting2 = - new JoinDataComplete(new JoinData { JoinNumber = 162, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join second meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DialMeeting3")] - public JoinDataComplete DialMeeting3 = - new JoinDataComplete(new JoinData { JoinNumber = 163, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Join third meeting", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryDialSelectedLine")] - public JoinDataComplete DirectoryDialSelectedLine = - new JoinDataComplete(new JoinData { JoinNumber = 106, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial selected directory line", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntries")] - public JoinDataComplete DirectoryEntries = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Entries - XSig, 255 entries", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntryIsContact")] - public JoinDataComplete DirectoryEntryIsContact = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Selected Entry Is Contact FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryEntrySelectedName")] - public JoinDataComplete DirectoryEntrySelectedName = - new JoinDataComplete(new JoinData { JoinNumber = 356, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryEntrySelectedNumber")] - public JoinDataComplete DirectoryEntrySelectedNumber = - new JoinDataComplete(new JoinData { JoinNumber = 357, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Entry Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectoryFolderBack")] - public JoinDataComplete DirectoryFolderBack = - new JoinDataComplete(new JoinData { JoinNumber = 105, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go back one directory level", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryHasChanged")] - public JoinDataComplete DirectoryHasChanged = - new JoinDataComplete(new JoinData { JoinNumber = 103, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory has changed FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryIsRoot")] - public JoinDataComplete DirectoryIsRoot = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory is on Root FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryLineSelected")] - public JoinDataComplete DirectoryLineSelected = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Line Selected FB", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRoot")] - public JoinDataComplete DirectoryRoot = - new JoinDataComplete(new JoinData { JoinNumber = 104, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Go to Directory Root", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectoryRowCount")] - public JoinDataComplete DirectoryRowCount = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Row Count FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySearchBusy")] - public JoinDataComplete DirectorySearchBusy = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search Busy FB", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("DirectorySearchString")] - public JoinDataComplete DirectorySearchString = - new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Search String", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("DirectorySelectRow")] - public JoinDataComplete DirectorySelectRow = - new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Directory Select Row", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("DirectorySelectedFolderName")] - public JoinDataComplete DirectorySelectedFolderName = - new JoinDataComplete(new JoinData { JoinNumber = 358, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Selected Directory Folder Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("0")] - public JoinDataComplete Dtmf0 = - new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 }, - new JoinMetadata - { - Description = "DTMF 0", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - [JoinName("1")] - public JoinDataComplete Dtmf1 = - new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, + public JoinDataComplete Dtmf1 = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 1", @@ -1705,8 +1292,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("2")] - public JoinDataComplete Dtmf2 = - new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + public JoinDataComplete Dtmf2 = new JoinDataComplete( + new JoinData + { + JoinNumber = 12, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 2", @@ -1715,8 +1306,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("3")] - public JoinDataComplete Dtmf3 = - new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + public JoinDataComplete Dtmf3 = new JoinDataComplete( + new JoinData + { + JoinNumber = 13, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 3", @@ -1725,8 +1320,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("4")] - public JoinDataComplete Dtmf4 = - new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + public JoinDataComplete Dtmf4 = new JoinDataComplete( + new JoinData + { + JoinNumber = 14, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 4", @@ -1735,8 +1334,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("5")] - public JoinDataComplete Dtmf5 = - new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + public JoinDataComplete Dtmf5 = new JoinDataComplete( + new JoinData + { + JoinNumber = 15, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 5", @@ -1745,8 +1348,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("6")] - public JoinDataComplete Dtmf6 = - new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 }, + public JoinDataComplete Dtmf6 = new JoinDataComplete( + new JoinData + { + JoinNumber = 16, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 6", @@ -1755,8 +1362,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("7")] - public JoinDataComplete Dtmf7 = - new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 }, + public JoinDataComplete Dtmf7 = new JoinDataComplete( + new JoinData + { + JoinNumber = 17, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 7", @@ -1765,8 +1376,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("8")] - public JoinDataComplete Dtmf8 = - new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 }, + public JoinDataComplete Dtmf8 = new JoinDataComplete( + new JoinData + { + JoinNumber = 18, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 8", @@ -1775,8 +1390,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("9")] - public JoinDataComplete Dtmf9 = - new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 }, + public JoinDataComplete Dtmf9 = new JoinDataComplete( + new JoinData + { + JoinNumber = 19, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF 9", @@ -1784,19 +1403,27 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - [JoinName("#")] - public JoinDataComplete DtmfPound = - new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + [JoinName("0")] + public JoinDataComplete Dtmf0 = new JoinDataComplete( + new JoinData + { + JoinNumber = 20, + JoinSpan = 1 + }, new JoinMetadata { - Description = "DTMF #", + Description = "DTMF 0", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("*")] - public JoinDataComplete DtmfStar = - new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, + public JoinDataComplete DtmfStar = new JoinDataComplete( + new JoinData + { + JoinNumber = 21, + JoinSpan = 1 + }, new JoinMetadata { Description = "DTMF *", @@ -1804,9 +1431,27 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); + [JoinName("#")] + public JoinDataComplete DtmfPound = new JoinDataComplete( + new JoinData + { + JoinNumber = 22, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "DTMF #", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + [JoinName("EndCall")] - public JoinDataComplete EndCall = - new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, + public JoinDataComplete EndCall = new JoinDataComplete( + new JoinData + { + JoinNumber = 24, + JoinSpan = 1 + }, new JoinMetadata { Description = "Hang Up", @@ -1815,8 +1460,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("HookState")] - public JoinDataComplete HookState = - new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, + public JoinDataComplete HookState = new JoinDataComplete( + new JoinData + { + JoinNumber = 31, + JoinSpan = 1 + }, new JoinMetadata { Description = "Current Hook State", @@ -1824,200 +1473,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - [JoinName("IncomingAnswer")] - public JoinDataComplete IncomingAnswer = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Answer Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCall")] - public JoinDataComplete IncomingCall = - new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("IncomingCallName")] - public JoinDataComplete IncomingCallName = - new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingCallNumber")] - public JoinDataComplete IncomingCallNumber = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Incoming Call Number", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("IncomingReject")] - public JoinDataComplete IncomingReject = - new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Reject Incoming Call", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - - [JoinName("ManualDial")] - public JoinDataComplete ManualDial = - new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Dial manual string", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("Meeting Count Fb")] - public JoinDataComplete MeetingCount = - new JoinDataComplete(new JoinData { JoinNumber = 161, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Meeting Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("MicMuteOff")] - public JoinDataComplete MicMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 172, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteOn")] - public JoinDataComplete MicMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 171, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MicMuteToggle")] - public JoinDataComplete MicMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 173, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Mic Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("MinutesBeforeMeetingStart")] - public JoinDataComplete MinutesBeforeMeetingStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Minutes before meeting start that a meeting is joinable", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("ParticipantCount")] - public JoinDataComplete ParticipantCount = - new JoinDataComplete(new JoinData { JoinNumber = 151, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Current Participant Count", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("Schedule")] - public JoinDataComplete Schedule = - new JoinDataComplete(new JoinData { JoinNumber = 102, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Schedule Data - XSIG", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - - [JoinName("AutoShareWhileInCall")] - public JoinDataComplete SourceShareAutoStart = - new JoinDataComplete(new JoinData { JoinNumber = 203, JoinSpan = 1 }, - new JoinMetadata - { - Description = "When high, will autostart sharing when a call is joined", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareEnd")] - public JoinDataComplete SourceShareEnd = - new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Stop Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SourceShareStart")] - public JoinDataComplete SourceShareStart = - new JoinDataComplete(new JoinData { JoinNumber = 201, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Start Sharing & Feedback", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("RecievingContent")] - public JoinDataComplete RecievingContent = - new JoinDataComplete(new JoinData { JoinNumber = 204, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Recieving content from the far end", - JoinType = eJoinType.Digital, - JoinCapabilities = eJoinCapabilities.ToSIMPL - }); - - [JoinName("SelfviewPosition")] - public JoinDataComplete SelfviewPosition = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SelfviewPositionFb")] - public JoinDataComplete SelfviewPositionFb = - new JoinDataComplete(new JoinData { JoinNumber = 211, JoinSpan = 1 }, - new JoinMetadata - { - Description = "advance selfview position", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - [JoinName("SpeedDialStart")] - public JoinDataComplete SpeedDialStart = - new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 4 }, + public JoinDataComplete SpeedDialStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 41, + JoinSpan = 4 + }, new JoinMetadata { Description = "Speed Dial", @@ -2025,79 +1487,69 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - [JoinName("UpdateMeetings")] - public JoinDataComplete UpdateMeetings = - new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 1 }, + [JoinName("IncomingCall")] + public JoinDataComplete IncomingCall = new JoinDataComplete( + new JoinData + { + JoinNumber = 50, + JoinSpan = 1 + }, new JoinMetadata { - Description = "Update Meetings", + Description = "Incoming Call", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("IncomingAnswer")] + public JoinDataComplete IncomingAnswer = new JoinDataComplete( + new JoinData + { + JoinNumber = 51, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Answer Incoming Call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); - [JoinName("VolumeDown")] - public JoinDataComplete VolumeDown = - new JoinDataComplete(new JoinData { JoinNumber = 175, JoinSpan = 1 }, + [JoinName("IncomingReject")] + public JoinDataComplete IncomingReject = new JoinDataComplete( + new JoinData + { + JoinNumber = 52, + JoinSpan = 1 + }, new JoinMetadata { - Description = "Volume Down", + Description = "Reject Incoming Call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); - [JoinName("VolumeLevel")] - public JoinDataComplete VolumeLevel = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, + [JoinName("ManualDial")] + public JoinDataComplete ManualDial = new JoinDataComplete( + new JoinData + { + JoinNumber = 71, + JoinSpan = 1 + }, new JoinMetadata { - Description = "Volume Level", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("VolumeMuteOff")] - public JoinDataComplete VolumeMuteOff = - new JoinDataComplete(new JoinData { JoinNumber = 177, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Off", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteOn")] - public JoinDataComplete VolumeMuteOn = - new JoinDataComplete(new JoinData { JoinNumber = 176, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute On", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeMuteToggle")] - public JoinDataComplete VolumeMuteToggle = - new JoinDataComplete(new JoinData { JoinNumber = 178, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Mute Toggle", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("VolumeUp")] - public JoinDataComplete VolumeUp = - new JoinDataComplete(new JoinData { JoinNumber = 174, JoinSpan = 1 }, - new JoinMetadata - { - Description = "Volume Up", + Description = "Dial manual string", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("DialPhoneCall")] - public JoinDataComplete DialPhone = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + public JoinDataComplete DialPhone = new JoinDataComplete( + new JoinData + { + JoinNumber = 72, + JoinSpan = 1 + }, new JoinMetadata { Description = "Dial Phone", @@ -2106,8 +1558,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("PhoneHookState")] - public JoinDataComplete PhoneHookState = - new JoinDataComplete(new JoinData { JoinNumber = 72, JoinSpan = 1 }, + public JoinDataComplete PhoneHookState = new JoinDataComplete( + new JoinData + { + JoinNumber = 72, + JoinSpan = 1 + }, new JoinMetadata { Description = "Dial Phone", @@ -2116,8 +1572,12 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps }); [JoinName("EndPhoneCall")] - public JoinDataComplete HangUpPhone = - new JoinDataComplete(new JoinData { JoinNumber = 73, JoinSpan = 1 }, + public JoinDataComplete HangUpPhone = new JoinDataComplete( + new JoinData + { + JoinNumber = 73, + JoinSpan = 1 + }, new JoinMetadata { Description = "Hang Up PHone", @@ -2125,9 +1585,699 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); + [JoinName("DirectorySearchBusy")] + public JoinDataComplete DirectorySearchBusy = new JoinDataComplete( + new JoinData + { + JoinNumber = 100, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Search Busy FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryEntryIsContact")] + public JoinDataComplete DirectoryEntryIsContact = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Selected Entry Is Contact FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryLineSelected")] + public JoinDataComplete DirectoryLineSelected = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Line Selected FB", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryIsRoot")] + public JoinDataComplete DirectoryIsRoot = new JoinDataComplete( + new JoinData + { + JoinNumber = 102, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory is on Root FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryHasChanged")] + public JoinDataComplete DirectoryHasChanged = new JoinDataComplete( + new JoinData + { + JoinNumber = 103, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory has changed FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryRoot")] + public JoinDataComplete DirectoryRoot = new JoinDataComplete( + new JoinData + { + JoinNumber = 104, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Go to Directory Root", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryFolderBack")] + public JoinDataComplete DirectoryFolderBack = new JoinDataComplete( + new JoinData + { + JoinNumber = 105, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Go back one directory level", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DirectoryDialSelectedLine")] + public JoinDataComplete DirectoryDialSelectedLine = new JoinDataComplete( + new JoinData + { + JoinNumber = 106, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Dial selected directory line", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + [JoinName("CameraTiltUp")] + public JoinDataComplete CameraTiltUp = new JoinDataComplete( + new JoinData + { + JoinNumber = 111, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Tilt Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraTiltDown")] + public JoinDataComplete CameraTiltDown = new JoinDataComplete( + new JoinData + { + JoinNumber = 112, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Tilt Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanLeft")] + public JoinDataComplete CameraPanLeft = new JoinDataComplete( + new JoinData + { + JoinNumber = 113, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Pan Left", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPanRight")] + public JoinDataComplete CameraPanRight = new JoinDataComplete( + new JoinData + { + JoinNumber = 114, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Pan Right", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomIn")] + public JoinDataComplete CameraZoomIn = new JoinDataComplete( + new JoinData + { + JoinNumber = 115, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Zoom In", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraZoomOut")] + public JoinDataComplete CameraZoomOut = new JoinDataComplete( + new JoinData + { + JoinNumber = 116, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Zoom Out", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraPresetSave")] + public JoinDataComplete CameraPresetSave = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Save Selected Preset", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeAuto")] + public JoinDataComplete CameraModeAuto = new JoinDataComplete( + new JoinData + { + JoinNumber = 131, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Auto", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeManual")] + public JoinDataComplete CameraModeManual = new JoinDataComplete( + new JoinData + { + JoinNumber = 132, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Manual", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraModeOff")] + public JoinDataComplete CameraModeOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 133, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Mode Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSelfView")] + public JoinDataComplete CameraSelfView = new JoinDataComplete( + new JoinData + { + JoinNumber = 141, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Self View Toggle/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraLayout")] + public JoinDataComplete CameraLayout = new JoinDataComplete( + new JoinData + { + JoinNumber = 142, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Layout Toggle", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsAutoMode")] + public JoinDataComplete CameraSupportsAutoMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 143, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Supports Auto Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CameraSupportsOffMode")] + public JoinDataComplete CameraSupportsOffMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 144, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Supports Off Mode FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("UpdateMeetings")] + public JoinDataComplete UpdateMeetings = new JoinDataComplete( + new JoinData + { + JoinNumber = 160, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Update Meetings", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting1")] + public JoinDataComplete DialMeeting1 = new JoinDataComplete( + new JoinData + { + JoinNumber = 161, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join first meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting2")] + public JoinDataComplete DialMeeting2 = new JoinDataComplete( + new JoinData + { + JoinNumber = 162, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join second meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DialMeeting3")] + public JoinDataComplete DialMeeting3 = new JoinDataComplete( + new JoinData + { + JoinNumber = 163, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Join third meeting", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = new JoinDataComplete( + new JoinData + { + JoinNumber = 171, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 172, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("MicMuteToggle")] + public JoinDataComplete MicMuteToggle = new JoinDataComplete( + new JoinData + { + JoinNumber = 173, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Mic Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeUp")] + public JoinDataComplete VolumeUp = new JoinDataComplete( + new JoinData + { + JoinNumber = 174, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Up", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeDown")] + public JoinDataComplete VolumeDown = new JoinDataComplete( + new JoinData + { + JoinNumber = 175, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Down", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOn")] + public JoinDataComplete VolumeMuteOn = new JoinDataComplete( + new JoinData + { + JoinNumber = 176, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute On", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteOff")] + public JoinDataComplete VolumeMuteOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 177, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute Off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("VolumeMuteToggle")] + public JoinDataComplete VolumeMuteToggle = new JoinDataComplete( + new JoinData + { + JoinNumber = 178, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Mute Toggle", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareStart")] + public JoinDataComplete SourceShareStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 201, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Start Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SourceShareEnd")] + public JoinDataComplete SourceShareEnd = new JoinDataComplete( + new JoinData + { + JoinNumber = 202, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Stop Sharing & Feedback", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("AutoShareWhileInCall")] + public JoinDataComplete SourceShareAutoStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 203, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "When high, will autostart sharing when a call is joined", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("RecievingContent")] + public JoinDataComplete RecievingContent = new JoinDataComplete( + new JoinData + { + JoinNumber = 204, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Recieving content from the far end", + JoinType = eJoinType.Digital, + JoinCapabilities = eJoinCapabilities.ToSIMPL + }); + + [JoinName("SelfviewPosition")] + public JoinDataComplete SelfviewPosition = new JoinDataComplete( + new JoinData + { + JoinNumber = 211, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + + #endregion + + + + #region Analog + + [JoinName("MinutesBeforeMeetingStart")] + public JoinDataComplete MinutesBeforeMeetingStart = new JoinDataComplete( + new JoinData + { + JoinNumber = 41, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Minutes before meeting start that a meeting is joinable", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraNumberSelect")] + public JoinDataComplete CameraNumberSelect = new JoinDataComplete( + new JoinData + { + JoinNumber = 60, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Number Select/FB", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectoryRowCount")] + public JoinDataComplete DirectoryRowCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Row Count FB", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("DirectorySelectRow")] + public JoinDataComplete DirectorySelectRow = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Select Row", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("CameraPresetSelect")] + public JoinDataComplete CameraPresetSelect = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Preset Select", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ParticipantCount")] + public JoinDataComplete ParticipantCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 151, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Participant Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("Meeting Count Fb")] + public JoinDataComplete MeetingCount = new JoinDataComplete( + new JoinData + { + JoinNumber = 161, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Meeting Count", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("VolumeLevel")] + public JoinDataComplete VolumeLevel = new JoinDataComplete( + new JoinData + { + JoinNumber = 174, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Volume Level", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); + + #endregion + + + + #region Serials + + [JoinName("CurrentDialString")] + public JoinDataComplete CurrentDialString = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Dial String", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + [JoinName("PhoneString")] - public JoinDataComplete PhoneDialString = - new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + public JoinDataComplete PhoneDialString = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, new JoinMetadata { Description = "Phone Dial String", @@ -2135,6 +2285,220 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Serial }); + [JoinName("CurrentCallName")] + public JoinDataComplete CurrentCallData = new JoinDataComplete( + new JoinData + { + JoinNumber = 2, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Call Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CallDirection")] + public JoinDataComplete CallDirection = new JoinDataComplete( + new JoinData + { + JoinNumber = 22, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Call Direction", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallName")] + public JoinDataComplete IncomingCallName = new JoinDataComplete( + new JoinData + { + JoinNumber = 51, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Incoming Call Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("IncomingCallNumber")] + public JoinDataComplete IncomingCallNumber = new JoinDataComplete( + new JoinData + { + JoinNumber = 52, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Incoming Call Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + + [JoinName("DirectorySearchString")] + public JoinDataComplete DirectorySearchString = new JoinDataComplete( + new JoinData + { + JoinNumber = 100, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Search String", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntries")] + public JoinDataComplete DirectoryEntries = new JoinDataComplete( + new JoinData + { + JoinNumber = 101, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Directory Entries - XSig, 255 entries", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("Schedule")] + public JoinDataComplete Schedule = new JoinDataComplete( + new JoinData + { + JoinNumber = 102, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Schedule Data - XSIG", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraPresetNames")] + public JoinDataComplete CameraPresetNames = new JoinDataComplete( + new JoinData + { + JoinNumber = 121, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Camera Preset Names - XSIG, max of 15", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CameraLayoutStringFb")] + public JoinDataComplete CameraLayoutStringFb = new JoinDataComplete( + new JoinData + { + JoinNumber = 141, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Layout Fb", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentParticipants")] + public JoinDataComplete CurrentParticipants = new JoinDataComplete( + new JoinData + { + JoinNumber = 151, + JoinSpan = 1 + }, + new JoinMetadata() + { + Description = "Current Participants XSig", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("CurrentSource")] + public JoinDataComplete CurrentSource = new JoinDataComplete( + new JoinData + { + JoinNumber = 201, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Current Source", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("SelfviewPositionFb")] + public JoinDataComplete SelfviewPositionFb = new JoinDataComplete( + new JoinData + { + JoinNumber = 211, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "advance selfview position", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedName")] + public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete( + new JoinData + { + JoinNumber = 356, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Entry Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectoryEntrySelectedNumber")] + public JoinDataComplete DirectoryEntrySelectedNumber = new JoinDataComplete( + new JoinData + { + JoinNumber = 357, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Entry Number", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("DirectorySelectedFolderName")] + public JoinDataComplete DirectorySelectedFolderName = new JoinDataComplete( + new JoinData + { + JoinNumber = 358, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Selected Directory Folder Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + #endregion + + public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof(VideoCodecControllerJoinMap)) { 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 a693bb12..7fecc98a 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 @@ -559,10 +559,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec const int maxDigitals = 7; const int maxStrings = 1; const int maxAnalogs = 1; - const int offset = maxDigitals + maxStrings + maxAnalogs; - var digitalIndex = maxStrings + maxAnalogs * maxParticipants; //15 + const int offset = maxDigitals + maxStrings + maxAnalogs; // 9 + var digitalIndex = (maxStrings + maxAnalogs) * maxParticipants; // 100 var stringIndex = 0; - var analogIndex = 0; + var analogIndex = stringIndex + maxParticipants; var meetingIndex = 0; var tokenArray = new XSigToken[maxParticipants * offset]; From 4e041d17734bdd3756c77ef78facceb925a02c5e Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 11 May 2021 11:36:17 -0500 Subject: [PATCH 216/480] Removed unused DecodecParticipantsXSig method. --- .../VideoCodec/VideoCodecBase.cs | 41 ------------------- 1 file changed, 41 deletions(-) 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 7fecc98a..6f735740 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 @@ -618,47 +618,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec return GetXSigString(tokenArray); } - // TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL - private void DecodeParticipantsXSig(string xsigData) - { - if (string.IsNullOrEmpty(xsigData)) return; - var bytes = Encoding.GetEncoding(XSigEncoding).GetBytes(xsigData); - using (var xsigStream = new XSigTokenStreamReader(new MemoryStream(bytes))) - { - XSigToken token = null; - while ((token = xsigStream.ReadXSigToken()) != null) - { - switch (token.TokenType) - { - case XSigTokenType.Digital: - { - var data = token as XSigDigitalToken; - if (data == null) return; - Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", - data.TokenType, data.Index, data.Value.ToString()); - break; - } - case XSigTokenType.Analog: - { - var data = token as XSigAnalogToken; - if (data == null) return; - Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", - data.TokenType, data.Index, data.Value); - break; - } - case XSigTokenType.Serial: - { - var data = token as XSigSerialToken; - if (data == null) return; - Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", data.TokenType, data.Index, - data.Value); - break; - } - } - } - } - } - private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); From b4edb021ee68f7a495f92ba7fc150a2947a41c96 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 11 May 2021 12:23:27 -0600 Subject: [PATCH 217/480] #698 merged in join map updates from JKD. Fixed enum bit comparison for available layout feedbacks --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 42 +++++----- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 8 +- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 78 +++++++++---------- 3 files changed, 61 insertions(+), 67 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index 724331fb..c2d45e42 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -875,12 +875,11 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantAudioMuteToggleStart")] public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 2001, + JoinNumber = 500, JoinSpan = 50 }, new JoinMetadata @@ -890,12 +889,11 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantVideoMuteToggleStart")] public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 2101, + JoinNumber = 800, JoinSpan = 50 }, new JoinMetadata @@ -905,12 +903,11 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantPinToggleStart")] public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 2201, + JoinNumber = 1100, JoinSpan = 50 }, new JoinMetadata @@ -2177,14 +2174,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantAudioMuteToggleStart")] public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 2001, - JoinSpan = 50 - }, + new JoinData + { + JoinNumber = 500, + JoinSpan = 50 + }, new JoinMetadata { Description = "Toggles the participant's audio mute status", @@ -2192,14 +2188,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantVideoMuteToggleStart")] public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 2101, - JoinSpan = 50 - }, + new JoinData + { + JoinNumber = 800, + JoinSpan = 50 + }, new JoinMetadata { Description = "Toggles the participant's video mute status", @@ -2207,14 +2202,13 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - // TODO: #698 Set Join number [JoinName("ParticipantPinToggleStart")] public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 2201, - JoinSpan = 50 - }, + new JoinData + { + JoinNumber = 1100, + JoinSpan = 50 + }, new JoinMetadata { Description = "Toggles the participant's pin status", diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 10f5929d..5b5a2966 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1727,13 +1727,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { layoutsCodec.AvailableLayoutsChanged += (o, a) => { - trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, a.AvailableLayouts + trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); - trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, a.AvailableLayouts + trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); - trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, a.AvailableLayouts + trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); - trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, a.AvailableLayouts + trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); }; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 7ceb1ba3..61a59fff 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -164,47 +164,47 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); - [JoinName("ParticipantAudioMuteToggleStart")] - public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 500, - JoinSpan = 100 - }, - new JoinMetadata - { - Description = "Toggles the participant's audio mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + //[JoinName("ParticipantAudioMuteToggleStart")] + //public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 500, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's audio mute status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); - [JoinName("ParticipantVideoMuteToggleStart")] - public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 800, - JoinSpan = 100 - }, - new JoinMetadata - { - Description = "Toggles the participant's video mute status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + //[JoinName("ParticipantVideoMuteToggleStart")] + //public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 800, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's video mute status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); - [JoinName("ParticipantPinToggleStart")] - public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( - new JoinData - { - JoinNumber = 1100, - JoinSpan = 100 - }, - new JoinMetadata - { - Description = "Toggles the participant's pin status", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); + //[JoinName("ParticipantPinToggleStart")] + //public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 1100, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's pin status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); #endregion From 8d215930d9c2cb28796dc0872cc7e32681d83300 Mon Sep 17 00:00:00 2001 From: Jason T Alborough Date: Tue, 11 May 2021 15:20:35 -0400 Subject: [PATCH 218/480] Adds WriteControlProperty to ReconfigurableDevice CameraBase now uses ReconfigurableDevice --- .../Devices/ReconfigurableDevice.cs | 8 +++++++ .../Cameras/CameraBase.cs | 22 ++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs index 7b4f1c99..60c8db0c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs @@ -7,6 +7,8 @@ using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace PepperDash.Essentials.Core.Devices { @@ -52,6 +54,12 @@ namespace PepperDash.Essentials.Core.Devices Name = config.Name; } + protected virtual void WriteControlProperty(JToken controlObject) + { + Config.Properties["control"] = JToken.FromObject(controlObject); + CustomSetConfig(Config); + } + /// /// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc) /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs index 8b42cd82..edfd34cb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs @@ -8,6 +8,8 @@ using Crestron.SimplSharp.Reflection; using Crestron.SimplSharpPro.DeviceSupport; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Devices.Common.Codec; @@ -25,7 +27,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras Focus = 8 } - public abstract class CameraBase : EssentialsDevice, IRoutingOutputs + public abstract class CameraBase : ReconfigurableDevice, IRoutingOutputs { public eCameraControlMode ControlMode { get; protected set; } @@ -70,12 +72,20 @@ namespace PepperDash.Essentials.Devices.Common.Cameras // A bitmasked value to indicate the movement capabilites of this camera protected eCameraCapabilities Capabilities { get; set; } - protected CameraBase(string key, string name) : - base(key, name) - { - OutputPorts = new RoutingPortCollection(); + protected CameraBase(DeviceConfig config) : base(config) + { + OutputPorts = new RoutingPortCollection(); - ControlMode = eCameraControlMode.Manual; + ControlMode = eCameraControlMode.Manual; + + } + + protected CameraBase(string key, string name) : + base (new DeviceConfig{Name = name, Key = key}) + { + OutputPorts = new RoutingPortCollection(); + + ControlMode = eCameraControlMode.Manual; } protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, From da179c01f5098d1a5469bb84743f363f4cf1d2c0 Mon Sep 17 00:00:00 2001 From: Jason T Alborough Date: Tue, 11 May 2021 17:52:26 -0400 Subject: [PATCH 219/480] Fixes UpdateDeviceConfig() --- .../Config/Essentials/ConfigWriter.cs | 320 +++++++++--------- 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs index cb361d28..b97eeafa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs @@ -1,162 +1,162 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using PepperDash.Core; - -namespace PepperDash.Essentials.Core.Config -{ - /// - /// Responsible for updating config at runtime, and writing the updates out to a local file - /// - public class ConfigWriter - { - public const string LocalConfigFolder = "LocalConfig"; - - public const long WriteTimeout = 30000; - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PepperDash.Core; + +namespace PepperDash.Essentials.Core.Config +{ + /// + /// Responsible for updating config at runtime, and writing the updates out to a local file + /// + public class ConfigWriter + { + public const string LocalConfigFolder = "LocalConfig"; + + public const long WriteTimeout = 30000; + public static CTimer WriteTimer; - static CCriticalSection fileLock = new CCriticalSection(); - - /// - /// Updates the config properties of a device - /// - /// - /// - /// - public static bool UpdateDeviceProperties(string deviceKey, JToken properties) - { - bool success = false; - - // Get the current device config - var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey)); - - if (deviceConfig != null) - { - // Replace the current properties JToken with the new one passed into this method - deviceConfig.Properties = properties; - - Debug.Console(1, "Updated properties of device: '{0}'", deviceKey); - - success = true; - } - - ResetTimer(); - - return success; - } - - public static bool UpdateDeviceConfig(DeviceConfig config) - { - bool success = false; - - var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key)); - - if (deviceConfig != null) - { - deviceConfig = config; - - Debug.Console(1, "Updated config of device: '{0}'", config.Key); - - success = true; - } - - ResetTimer(); - - return success; - } - - public static bool UpdateRoomConfig(DeviceConfig config) - { - bool success = false; - - var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key)); - - if (deviceConfig != null) - { - deviceConfig = config; - - Debug.Console(1, "Updated config of device: '{0}'", config.Key); - - success = true; - } - - ResetTimer(); - - return success; - } - - /// - /// Resets (or starts) the write timer - /// - static void ResetTimer() - { - if (WriteTimer == null) - WriteTimer = new CTimer(WriteConfigFile, WriteTimeout); - - WriteTimer.Reset(WriteTimeout); - - Debug.Console(1, "Config File write timer has been reset."); - } - - /// - /// Writes the current config to a file in the LocalConfig subfolder - /// - /// - private static void WriteConfigFile(object o) - { - var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json"; - - var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject); - - WriteFile(filePath, configData); - } - - /// - /// Writes - /// - /// - /// - public static void WriteFile(string filePath, string configData) - { - if (WriteTimer != null) - WriteTimer.Stop(); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file"); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath); - - try - { - if (fileLock.TryEnter()) - { - using (StreamWriter sw = new StreamWriter(filePath)) - { - sw.Write(configData); - sw.Flush(); - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock"); - } - } - catch (Exception e) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e); - } - finally - { - if (fileLock != null && !fileLock.Disposed) - fileLock.Leave(); - - } - } - - - } + static CCriticalSection fileLock = new CCriticalSection(); + + /// + /// Updates the config properties of a device + /// + /// + /// + /// + public static bool UpdateDeviceProperties(string deviceKey, JToken properties) + { + bool success = false; + + // Get the current device config + var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey)); + + if (deviceConfig != null) + { + // Replace the current properties JToken with the new one passed into this method + deviceConfig.Properties = properties; + + Debug.Console(1, "Updated properties of device: '{0}'", deviceKey); + + success = true; + } + + ResetTimer(); + + return success; + } + + public static bool UpdateDeviceConfig(DeviceConfig config) + { + bool success = false; + + var deviceConfig = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key)); + + if (deviceConfig >= 0) + { + ConfigReader.ConfigObject.Devices[deviceConfig] = config; + + Debug.Console(1, "Updated config of device: '{0}'", config.Key); + + success = true; + } + + ResetTimer(); + + return success; + } + + public static bool UpdateRoomConfig(DeviceConfig config) + { + bool success = false; + + var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key)); + + if (deviceConfig != null) + { + deviceConfig = config; + + Debug.Console(1, "Updated config of device: '{0}'", config.Key); + + success = true; + } + + ResetTimer(); + + return success; + } + + /// + /// Resets (or starts) the write timer + /// + static void ResetTimer() + { + if (WriteTimer == null) + WriteTimer = new CTimer(WriteConfigFile, WriteTimeout); + + WriteTimer.Reset(WriteTimeout); + + Debug.Console(1, "Config File write timer has been reset."); + } + + /// + /// Writes the current config to a file in the LocalConfig subfolder + /// + /// + private static void WriteConfigFile(object o) + { + var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json"; + + var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject); + + WriteFile(filePath, configData); + } + + /// + /// Writes + /// + /// + /// + public static void WriteFile(string filePath, string configData) + { + if (WriteTimer != null) + WriteTimer.Stop(); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file"); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath); + + try + { + if (fileLock.TryEnter()) + { + using (StreamWriter sw = new StreamWriter(filePath)) + { + sw.Write(configData); + sw.Flush(); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock"); + } + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e); + } + finally + { + if (fileLock != null && !fileLock.Disposed) + fileLock.Leave(); + + } + } + + + } } \ No newline at end of file From c14193f9aca0c1fb019cf47346143b9d093f58f1 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 11 May 2021 18:13:18 -0500 Subject: [PATCH 220/480] Updates to VideoCodecControllerJoinMap to fix joins for Participant triggers. Updated ZoomRoomJoinMaps to implement zConfiguration.eLayoutStyle to pass the name across the bridge. --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 8 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 4672 +++++++++-------- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 8 +- 3 files changed, 2348 insertions(+), 2340 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index c2d45e42..dcb66a2e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -879,7 +879,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 500, + JoinNumber = 501, JoinSpan = 50 }, new JoinMetadata @@ -893,7 +893,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 800, + JoinNumber = 801, JoinSpan = 50 }, new JoinMetadata @@ -907,7 +907,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( new JoinData { - JoinNumber = 1100, + JoinNumber = 1101, JoinSpan = 50 }, new JoinMetadata @@ -1237,7 +1237,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps Description = "advance selfview position", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial - }); + }); [JoinName("DirectoryEntrySelectedName")] public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete( diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 5b5a2966..71882d5c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -3,11 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; using Crestron.SimplSharpPro.CrestronThread; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; +using PepperDash.Core.Intersystem.Tokens; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; @@ -20,1750 +22,1756 @@ using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { - public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, - IRouting, - IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, - IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute - { - private const long MeetingRefreshTimer = 60000; - private const uint DefaultMeetingDurationMin = 30; - private const string Delimiter = "\x0D\x0A"; - private readonly CrestronQueue _receiveQueue; + public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, + IRouting, + IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, + IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute + { + private const long MeetingRefreshTimer = 60000; + private const uint DefaultMeetingDurationMin = 30; + private const string Delimiter = "\x0D\x0A"; + private readonly CrestronQueue _receiveQueue; - private readonly Thread _receiveThread; + private readonly Thread _receiveThread; - private readonly ZoomRoomSyncState _syncState; - public bool CommDebuggingIsOn; - private CodecDirectory _currentDirectoryResult; - private uint _jsonCurlyBraceCounter; - private bool _jsonFeedbackMessageIsIncoming; - private StringBuilder _jsonMessage; - private int _previousVolumeLevel; - private CameraBase _selectedCamera; + private readonly ZoomRoomSyncState _syncState; + public bool CommDebuggingIsOn; + private CodecDirectory _currentDirectoryResult; + private uint _jsonCurlyBraceCounter; + private bool _jsonFeedbackMessageIsIncoming; + private StringBuilder _jsonMessage; + private int _previousVolumeLevel; + private CameraBase _selectedCamera; - private readonly ZoomRoomPropertiesConfig _props; + private readonly ZoomRoomPropertiesConfig _props; - public ZoomRoom(DeviceConfig config, IBasicCommunication comm) - : base(config) - { - _props = JsonConvert.DeserializeObject(config.Properties.ToString()); + public ZoomRoom(DeviceConfig config, IBasicCommunication comm) + : base(config) + { + _props = JsonConvert.DeserializeObject(config.Properties.ToString()); - // The queue that will collect the repsonses in the order they are received - _receiveQueue = new CrestronQueue(1024); + // The queue that will collect the repsonses in the order they are received + _receiveQueue = new CrestronQueue(1024); - // The thread responsible for dequeuing and processing the messages - _receiveThread = new Thread(o => ProcessQueue(), null) {Priority = Thread.eThreadPriority.MediumPriority}; + // The thread responsible for dequeuing and processing the messages + _receiveThread = new Thread(o => ProcessQueue(), null) { Priority = Thread.eThreadPriority.MediumPriority }; - Communication = comm; + Communication = comm; - if (_props.CommunicationMonitorProperties != null) - { - CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, - _props.CommunicationMonitorProperties); - } - else - { - CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, - "zStatus SystemUnit\r"); - } + if (_props.CommunicationMonitorProperties != null) + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, + _props.CommunicationMonitorProperties); + } + else + { + CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, + "zStatus SystemUnit\r"); + } - DeviceManager.AddDevice(CommunicationMonitor); + DeviceManager.AddDevice(CommunicationMonitor); - Status = new ZoomRoomStatus(); + Status = new ZoomRoomStatus(); - Configuration = new ZoomRoomConfiguration(); + Configuration = new ZoomRoomConfiguration(); - CodecInfo = new ZoomRoomInfo(Status, Configuration); + CodecInfo = new ZoomRoomInfo(Status, Configuration); - _syncState = new ZoomRoomSyncState(Key + "--Sync", this); + _syncState = new ZoomRoomSyncState(Key + "--Sync", this); - _syncState.InitialSyncCompleted += SyncState_InitialSyncCompleted; + _syncState.InitialSyncCompleted += SyncState_InitialSyncCompleted; - PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync"); + PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync"); - PortGather = new CommunicationGather(Communication, "\x0A") {IncludeDelimiter = true}; - PortGather.LineReceived += Port_LineReceived; + PortGather = new CommunicationGather(Communication, "\x0A") { IncludeDelimiter = true }; + PortGather.LineReceived += Port_LineReceived; - CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); + CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); - Output1 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); + Output1 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); - SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc); + SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc); - CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc); + CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc); - CameraIsMutedFeedback = CameraIsOffFeedback; + CameraIsMutedFeedback = CameraIsOffFeedback; - CameraAutoModeIsOnFeedback = new BoolFeedback(CameraAutoModeIsOnFeedbackFunc); + CameraAutoModeIsOnFeedback = new BoolFeedback(CameraAutoModeIsOnFeedbackFunc); - CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer); + CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer); - ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); + ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); - SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); + SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); - SetUpFeedbackActions(); + SetUpFeedbackActions(); - Cameras = new List(); + Cameras = new List(); - SetUpDirectory(); + SetUpDirectory(); - Participants = new CodecParticipants(); + Participants = new CodecParticipants(); - SupportsCameraOff = _props.SupportsCameraOff; - SupportsCameraAutoMode = _props.SupportsCameraAutoMode; + SupportsCameraOff = _props.SupportsCameraOff; + SupportsCameraAutoMode = _props.SupportsCameraAutoMode; - PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc); - CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc); - CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc); + PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc); + CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc); + CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc); - LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); + LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); - LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); - LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); - CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); - ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); + LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); + LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); + CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); + ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); - NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); + NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); - } + } - public CommunicationGather PortGather { get; private set; } + public CommunicationGather PortGather { get; private set; } - public ZoomRoomStatus Status { get; private set; } + public ZoomRoomStatus Status { get; private set; } - public ZoomRoomConfiguration Configuration { get; private set; } + public ZoomRoomConfiguration Configuration { get; private set; } - //CTimer LoginMessageReceivedTimer; - //CTimer RetryConnectionTimer; + //CTimer LoginMessageReceivedTimer; + //CTimer RetryConnectionTimer; - /// - /// Gets and returns the scaled volume of the codec - /// - protected override Func VolumeLevelFeedbackFunc - { - get - { - return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); - } - } + /// + /// Gets and returns the scaled volume of the codec + /// + protected override Func VolumeLevelFeedbackFunc + { + get + { + return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); + } + } - protected override Func PrivacyModeIsOnFeedbackFunc - { - get { return () => Configuration.Call.Microphone.Mute; } - } + protected override Func PrivacyModeIsOnFeedbackFunc + { + get { return () => Configuration.Call.Microphone.Mute; } + } - protected override Func StandbyIsOnFeedbackFunc - { - get { return () => false; } - } + protected override Func StandbyIsOnFeedbackFunc + { + get { return () => false; } + } - protected override Func SharingSourceFeedbackFunc - { - get { return () => Status.Sharing.dispState; } - } + protected override Func SharingSourceFeedbackFunc + { + get { return () => Status.Sharing.dispState; } + } - protected override Func SharingContentIsOnFeedbackFunc - { - get { return () => Status.Call.Sharing.IsSharing; } - } + protected override Func SharingContentIsOnFeedbackFunc + { + get { return () => Status.Call.Sharing.IsSharing; } + } - protected Func FarEndIsSharingContentFeedbackFunc - { - get { return () => Status.Call.Sharing.State == zEvent.eSharingState.Receiving; } - } + protected Func FarEndIsSharingContentFeedbackFunc + { + get { return () => Status.Call.Sharing.State == zEvent.eSharingState.Receiving; } + } - protected override Func MuteFeedbackFunc - { - get { return () => Configuration.Audio.Output.Volume == 0; } - } + protected override Func MuteFeedbackFunc + { + get { return () => Configuration.Audio.Output.Volume == 0; } + } - //protected Func RoomIsOccupiedFeedbackFunc - //{ - // get - // { - // return () => false; - // } - //} + //protected Func RoomIsOccupiedFeedbackFunc + //{ + // get + // { + // return () => false; + // } + //} - //protected Func PeopleCountFeedbackFunc - //{ - // get - // { - // return () => 0; - // } - //} + //protected Func PeopleCountFeedbackFunc + //{ + // get + // { + // return () => 0; + // } + //} - protected Func SelfViewIsOnFeedbackFunc - { - get { return () => !Configuration.Video.HideConfSelfVideo; } - } + protected Func SelfViewIsOnFeedbackFunc + { + get { return () => !Configuration.Video.HideConfSelfVideo; } + } - protected Func CameraIsOffFeedbackFunc - { - get { return () => Configuration.Call.Camera.Mute; } - } - - protected Func CameraAutoModeIsOnFeedbackFunc - { - get { return () => false; } - } - - protected Func SelfviewPipPositionFeedbackFunc - { - get - { - return - () => - _currentSelfviewPipPosition != null - ? _currentSelfviewPipPosition.Command ?? "Unknown" - : "Unknown"; - } - } - - protected Func LocalLayoutIsProminentFeedbackFunc - { - get { return () => false; } - } - - - public RoutingInputPort CodecOsdIn { get; private set; } - public RoutingOutputPort Output1 { get; private set; } - - #region ICommunicationMonitor Members - - public StatusMonitorBase CommunicationMonitor { get; private set; } - - #endregion - - #region IHasCodecCameras Members - - public event EventHandler CameraSelected; - - public List Cameras { get; private set; } - - public CameraBase SelectedCamera - { - get { return _selectedCamera; } - private set - { - _selectedCamera = value; - SelectedCameraFeedback.FireUpdate(); - ControllingFarEndCameraFeedback.FireUpdate(); - - var handler = CameraSelected; - if (handler != null) - { - handler(this, new CameraSelectedEventArgs(SelectedCamera)); - } - } - } - - - public StringFeedback SelectedCameraFeedback { get; private set; } - - public void SelectCamera(string key) - { - if (Cameras == null) - { - return; - } - - var camera = Cameras.FirstOrDefault(c => c.Key.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1); - if (camera != null) - { - Debug.Console(1, this, "Selected Camera with key: '{0}'", camera.Key); - SelectedCamera = camera; - } - else - { - Debug.Console(1, this, "Unable to select camera with key: '{0}'", key); - } - } + protected Func CameraIsOffFeedbackFunc + { + get { return () => Configuration.Call.Camera.Mute; } + } + + protected Func CameraAutoModeIsOnFeedbackFunc + { + get { return () => false; } + } + + protected Func SelfviewPipPositionFeedbackFunc + { + get + { + return + () => + _currentSelfviewPipPosition != null + ? _currentSelfviewPipPosition.Command ?? "Unknown" + : "Unknown"; + } + } + + protected Func LocalLayoutIsProminentFeedbackFunc + { + get { return () => false; } + } + + + public RoutingInputPort CodecOsdIn { get; private set; } + public RoutingOutputPort Output1 { get; private set; } + + #region ICommunicationMonitor Members + + public StatusMonitorBase CommunicationMonitor { get; private set; } + + #endregion + + #region IHasCodecCameras Members + + public event EventHandler CameraSelected; + + public List Cameras { get; private set; } + + public CameraBase SelectedCamera + { + get { return _selectedCamera; } + private set + { + _selectedCamera = value; + SelectedCameraFeedback.FireUpdate(); + ControllingFarEndCameraFeedback.FireUpdate(); + + var handler = CameraSelected; + if (handler != null) + { + handler(this, new CameraSelectedEventArgs(SelectedCamera)); + } + } + } + + + public StringFeedback SelectedCameraFeedback { get; private set; } + + public void SelectCamera(string key) + { + if (Cameras == null) + { + return; + } + + var camera = Cameras.FirstOrDefault(c => c.Key.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1); + if (camera != null) + { + Debug.Console(1, this, "Selected Camera with key: '{0}'", camera.Key); + SelectedCamera = camera; + } + else + { + Debug.Console(1, this, "Unable to select camera with key: '{0}'", key); + } + } - public CameraBase FarEndCamera { get; private set; } + public CameraBase FarEndCamera { get; private set; } - public BoolFeedback ControllingFarEndCameraFeedback { get; private set; } + public BoolFeedback ControllingFarEndCameraFeedback { get; private set; } - #endregion + #endregion - #region IHasCodecSelfView Members + #region IHasCodecSelfView Members - public BoolFeedback SelfviewIsOnFeedback { get; private set; } + public BoolFeedback SelfviewIsOnFeedback { get; private set; } - public void SelfViewModeOn() - { - SendText("zConfiguration Video hide_conf_self_video: off"); - } + public void SelfViewModeOn() + { + SendText("zConfiguration Video hide_conf_self_video: off"); + } - public void SelfViewModeOff() - { - SendText("zConfiguration Video hide_conf_self_video: on"); - } + public void SelfViewModeOff() + { + SendText("zConfiguration Video hide_conf_self_video: on"); + } - public void SelfViewModeToggle() - { - if (SelfviewIsOnFeedback.BoolValue) - { - SelfViewModeOff(); - } - else - { - SelfViewModeOn(); - } - } + public void SelfViewModeToggle() + { + if (SelfviewIsOnFeedback.BoolValue) + { + SelfViewModeOff(); + } + else + { + SelfViewModeOn(); + } + } - #endregion + #endregion - #region IHasDirectoryHistoryStack Members + #region IHasDirectoryHistoryStack Members - public event EventHandler DirectoryResultReturned; - public CodecDirectory DirectoryRoot { get; private set; } + public event EventHandler DirectoryResultReturned; + public CodecDirectory DirectoryRoot { get; private set; } - public CodecDirectory CurrentDirectoryResult - { - get { return _currentDirectoryResult; } - } + public CodecDirectory CurrentDirectoryResult + { + get { return _currentDirectoryResult; } + } - public CodecPhonebookSyncState PhonebookSyncState { get; private set; } + public CodecPhonebookSyncState PhonebookSyncState { get; private set; } - public void SearchDirectory(string searchString) - { - var directoryResults = new CodecDirectory(); + public void SearchDirectory(string searchString) + { + var directoryResults = new CodecDirectory(); - directoryResults.AddContactsToDirectory( - DirectoryRoot.CurrentDirectoryResults.FindAll( - c => c.Name.IndexOf(searchString, 0, StringComparison.OrdinalIgnoreCase) > -1)); + directoryResults.AddContactsToDirectory( + DirectoryRoot.CurrentDirectoryResults.FindAll( + c => c.Name.IndexOf(searchString, 0, StringComparison.OrdinalIgnoreCase) > -1)); - DirectoryBrowseHistoryStack.Clear(); - _currentDirectoryResult = directoryResults; + DirectoryBrowseHistoryStack.Clear(); + _currentDirectoryResult = directoryResults; - OnDirectoryResultReturned(directoryResults); - } + OnDirectoryResultReturned(directoryResults); + } - public void GetDirectoryFolderContents(string folderId) - { - var directoryResults = new CodecDirectory {ResultsFolderId = folderId}; + public void GetDirectoryFolderContents(string folderId) + { + var directoryResults = new CodecDirectory { ResultsFolderId = folderId }; - directoryResults.AddContactsToDirectory( - DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId))); + directoryResults.AddContactsToDirectory( + DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId))); - DirectoryBrowseHistoryStack.Push(_currentDirectoryResult); + DirectoryBrowseHistoryStack.Push(_currentDirectoryResult); - _currentDirectoryResult = directoryResults; + _currentDirectoryResult = directoryResults; - OnDirectoryResultReturned(directoryResults); - } + OnDirectoryResultReturned(directoryResults); + } - public void SetCurrentDirectoryToRoot() - { - DirectoryBrowseHistoryStack.Clear(); + public void SetCurrentDirectoryToRoot() + { + DirectoryBrowseHistoryStack.Clear(); - _currentDirectoryResult = DirectoryRoot; - - OnDirectoryResultReturned(DirectoryRoot); - } - - public void GetDirectoryParentFolderContents() - { - if (DirectoryBrowseHistoryStack.Count == 0) - { - return; - } - - var currentDirectory = DirectoryBrowseHistoryStack.Pop(); - - _currentDirectoryResult = currentDirectory; - - OnDirectoryResultReturned(currentDirectory); - } + _currentDirectoryResult = DirectoryRoot; + + OnDirectoryResultReturned(DirectoryRoot); + } + + public void GetDirectoryParentFolderContents() + { + if (DirectoryBrowseHistoryStack.Count == 0) + { + return; + } + + var currentDirectory = DirectoryBrowseHistoryStack.Pop(); + + _currentDirectoryResult = currentDirectory; + + OnDirectoryResultReturned(currentDirectory); + } - public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; } + public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; } - public List DirectoryBrowseHistory { get; private set; } + public List DirectoryBrowseHistory { get; private set; } - public Stack DirectoryBrowseHistoryStack { get; private set; } - - #endregion - - #region IHasScheduleAwareness Members - - public CodecScheduleAwareness CodecSchedule { get; private set; } - - public void GetSchedule() - { - GetBookings(); - } - - #endregion - - #region IRouting Members - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - ExecuteSwitch(inputSelector); - } - - #endregion - - private void SyncState_InitialSyncCompleted(object sender, EventArgs e) - { - SetUpRouting(); - - SetIsReady(); - } - - private void SetUpCallFeedbackActions() - { - Status.Call.Sharing.PropertyChanged += (o, a) => - { - if (a.PropertyName == "State") - { - SharingContentIsOnFeedback.FireUpdate(); - ReceivingContent.FireUpdate(); - } - }; - - Status.Call.PropertyChanged += (o, a) => - { - if (a.PropertyName == "Info") - { - Debug.Console(1, this, "Updating Call Status"); - UpdateCallStatus(); - } - }; - } - - /// - /// Subscribes to the PropertyChanged events on the state objects and fires the corresponding feedbacks. - /// - private void SetUpFeedbackActions() - { - Configuration.Audio.Output.PropertyChanged += (o, a) => - { - if (a.PropertyName == "Volume") - { - VolumeLevelFeedback.FireUpdate(); - MuteFeedback.FireUpdate(); - } - }; - - Configuration.Call.Microphone.PropertyChanged += (o, a) => - { - if (a.PropertyName == "Mute") - { - PrivacyModeIsOnFeedback.FireUpdate(); - } - }; - - Configuration.Video.PropertyChanged += (o, a) => - { - if (a.PropertyName == "HideConfSelfVideo") - { - SelfviewIsOnFeedback.FireUpdate(); - } - }; - Configuration.Video.Camera.PropertyChanged += (o, a) => - { - if (a.PropertyName == "SelectedId") - { - SelectCamera(Configuration.Video.Camera.SelectedId); - // this will in turn fire the affected feedbacks - } - }; - - Configuration.Call.Camera.PropertyChanged += (o, a) => - { - Debug.Console(1, this, "Configuration.Call.Camera.PropertyChanged: {0}", a.PropertyName); - - if (a.PropertyName != "Mute") return; - - CameraIsOffFeedback.FireUpdate(); - CameraAutoModeIsOnFeedback.FireUpdate(); - }; - - Configuration.Call.Layout.PropertyChanged += (o, a) => - { - switch (a.PropertyName) - { - case "Position": - { - ComputeSelfviewPipStatus(); - - SelfviewPipPositionFeedback.FireUpdate(); - - break; - } - case "ShareThumb": - { - ContentSwappedWithThumbnailFeedback.FireUpdate(); - break; - } - case "Style": - { - LocalLayoutFeedback.FireUpdate(); - break; - } - - } - }; - - Status.Call.Sharing.PropertyChanged += (o, a) => - { - if (a.PropertyName == "State") - { - SharingContentIsOnFeedback.FireUpdate(); - ReceivingContent.FireUpdate(); - } - }; - - Status.Call.PropertyChanged += (o, a) => - { - if (a.PropertyName == "Info") - { - Debug.Console(1, this, "Updating Call Status"); - UpdateCallStatus(); - } - }; - - Status.Sharing.PropertyChanged += (o, a) => - { - switch (a.PropertyName) - { - case "dispState": - SharingSourceFeedback.FireUpdate(); - break; - case "password": - break; - } - }; - - Status.PhoneCall.PropertyChanged += (o, a) => - { - switch (a.PropertyName) - { - case "IsIncomingCall": - Debug.Console(1, this, "Incoming Phone Call: {0}", Status.PhoneCall.IsIncomingCall); - break; - case "PeerDisplayName": - Debug.Console(1, this, "Peer Display Name: {0}", Status.PhoneCall.PeerDisplayName); - CallerIdNameFeedback.FireUpdate(); - break; - case "PeerNumber": - Debug.Console(1, this, "Peer Number: {0}", Status.PhoneCall.PeerNumber); - CallerIdNumberFeedback.FireUpdate(); - break; - case "OffHook": - Debug.Console(1, this, "Phone is OffHook: {0}", Status.PhoneCall.OffHook); - PhoneOffHookFeedback.FireUpdate(); - break; - } - }; - - Status.Layout.PropertyChanged += (o, a) => - { - switch (a.PropertyName) - { - case "can_Switch_Speaker_View": - case "can_Switch_Wall_View": - case "can_Switch_Share_On_All_Screens": - { - ComputeAvailableLayouts(); - break; - } - case "is_In_First_Page": - { - LayoutViewIsOnFirstPageFeedback.FireUpdate(); - break; - } - case "is_In_Last_Page": - { - LayoutViewIsOnLastPageFeedback.FireUpdate(); - break; - } - //case "video_type": - // { - // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style - // LocalLayoutFeedback.FireUpdate(); - // break; - // } - } - }; - - Status.NumberOfScreens.PropertyChanged += (o, a) => - { - switch (a.PropertyName) - { - case "NumberOfScreens": - { - NumberOfScreensFeedback.FireUpdate(); - break; - } - } - }; - } - - private void SetUpDirectory() - { - DirectoryRoot = new CodecDirectory(); - - DirectoryBrowseHistory = new List(); - DirectoryBrowseHistoryStack = new Stack(); - - CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot); - - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); - } - - private void SetUpRouting() - { - // Set up input ports - CreateOsdSource(); - InputPorts.Add(CodecOsdIn); - - // Set up output ports - OutputPorts.Add(Output1); - } - - /// - /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input - /// to enable routing - /// - private void CreateOsdSource() - { - OsdSource = new DummyRoutingInputsDevice(Key + "[osd]"); - DeviceManager.AddDevice(OsdSource); - var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn); - TieLineCollection.Default.Add(tl); - - //foreach(var input in Status.Video. - } - - /// - /// Starts the HTTP feedback server and syncronizes state of codec - /// - /// - public override bool CustomActivate() - { - CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCodecCommDebug", "0 for Off, 1 for on", - ConsoleAccessLevelEnum.AccessOperator); - if (!_props.DisablePhonebookAutoDownload) - { - CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"), - "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook", - ConsoleAccessLevelEnum.AccessOperator); - } - - CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings", - "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); - - var socket = Communication as ISocketStatus; - if (socket != null) - { - socket.ConnectionChange += socket_ConnectionChange; - } - - CommDebuggingIsOn = false; - - Communication.Connect(); - - CommunicationMonitor.Start(); - - return base.CustomActivate(); - } - - public void SetCommDebug(string s) - { - if (s == "1") - { - CommDebuggingIsOn = true; - Debug.Console(0, this, "Comm Debug Enabled."); - } - else - { - CommDebuggingIsOn = false; - Debug.Console(0, this, "Comm Debug Disabled."); - } - } - - private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) - { - Debug.Console(1, this, "Socket status change {0}", e.Client.ClientStatus); - if (e.Client.IsConnected) - { - } - else - { - _syncState.CodecDisconnected(); - PhonebookSyncState.CodecDisconnected(); - } - } - - public void SendText(string command) - { - if (CommDebuggingIsOn) - { - Debug.Console(1, this, "Sending: '{0}'", command); - } - - Communication.SendText(command + Delimiter); - } - - /// - /// Gathers responses and enqueues them. - /// - /// - /// - private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) - { - //if (CommDebuggingIsOn) - // Debug.Console(1, this, "Gathered: '{0}'", args.Text); - - _receiveQueue.Enqueue(args.Text); - - // If the receive thread has for some reason stopped, this will restart it - if (_receiveThread.ThreadState != Thread.eThreadStates.ThreadRunning) - { - _receiveThread.Start(); - } - } - - - /// - /// Runs in it's own thread to dequeue messages in the order they were received to be processed - /// - /// - private object ProcessQueue() - { - try - { - while (true) - { - var message = _receiveQueue.Dequeue(); - - ProcessMessage(message); - } - } - catch (Exception e) - { - Debug.Console(1, this, "Error Processing Queue: {0}", e); - } - - return null; - } - - - /// - /// Queues the initial queries to be sent upon connection - /// - private void SetUpSyncQueries() - { - // zStatus - _syncState.AddQueryToQueue("zStatus Call Status"); - _syncState.AddQueryToQueue("zStatus Audio Input Line"); - _syncState.AddQueryToQueue("zStatus Audio Output Line"); - _syncState.AddQueryToQueue("zStatus Video Camera Line"); - _syncState.AddQueryToQueue("zStatus Video Optimizable"); - _syncState.AddQueryToQueue("zStatus Capabilities"); - _syncState.AddQueryToQueue("zStatus Sharing"); - _syncState.AddQueryToQueue("zStatus CameraShare"); - _syncState.AddQueryToQueue("zStatus Call Layout"); - _syncState.AddQueryToQueue("zStatus Call ClosedCaption Available"); - _syncState.AddQueryToQueue("zStatus NumberOfScreens"); - - // zConfiguration - - _syncState.AddQueryToQueue("zConfiguration Call Sharing optimize_video_sharing"); - _syncState.AddQueryToQueue("zConfiguration Call Microphone Mute"); - _syncState.AddQueryToQueue("zConfiguration Call Camera Mute"); - _syncState.AddQueryToQueue("zConfiguration Audio Input SelectedId"); - _syncState.AddQueryToQueue("zConfiguration Audio Input is_sap_disabled"); - _syncState.AddQueryToQueue("zConfiguration Audio Input reduce_reverb"); - _syncState.AddQueryToQueue("zConfiguration Audio Input volume"); - _syncState.AddQueryToQueue("zConfiguration Audio Output selectedId"); - _syncState.AddQueryToQueue("zConfiguration Audio Output volume"); - _syncState.AddQueryToQueue("zConfiguration Video hide_conf_self_video"); - _syncState.AddQueryToQueue("zConfiguration Video Camera selectedId"); - _syncState.AddQueryToQueue("zConfiguration Video Camera Mirror"); - _syncState.AddQueryToQueue("zConfiguration Client appVersion"); - _syncState.AddQueryToQueue("zConfiguration Client deviceSystem"); - _syncState.AddQueryToQueue("zConfiguration Call Layout ShareThumb"); - _syncState.AddQueryToQueue("zConfiguration Call Layout Style"); - _syncState.AddQueryToQueue("zConfiguration Call Layout Size"); - _syncState.AddQueryToQueue("zConfiguration Call Layout Position"); - _syncState.AddQueryToQueue("zConfiguration Call Lock Enable"); - _syncState.AddQueryToQueue("zConfiguration Call MuteUserOnEntry Enable"); - _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption FontSize "); - _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption Visible"); - - // zCommand - - if (!_props.DisablePhonebookAutoDownload) - { - _syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512"); - } - - _syncState.AddQueryToQueue("zCommand Bookings List"); - _syncState.AddQueryToQueue("zCommand Call ListParticipants"); - _syncState.AddQueryToQueue("zCommand Call Info"); - - - _syncState.StartSync(); - } - - /// - /// Processes messages as they are dequeued - /// - /// - private void ProcessMessage(string message) - { - // Counts the curly braces - if (message.Contains("client_loop: send disconnect: Broken pipe")) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Error, - "Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected."); - - return; - } - - if (message.Contains('{')) - { - _jsonCurlyBraceCounter++; - } - - if (message.Contains('}')) - { - _jsonCurlyBraceCounter--; - } - - Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); - - if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter) - // Check for the beginning of a new JSON message - { - _jsonFeedbackMessageIsIncoming = true; - _jsonCurlyBraceCounter = 1; // reset the counter for each new message - - _jsonMessage = new StringBuilder(); - - _jsonMessage.Append(message); - - if (CommDebuggingIsOn) - { - Debug.Console(2, this, "Incoming JSON message..."); - } - - return; - } - if (_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "}" + Delimiter) - // Check for the end of a JSON message - { - _jsonMessage.Append(message); - - if (_jsonCurlyBraceCounter == 0) - { - _jsonFeedbackMessageIsIncoming = false; - - if (CommDebuggingIsOn) - { - Debug.Console(2, this, "Complete JSON Received:\n{0}", _jsonMessage.ToString()); - } - - // Forward the complete message to be deserialized - DeserializeResponse(_jsonMessage.ToString()); - } - - //JsonMessage = new StringBuilder(); - return; - } - - // NOTE: This must happen after the above conditions have been checked - // Append subsequent partial JSON fragments to the string builder - if (_jsonFeedbackMessageIsIncoming) - { - _jsonMessage.Append(message); - - //Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString()); - return; - } - - if (CommDebuggingIsOn) - { - Debug.Console(1, this, "Non-JSON response: '{0}'", message); - } - - _jsonCurlyBraceCounter = 0; // reset on non-JSON response - - if (!_syncState.InitialSyncComplete) - { - switch (message.Trim().ToLower()) // remove the whitespace - { - case "*r login successful": - { - _syncState.LoginMessageReceived(); - - // Fire up a thread to send the intial commands. - CrestronInvoke.BeginInvoke(o => - { - Thread.Sleep(100); - // disable echo of commands - SendText("echo off"); - Thread.Sleep(100); - // set feedback exclusions - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list"); - Thread.Sleep(100); - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list"); - Thread.Sleep(100); - - if (!_props.DisablePhonebookAutoDownload) - { - SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact"); - } - // switch to json format - SendText("format json"); - }); - - break; - } - } - } - } - - /// - /// Deserializes a JSON formatted response - /// - /// - private void DeserializeResponse(string response) - { - try - { - var trimmedResponse = response.Trim(); - - if (trimmedResponse.Length <= 0) - { - return; - } - - var message = JObject.Parse(trimmedResponse); - - var eType = - (eZoomRoomResponseType) - Enum.Parse(typeof (eZoomRoomResponseType), message["type"].Value(), true); - - var topKey = message["topKey"].Value(); - - var responseObj = message[topKey]; - - Debug.Console(1, "{0} Response Received. topKey: '{1}'\n{2}", eType, topKey, responseObj.ToString()); - - switch (eType) - { - case eZoomRoomResponseType.zConfiguration: - { - switch (topKey.ToLower()) - { - case "call": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Call); - - break; - } - case "audio": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Audio); - - break; - } - case "video": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Video); - - break; - } - case "client": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Client); - - break; - } - default: - { - break; - } - } - break; - } - case eZoomRoomResponseType.zCommand: - { - switch (topKey.ToLower()) - { - case "inforesult": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info); - break; - } - case "phonebooklistresult": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); - - if (!PhonebookSyncState.InitialSyncComplete) - { - PhonebookSyncState.InitialPhonebookFoldersReceived(); - PhonebookSyncState.PhonebookRootEntriesReceived(); - PhonebookSyncState.SetPhonebookHasFolders(false); - PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); - } - - var directoryResults = - zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); - - DirectoryRoot = directoryResults; - - _currentDirectoryResult = DirectoryRoot; - - OnDirectoryResultReturned(directoryResults); - - break; - } - case "listparticipantsresult": - { - Debug.Console(1, this, "JTokenType: {0}", responseObj.Type); - - switch (responseObj.Type) - { - case JTokenType.Array: - Status.Call.Participants = - JsonConvert.DeserializeObject>( - responseObj.ToString()); - break; - case JTokenType.Object: - { - // this is a single participant event notification - - var participant = - JsonConvert.DeserializeObject( - responseObj.ToString()); - - if (participant != null) - { - switch (participant.Event) - { - case "ZRCUserChangedEventUserInfoUpdated": - case "ZRCUserChangedEventLeftMeeting": - { - var existingParticipant = - Status.Call.Participants.FirstOrDefault( - p => p.UserId.Equals(participant.UserId)); - - if (existingParticipant != null) - { - switch (participant.Event) - { - case "ZRCUserChangedEventLeftMeeting": - Status.Call.Participants.Remove(existingParticipant); - break; - case "ZRCUserChangedEventUserInfoUpdated": - JsonConvert.PopulateObject(responseObj.ToString(), - existingParticipant); - break; - } - } - } - break; - case "ZRCUserChangedEventJoinedMeeting": - Status.Call.Participants.Add(participant); - break; - } - } - } - break; - } - - var participants = - zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult( - Status.Call.Participants); - - Participants.CurrentParticipants = participants; - - PrintCurrentCallParticipants(); - - break; - } - default: - { - break; - } - } - break; - } - case eZoomRoomResponseType.zEvent: - { - switch (topKey.ToLower()) - { - case "phonebook": - { - if (responseObj["Updated Contact"] != null) - { - var updatedContact = - JsonConvert.DeserializeObject( - responseObj["Updated Contact"].ToString()); - - var existingContact = - Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid)); - - if (existingContact != null) - { - // Update existing contact - JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(), - existingContact); - } - } - else if (responseObj["Added Contact"] != null) - { - var jToken = responseObj["Updated Contact"]; - if (jToken != null) - { - var newContact = - JsonConvert.DeserializeObject( - jToken.ToString()); - - // Add a new contact - Status.Phonebook.Contacts.Add(newContact); - } - } - - break; - } - case "bookingslistresult": - { - if (!_syncState.InitialSyncComplete) - { - _syncState.LastQueryResponseReceived(); - } - - var codecBookings = JsonConvert.DeserializeObject>( - responseObj.ToString()); - - if (codecBookings != null && codecBookings.Count > 0) - { - CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( - codecBookings, CodecSchedule.MeetingWarningMinutes); - } - - break; - } - case "bookings updated": - { - GetBookings(); - - break; - } - case "sharingstate": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing); - - SetLayout(); - - break; - } - case "incomingcallindication": - { - var incomingCall = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (incomingCall != null) - { - var newCall = new CodecActiveCallItem - { - Direction = eCodecCallDirection.Incoming, - Status = eCodecCallStatus.Ringing, - Type = eCodecCallType.Unknown, - Name = incomingCall.callerName, - Id = incomingCall.callerJID - }; - - ActiveCalls.Add(newCall); - - OnCallStatusChange(newCall); - } - - break; - } - case "treatedincomingcallindication": - { - var incomingCall = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (incomingCall != null) - { - var existingCall = - ActiveCalls.FirstOrDefault(c => c.Id.Equals(incomingCall.callerJID)); - - if (existingCall != null) - { - existingCall.Status = !incomingCall.accepted - ? eCodecCallStatus.Disconnected - : eCodecCallStatus.Connecting; - - OnCallStatusChange(existingCall); - } - - UpdateCallStatus(); - } - - break; - } - case "calldisconnect": - { - var disconnectEvent = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (disconnectEvent.Successful) - { - if (ActiveCalls.Count > 0) - { - var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); - - if (activeCall != null) - { - activeCall.Status = eCodecCallStatus.Disconnected; - - OnCallStatusChange(activeCall); - } - } - var emptyList = new List(); - Participants.CurrentParticipants = emptyList; - } - - UpdateCallStatus(); - break; - } - case "callconnecterror": - { - UpdateCallStatus(); - break; - } - case "videounmuterequest": - { - // TODO: notify room of a request to unmute video - break; - } - case "meetingneedspassword": - { - // TODO: notify user to enter a password - break; - } - case "needwaitforhost": - { - var needWait = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (needWait.Wait) - { - // TODO: notify user to wait for host - } - - break; - } - case "openvideofailforhoststop": - { - // TODO: notify user that host has disabled unmuting video - break; - } - case "updatedcallrecordinfo": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.CallRecordInfo); - - break; - } - case "phonecallstatus": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall); - break; - } - case "pinstatusofscreennotification": - { - var status = responseObj.ToObject(); - - var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); - - if (participant != null) - { - participant.IsPinnedFb = true; - participant.ScreenIndexIsPinnedToFb = status.ScreenIndex; - } - else - { - participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); - - if (participant == null) - { - Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); - return; - } - else - { - participant.IsPinnedFb = false; - participant.ScreenIndexIsPinnedToFb = -1; - } - } - - // fire the event as we've modified the participants list - Participants.OnParticipantsChanged(); - - break; - } - default: - { - break; - } - } - break; - } - case eZoomRoomResponseType.zStatus: - { - switch (topKey.ToLower()) - { - case "login": - { - _syncState.LoginMessageReceived(); - - if (!_syncState.InitialQueryMessagesWereSent) - { - SetUpSyncQueries(); - } - - JsonConvert.PopulateObject(responseObj.ToString(), Status.Login); - - break; - } - case "systemunit": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.SystemUnit); - - break; - } - case "call": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call); - - UpdateCallStatus(); - - break; - } - case "capabilities": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Capabilities); - break; - } - case "sharing": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Sharing); - - break; - } - case "numberofscreens": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.NumberOfScreens); - break; - } - case "video": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Video); - break; - } - case "camerashare": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.CameraShare); - break; - } - case "layout": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Layout); - break; - } - case "audio input line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioInputs); - break; - } - case "audio output line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioOuputs); - break; - } - case "video camera line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Cameras); - - if (!_syncState.CamerasHaveBeenSetUp) - { - SetUpCameras(); - } - - break; - } - default: - { - break; - } - } - - break; - } - default: - { - Debug.Console(1, "Unknown Response Type:"); - break; - } - } - } - catch (Exception ex) - { - Debug.Console(1, this, "Error Deserializing feedback: {0}", ex); - } - } - - private void SetLayout() - { - if (!_props.AutoDefaultLayouts) return; - - if ( - (Status.Call.Sharing.State == zEvent.eSharingState.Receiving || - Status.Call.Sharing.State == zEvent.eSharingState.Sending)) - { - SendText(String.Format("zconfiguration call layout style: {0}", - _props.DefaultSharingLayout)); - } - else - { - SendText(String.Format("zconfiguration call layout style: {0}", - _props.DefaultCallLayout)); - } - } - - public void PrintCurrentCallParticipants() - { - if (Debug.Level <= 0) - { - return; - } - - Debug.Console(1, this, "****************************Call Participants***************************"); - foreach (var participant in Participants.CurrentParticipants) - { - Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name, - participant.AudioMuteFb, participant.IsHost); - } - Debug.Console(1, this, "************************************************************************"); - } - - /// - /// Retrieves bookings list - /// - private void GetBookings() - { - SendText("zCommand Bookings List"); - } - - - /// - /// Updates the current call status - /// - private void UpdateCallStatus() - { - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); - - if (Status.Call != null) - { - var callStatus = Status.Call.Status; - - // If not currently in a meeting, intialize the call object - if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING) - { - Debug.Console(1, this, "Creating new Status.Call object"); - Status.Call = new zStatus.Call {Status = callStatus}; - - SetUpCallFeedbackActions(); - } - - if (ActiveCalls.Count == 0) - { - if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING || - callStatus == zStatus.eCallStatus.IN_MEETING) - { - var newStatus = eCodecCallStatus.Unknown; - - switch (callStatus) - { - case zStatus.eCallStatus.CONNECTING_MEETING: - newStatus = eCodecCallStatus.Connecting; - break; - case zStatus.eCallStatus.IN_MEETING: - newStatus = eCodecCallStatus.Connected; - break; - } - - var newCall = new CodecActiveCallItem {Status = newStatus}; - - ActiveCalls.Add(newCall); - - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); - - OnCallStatusChange(newCall); - } - } - else - { - var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); - - switch (callStatus) - { - case zStatus.eCallStatus.IN_MEETING: - existingCall.Status = eCodecCallStatus.Connected; - break; - case zStatus.eCallStatus.NOT_IN_MEETING: - existingCall.Status = eCodecCallStatus.Disconnected; - break; - } - - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); - - OnCallStatusChange(existingCall); - } - } - - Debug.Console(1, this, "****************************Active Calls*********************************"); - - // Clean up any disconnected calls left in the list - for (int i = 0; i < ActiveCalls.Count; i++) - { - var call = ActiveCalls[i]; - - Debug.Console(1, this, - @"Name: {0} + public Stack DirectoryBrowseHistoryStack { get; private set; } + + #endregion + + #region IHasScheduleAwareness Members + + public CodecScheduleAwareness CodecSchedule { get; private set; } + + public void GetSchedule() + { + GetBookings(); + } + + #endregion + + #region IRouting Members + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + ExecuteSwitch(inputSelector); + } + + #endregion + + private void SyncState_InitialSyncCompleted(object sender, EventArgs e) + { + SetUpRouting(); + + SetIsReady(); + } + + private void SetUpCallFeedbackActions() + { + Status.Call.Sharing.PropertyChanged += (o, a) => + { + if (a.PropertyName == "State") + { + SharingContentIsOnFeedback.FireUpdate(); + ReceivingContent.FireUpdate(); + } + }; + + Status.Call.PropertyChanged += (o, a) => + { + if (a.PropertyName == "Info") + { + Debug.Console(1, this, "Updating Call Status"); + UpdateCallStatus(); + } + }; + } + + /// + /// Subscribes to the PropertyChanged events on the state objects and fires the corresponding feedbacks. + /// + private void SetUpFeedbackActions() + { + Configuration.Audio.Output.PropertyChanged += (o, a) => + { + if (a.PropertyName == "Volume") + { + VolumeLevelFeedback.FireUpdate(); + MuteFeedback.FireUpdate(); + } + }; + + Configuration.Call.Microphone.PropertyChanged += (o, a) => + { + if (a.PropertyName == "Mute") + { + PrivacyModeIsOnFeedback.FireUpdate(); + } + }; + + Configuration.Video.PropertyChanged += (o, a) => + { + if (a.PropertyName == "HideConfSelfVideo") + { + SelfviewIsOnFeedback.FireUpdate(); + } + }; + Configuration.Video.Camera.PropertyChanged += (o, a) => + { + if (a.PropertyName == "SelectedId") + { + SelectCamera(Configuration.Video.Camera.SelectedId); + // this will in turn fire the affected feedbacks + } + }; + + Configuration.Call.Camera.PropertyChanged += (o, a) => + { + Debug.Console(1, this, "Configuration.Call.Camera.PropertyChanged: {0}", a.PropertyName); + + if (a.PropertyName != "Mute") return; + + CameraIsOffFeedback.FireUpdate(); + CameraAutoModeIsOnFeedback.FireUpdate(); + }; + + Configuration.Call.Layout.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "Position": + { + ComputeSelfviewPipStatus(); + + SelfviewPipPositionFeedback.FireUpdate(); + + break; + } + case "ShareThumb": + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } + case "Style": + { + LocalLayoutFeedback.FireUpdate(); + break; + } + + } + }; + + Status.Call.Sharing.PropertyChanged += (o, a) => + { + if (a.PropertyName == "State") + { + SharingContentIsOnFeedback.FireUpdate(); + ReceivingContent.FireUpdate(); + } + }; + + Status.Call.PropertyChanged += (o, a) => + { + if (a.PropertyName == "Info") + { + Debug.Console(1, this, "Updating Call Status"); + UpdateCallStatus(); + } + }; + + Status.Sharing.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "dispState": + SharingSourceFeedback.FireUpdate(); + break; + case "password": + break; + } + }; + + Status.PhoneCall.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "IsIncomingCall": + Debug.Console(1, this, "Incoming Phone Call: {0}", Status.PhoneCall.IsIncomingCall); + break; + case "PeerDisplayName": + Debug.Console(1, this, "Peer Display Name: {0}", Status.PhoneCall.PeerDisplayName); + CallerIdNameFeedback.FireUpdate(); + break; + case "PeerNumber": + Debug.Console(1, this, "Peer Number: {0}", Status.PhoneCall.PeerNumber); + CallerIdNumberFeedback.FireUpdate(); + break; + case "OffHook": + Debug.Console(1, this, "Phone is OffHook: {0}", Status.PhoneCall.OffHook); + PhoneOffHookFeedback.FireUpdate(); + break; + } + }; + + Status.Layout.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "can_Switch_Speaker_View": + case "can_Switch_Wall_View": + case "can_Switch_Share_On_All_Screens": + { + ComputeAvailableLayouts(); + break; + } + case "is_In_First_Page": + { + LayoutViewIsOnFirstPageFeedback.FireUpdate(); + break; + } + case "is_In_Last_Page": + { + LayoutViewIsOnLastPageFeedback.FireUpdate(); + break; + } + //case "video_type": + // { + // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style + // LocalLayoutFeedback.FireUpdate(); + // break; + // } + } + }; + + Status.NumberOfScreens.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "NumberOfScreens": + { + NumberOfScreensFeedback.FireUpdate(); + break; + } + } + }; + } + + private void SetUpDirectory() + { + DirectoryRoot = new CodecDirectory(); + + DirectoryBrowseHistory = new List(); + DirectoryBrowseHistoryStack = new Stack(); + + CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot); + + CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + } + + private void SetUpRouting() + { + // Set up input ports + CreateOsdSource(); + InputPorts.Add(CodecOsdIn); + + // Set up output ports + OutputPorts.Add(Output1); + } + + /// + /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input + /// to enable routing + /// + private void CreateOsdSource() + { + OsdSource = new DummyRoutingInputsDevice(Key + "[osd]"); + DeviceManager.AddDevice(OsdSource); + var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn); + TieLineCollection.Default.Add(tl); + + //foreach(var input in Status.Video. + } + + /// + /// Starts the HTTP feedback server and syncronizes state of codec + /// + /// + public override bool CustomActivate() + { + CrestronConsole.AddNewConsoleCommand(SetCommDebug, "SetCodecCommDebug", "0 for Off, 1 for on", + ConsoleAccessLevelEnum.AccessOperator); + if (!_props.DisablePhonebookAutoDownload) + { + CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"), + "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook", + ConsoleAccessLevelEnum.AccessOperator); + } + + CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings", + "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); + + var socket = Communication as ISocketStatus; + if (socket != null) + { + socket.ConnectionChange += socket_ConnectionChange; + } + + CommDebuggingIsOn = false; + + Communication.Connect(); + + CommunicationMonitor.Start(); + + return base.CustomActivate(); + } + + public void SetCommDebug(string s) + { + if (s == "1") + { + CommDebuggingIsOn = true; + Debug.Console(0, this, "Comm Debug Enabled."); + } + else + { + CommDebuggingIsOn = false; + Debug.Console(0, this, "Comm Debug Disabled."); + } + } + + private void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) + { + Debug.Console(1, this, "Socket status change {0}", e.Client.ClientStatus); + if (e.Client.IsConnected) + { + } + else + { + _syncState.CodecDisconnected(); + PhonebookSyncState.CodecDisconnected(); + } + } + + public void SendText(string command) + { + if (CommDebuggingIsOn) + { + Debug.Console(1, this, "Sending: '{0}'", command); + } + + Communication.SendText(command + Delimiter); + } + + /// + /// Gathers responses and enqueues them. + /// + /// + /// + private void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args) + { + //if (CommDebuggingIsOn) + // Debug.Console(1, this, "Gathered: '{0}'", args.Text); + + _receiveQueue.Enqueue(args.Text); + + // If the receive thread has for some reason stopped, this will restart it + if (_receiveThread.ThreadState != Thread.eThreadStates.ThreadRunning) + { + _receiveThread.Start(); + } + } + + + /// + /// Runs in it's own thread to dequeue messages in the order they were received to be processed + /// + /// + private object ProcessQueue() + { + try + { + while (true) + { + var message = _receiveQueue.Dequeue(); + + ProcessMessage(message); + } + } + catch (Exception e) + { + Debug.Console(1, this, "Error Processing Queue: {0}", e); + } + + return null; + } + + + /// + /// Queues the initial queries to be sent upon connection + /// + private void SetUpSyncQueries() + { + // zStatus + _syncState.AddQueryToQueue("zStatus Call Status"); + _syncState.AddQueryToQueue("zStatus Audio Input Line"); + _syncState.AddQueryToQueue("zStatus Audio Output Line"); + _syncState.AddQueryToQueue("zStatus Video Camera Line"); + _syncState.AddQueryToQueue("zStatus Video Optimizable"); + _syncState.AddQueryToQueue("zStatus Capabilities"); + _syncState.AddQueryToQueue("zStatus Sharing"); + _syncState.AddQueryToQueue("zStatus CameraShare"); + _syncState.AddQueryToQueue("zStatus Call Layout"); + _syncState.AddQueryToQueue("zStatus Call ClosedCaption Available"); + _syncState.AddQueryToQueue("zStatus NumberOfScreens"); + + // zConfiguration + + _syncState.AddQueryToQueue("zConfiguration Call Sharing optimize_video_sharing"); + _syncState.AddQueryToQueue("zConfiguration Call Microphone Mute"); + _syncState.AddQueryToQueue("zConfiguration Call Camera Mute"); + _syncState.AddQueryToQueue("zConfiguration Audio Input SelectedId"); + _syncState.AddQueryToQueue("zConfiguration Audio Input is_sap_disabled"); + _syncState.AddQueryToQueue("zConfiguration Audio Input reduce_reverb"); + _syncState.AddQueryToQueue("zConfiguration Audio Input volume"); + _syncState.AddQueryToQueue("zConfiguration Audio Output selectedId"); + _syncState.AddQueryToQueue("zConfiguration Audio Output volume"); + _syncState.AddQueryToQueue("zConfiguration Video hide_conf_self_video"); + _syncState.AddQueryToQueue("zConfiguration Video Camera selectedId"); + _syncState.AddQueryToQueue("zConfiguration Video Camera Mirror"); + _syncState.AddQueryToQueue("zConfiguration Client appVersion"); + _syncState.AddQueryToQueue("zConfiguration Client deviceSystem"); + _syncState.AddQueryToQueue("zConfiguration Call Layout ShareThumb"); + _syncState.AddQueryToQueue("zConfiguration Call Layout Style"); + _syncState.AddQueryToQueue("zConfiguration Call Layout Size"); + _syncState.AddQueryToQueue("zConfiguration Call Layout Position"); + _syncState.AddQueryToQueue("zConfiguration Call Lock Enable"); + _syncState.AddQueryToQueue("zConfiguration Call MuteUserOnEntry Enable"); + _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption FontSize "); + _syncState.AddQueryToQueue("zConfiguration Call ClosedCaption Visible"); + + // zCommand + + if (!_props.DisablePhonebookAutoDownload) + { + _syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512"); + } + + _syncState.AddQueryToQueue("zCommand Bookings List"); + _syncState.AddQueryToQueue("zCommand Call ListParticipants"); + _syncState.AddQueryToQueue("zCommand Call Info"); + + + _syncState.StartSync(); + } + + /// + /// Processes messages as they are dequeued + /// + /// + private void ProcessMessage(string message) + { + // Counts the curly braces + if (message.Contains("client_loop: send disconnect: Broken pipe")) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, + "Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected."); + + return; + } + + if (message.Contains('{')) + { + _jsonCurlyBraceCounter++; + } + + if (message.Contains('}')) + { + _jsonCurlyBraceCounter--; + } + + Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); + + if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter) + // Check for the beginning of a new JSON message + { + _jsonFeedbackMessageIsIncoming = true; + _jsonCurlyBraceCounter = 1; // reset the counter for each new message + + _jsonMessage = new StringBuilder(); + + _jsonMessage.Append(message); + + if (CommDebuggingIsOn) + { + Debug.Console(2, this, "Incoming JSON message..."); + } + + return; + } + if (_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "}" + Delimiter) + // Check for the end of a JSON message + { + _jsonMessage.Append(message); + + if (_jsonCurlyBraceCounter == 0) + { + _jsonFeedbackMessageIsIncoming = false; + + if (CommDebuggingIsOn) + { + Debug.Console(2, this, "Complete JSON Received:\n{0}", _jsonMessage.ToString()); + } + + // Forward the complete message to be deserialized + DeserializeResponse(_jsonMessage.ToString()); + } + + //JsonMessage = new StringBuilder(); + return; + } + + // NOTE: This must happen after the above conditions have been checked + // Append subsequent partial JSON fragments to the string builder + if (_jsonFeedbackMessageIsIncoming) + { + _jsonMessage.Append(message); + + //Debug.Console(1, this, "Building JSON:\n{0}", JsonMessage.ToString()); + return; + } + + if (CommDebuggingIsOn) + { + Debug.Console(1, this, "Non-JSON response: '{0}'", message); + } + + _jsonCurlyBraceCounter = 0; // reset on non-JSON response + + if (!_syncState.InitialSyncComplete) + { + switch (message.Trim().ToLower()) // remove the whitespace + { + case "*r login successful": + { + _syncState.LoginMessageReceived(); + + // Fire up a thread to send the intial commands. + CrestronInvoke.BeginInvoke(o => + { + Thread.Sleep(100); + // disable echo of commands + SendText("echo off"); + Thread.Sleep(100); + // set feedback exclusions + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list"); + Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list"); + Thread.Sleep(100); + + if (!_props.DisablePhonebookAutoDownload) + { + SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact"); + } + // switch to json format + SendText("format json"); + }); + + break; + } + } + } + } + + /// + /// Deserializes a JSON formatted response + /// + /// + private void DeserializeResponse(string response) + { + try + { + var trimmedResponse = response.Trim(); + + if (trimmedResponse.Length <= 0) + { + return; + } + + var message = JObject.Parse(trimmedResponse); + + var eType = + (eZoomRoomResponseType) + Enum.Parse(typeof(eZoomRoomResponseType), message["type"].Value(), true); + + var topKey = message["topKey"].Value(); + + var responseObj = message[topKey]; + + Debug.Console(1, "{0} Response Received. topKey: '{1}'\n{2}", eType, topKey, responseObj.ToString()); + + switch (eType) + { + case eZoomRoomResponseType.zConfiguration: + { + switch (topKey.ToLower()) + { + case "call": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Call); + + break; + } + case "audio": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Audio); + + break; + } + case "video": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Video); + + break; + } + case "client": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Client); + + break; + } + default: + { + break; + } + } + break; + } + case eZoomRoomResponseType.zCommand: + { + switch (topKey.ToLower()) + { + case "inforesult": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info); + break; + } + case "phonebooklistresult": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); + + if (!PhonebookSyncState.InitialSyncComplete) + { + PhonebookSyncState.InitialPhonebookFoldersReceived(); + PhonebookSyncState.PhonebookRootEntriesReceived(); + PhonebookSyncState.SetPhonebookHasFolders(false); + PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); + } + + var directoryResults = + zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); + + DirectoryRoot = directoryResults; + + _currentDirectoryResult = DirectoryRoot; + + OnDirectoryResultReturned(directoryResults); + + break; + } + case "listparticipantsresult": + { + Debug.Console(1, this, "JTokenType: {0}", responseObj.Type); + + switch (responseObj.Type) + { + case JTokenType.Array: + Status.Call.Participants = + JsonConvert.DeserializeObject>( + responseObj.ToString()); + break; + case JTokenType.Object: + { + // this is a single participant event notification + + var participant = + JsonConvert.DeserializeObject( + responseObj.ToString()); + + if (participant != null) + { + switch (participant.Event) + { + case "ZRCUserChangedEventUserInfoUpdated": + case "ZRCUserChangedEventLeftMeeting": + { + var existingParticipant = + Status.Call.Participants.FirstOrDefault( + p => p.UserId.Equals(participant.UserId)); + + if (existingParticipant != null) + { + switch (participant.Event) + { + case "ZRCUserChangedEventLeftMeeting": + Status.Call.Participants.Remove(existingParticipant); + break; + case "ZRCUserChangedEventUserInfoUpdated": + JsonConvert.PopulateObject(responseObj.ToString(), + existingParticipant); + break; + } + } + } + break; + case "ZRCUserChangedEventJoinedMeeting": + Status.Call.Participants.Add(participant); + break; + } + } + } + break; + } + + var participants = + zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult( + Status.Call.Participants); + + Participants.CurrentParticipants = participants; + + PrintCurrentCallParticipants(); + + break; + } + default: + { + break; + } + } + break; + } + case eZoomRoomResponseType.zEvent: + { + switch (topKey.ToLower()) + { + case "phonebook": + { + if (responseObj["Updated Contact"] != null) + { + var updatedContact = + JsonConvert.DeserializeObject( + responseObj["Updated Contact"].ToString()); + + var existingContact = + Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid)); + + if (existingContact != null) + { + // Update existing contact + JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(), + existingContact); + } + } + else if (responseObj["Added Contact"] != null) + { + var jToken = responseObj["Updated Contact"]; + if (jToken != null) + { + var newContact = + JsonConvert.DeserializeObject( + jToken.ToString()); + + // Add a new contact + Status.Phonebook.Contacts.Add(newContact); + } + } + + break; + } + case "bookingslistresult": + { + if (!_syncState.InitialSyncComplete) + { + _syncState.LastQueryResponseReceived(); + } + + var codecBookings = JsonConvert.DeserializeObject>( + responseObj.ToString()); + + if (codecBookings != null && codecBookings.Count > 0) + { + CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( + codecBookings, CodecSchedule.MeetingWarningMinutes); + } + + break; + } + case "bookings updated": + { + GetBookings(); + + break; + } + case "sharingstate": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing); + + SetLayout(); + + break; + } + case "incomingcallindication": + { + var incomingCall = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (incomingCall != null) + { + var newCall = new CodecActiveCallItem + { + Direction = eCodecCallDirection.Incoming, + Status = eCodecCallStatus.Ringing, + Type = eCodecCallType.Unknown, + Name = incomingCall.callerName, + Id = incomingCall.callerJID + }; + + ActiveCalls.Add(newCall); + + OnCallStatusChange(newCall); + } + + break; + } + case "treatedincomingcallindication": + { + var incomingCall = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (incomingCall != null) + { + var existingCall = + ActiveCalls.FirstOrDefault(c => c.Id.Equals(incomingCall.callerJID)); + + if (existingCall != null) + { + existingCall.Status = !incomingCall.accepted + ? eCodecCallStatus.Disconnected + : eCodecCallStatus.Connecting; + + OnCallStatusChange(existingCall); + } + + UpdateCallStatus(); + } + + break; + } + case "calldisconnect": + { + var disconnectEvent = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (disconnectEvent.Successful) + { + if (ActiveCalls.Count > 0) + { + var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); + + if (activeCall != null) + { + activeCall.Status = eCodecCallStatus.Disconnected; + + OnCallStatusChange(activeCall); + } + } + var emptyList = new List(); + Participants.CurrentParticipants = emptyList; + } + + UpdateCallStatus(); + break; + } + case "callconnecterror": + { + UpdateCallStatus(); + break; + } + case "videounmuterequest": + { + // TODO: notify room of a request to unmute video + break; + } + case "meetingneedspassword": + { + // TODO: notify user to enter a password + break; + } + case "needwaitforhost": + { + var needWait = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (needWait.Wait) + { + // TODO: notify user to wait for host + } + + break; + } + case "openvideofailforhoststop": + { + // TODO: notify user that host has disabled unmuting video + break; + } + case "updatedcallrecordinfo": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.CallRecordInfo); + + break; + } + case "phonecallstatus": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall); + break; + } + case "pinstatusofscreennotification": + { + var status = responseObj.ToObject(); + + var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); + + if (participant != null) + { + participant.IsPinnedFb = true; + participant.ScreenIndexIsPinnedToFb = status.ScreenIndex; + } + else + { + participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + if (participant == null) + { + Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); + return; + } + else + { + participant.IsPinnedFb = false; + participant.ScreenIndexIsPinnedToFb = -1; + } + } + + // fire the event as we've modified the participants list + Participants.OnParticipantsChanged(); + + break; + } + default: + { + break; + } + } + break; + } + case eZoomRoomResponseType.zStatus: + { + switch (topKey.ToLower()) + { + case "login": + { + _syncState.LoginMessageReceived(); + + if (!_syncState.InitialQueryMessagesWereSent) + { + SetUpSyncQueries(); + } + + JsonConvert.PopulateObject(responseObj.ToString(), Status.Login); + + break; + } + case "systemunit": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.SystemUnit); + + break; + } + case "call": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call); + + UpdateCallStatus(); + + break; + } + case "capabilities": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Capabilities); + break; + } + case "sharing": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Sharing); + + break; + } + case "numberofscreens": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.NumberOfScreens); + break; + } + case "video": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Video); + break; + } + case "camerashare": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.CameraShare); + break; + } + case "layout": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Layout); + break; + } + case "audio input line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioInputs); + break; + } + case "audio output line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioOuputs); + break; + } + case "video camera line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Cameras); + + if (!_syncState.CamerasHaveBeenSetUp) + { + SetUpCameras(); + } + + break; + } + default: + { + break; + } + } + + break; + } + default: + { + Debug.Console(1, "Unknown Response Type:"); + break; + } + } + } + catch (Exception ex) + { + Debug.Console(1, this, "Error Deserializing feedback: {0}", ex); + } + } + + private void SetLayout() + { + if (!_props.AutoDefaultLayouts) return; + + if ( + (Status.Call.Sharing.State == zEvent.eSharingState.Receiving || + Status.Call.Sharing.State == zEvent.eSharingState.Sending)) + { + SendText(String.Format("zconfiguration call layout style: {0}", + _props.DefaultSharingLayout)); + } + else + { + SendText(String.Format("zconfiguration call layout style: {0}", + _props.DefaultCallLayout)); + } + } + + public void PrintCurrentCallParticipants() + { + if (Debug.Level <= 0) + { + return; + } + + Debug.Console(1, this, "****************************Call Participants***************************"); + foreach (var participant in Participants.CurrentParticipants) + { + Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name, + participant.AudioMuteFb, participant.IsHost); + } + Debug.Console(1, this, "************************************************************************"); + } + + /// + /// Retrieves bookings list + /// + private void GetBookings() + { + SendText("zCommand Bookings List"); + } + + + /// + /// Updates the current call status + /// + private void UpdateCallStatus() + { + Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", + Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + + if (Status.Call != null) + { + var callStatus = Status.Call.Status; + + // If not currently in a meeting, intialize the call object + if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING) + { + Debug.Console(1, this, "Creating new Status.Call object"); + Status.Call = new zStatus.Call { Status = callStatus }; + + SetUpCallFeedbackActions(); + } + + if (ActiveCalls.Count == 0) + { + if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING || + callStatus == zStatus.eCallStatus.IN_MEETING) + { + var newStatus = eCodecCallStatus.Unknown; + + switch (callStatus) + { + case zStatus.eCallStatus.CONNECTING_MEETING: + newStatus = eCodecCallStatus.Connecting; + break; + case zStatus.eCallStatus.IN_MEETING: + newStatus = eCodecCallStatus.Connected; + break; + } + + var newCall = new CodecActiveCallItem { Status = newStatus }; + + ActiveCalls.Add(newCall); + + Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", + Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + + OnCallStatusChange(newCall); + } + } + else + { + var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); + + switch (callStatus) + { + case zStatus.eCallStatus.IN_MEETING: + existingCall.Status = eCodecCallStatus.Connected; + break; + case zStatus.eCallStatus.NOT_IN_MEETING: + existingCall.Status = eCodecCallStatus.Disconnected; + break; + } + + Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", + Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + + OnCallStatusChange(existingCall); + } + } + + Debug.Console(1, this, "****************************Active Calls*********************************"); + + // Clean up any disconnected calls left in the list + for (int i = 0; i < ActiveCalls.Count; i++) + { + var call = ActiveCalls[i]; + + Debug.Console(1, this, + @"Name: {0} ID: {1} IsActive: {2} Status: {3} Direction: {4}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction); - if (!call.IsActiveCall) - { - Debug.Console(1, this, "******Removing Inactive Call: {0}******", call.Name); - ActiveCalls.Remove(call); - } - } - Debug.Console(1, this, "**************************************************************************"); + if (!call.IsActiveCall) + { + Debug.Console(1, this, "******Removing Inactive Call: {0}******", call.Name); + ActiveCalls.Remove(call); + } + } + Debug.Console(1, this, "**************************************************************************"); - //clear participants list after call cleanup - if (ActiveCalls.Count == 0) - { - Participants.CurrentParticipants = new List(); - } - } + //clear participants list after call cleanup + if (ActiveCalls.Count == 0) + { + Participants.CurrentParticipants = new List(); + } + } - protected override void OnCallStatusChange(CodecActiveCallItem item) - { - base.OnCallStatusChange(item); + protected override void OnCallStatusChange(CodecActiveCallItem item) + { + base.OnCallStatusChange(item); - Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}", + Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); - if (_props.AutoDefaultLayouts) - { - SetLayout(); - } - } + if (_props.AutoDefaultLayouts) + { + SetLayout(); + } + } - public override void StartSharing() - { - SendText("zCommand Call Sharing HDMI Start"); - } + public override void StartSharing() + { + SendText("zCommand Call Sharing HDMI Start"); + } - /// - /// Stops sharing the current presentation - /// - public override void StopSharing() - { - SendText("zCommand Call Sharing Disconnect"); - } + /// + /// Stops sharing the current presentation + /// + public override void StopSharing() + { + SendText("zCommand Call Sharing Disconnect"); + } - public override void PrivacyModeOn() - { - SendText("zConfiguration Call Microphone Mute: on"); - } + public override void PrivacyModeOn() + { + SendText("zConfiguration Call Microphone Mute: on"); + } - public override void PrivacyModeOff() - { - SendText("zConfiguration Call Microphone Mute: off"); - } + public override void PrivacyModeOff() + { + SendText("zConfiguration Call Microphone Mute: off"); + } - public override void PrivacyModeToggle() - { - if (PrivacyModeIsOnFeedback.BoolValue) - { - PrivacyModeOff(); - } - else - { - PrivacyModeOn(); - } - } + public override void PrivacyModeToggle() + { + if (PrivacyModeIsOnFeedback.BoolValue) + { + PrivacyModeOff(); + } + else + { + PrivacyModeOn(); + } + } - public override void MuteOff() - { - SetVolume((ushort) _previousVolumeLevel); - } + public override void MuteOff() + { + SetVolume((ushort)_previousVolumeLevel); + } - public override void MuteOn() - { - _previousVolumeLevel = Configuration.Audio.Output.Volume; // Store the previous level for recall + public override void MuteOn() + { + _previousVolumeLevel = Configuration.Audio.Output.Volume; // Store the previous level for recall - SetVolume(0); - } + SetVolume(0); + } - public override void MuteToggle() - { - if (MuteFeedback.BoolValue) - { - MuteOff(); - } - else - { - MuteOn(); - } - } + public override void MuteToggle() + { + if (MuteFeedback.BoolValue) + { + MuteOff(); + } + else + { + MuteOn(); + } + } - /// - /// Increments the voluem - /// - /// - public override void VolumeUp(bool pressRelease) - { - // TODO: Implment volume decrement that calls SetVolume() - } + /// + /// Increments the voluem + /// + /// + public override void VolumeUp(bool pressRelease) + { + // TODO: Implment volume decrement that calls SetVolume() + } - /// - /// Decrements the volume - /// - /// - public override void VolumeDown(bool pressRelease) - { - // TODO: Implment volume decrement that calls SetVolume() - } + /// + /// Decrements the volume + /// + /// + public override void VolumeDown(bool pressRelease) + { + // TODO: Implment volume decrement that calls SetVolume() + } - /// - /// Scales the level and sets the codec to the specified level within its range - /// - /// level from slider (0-65535 range) - public override void SetVolume(ushort level) - { - var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0); - SendText(string.Format("zConfiguration Audio Output volume: {0}", scaledLevel)); - } + /// + /// Scales the level and sets the codec to the specified level within its range + /// + /// level from slider (0-65535 range) + public override void SetVolume(ushort level) + { + var scaledLevel = CrestronEnvironment.ScaleWithLimits(level, 65535, 0, 100, 0); + SendText(string.Format("zConfiguration Audio Output volume: {0}", scaledLevel)); + } - /// - /// Recalls the default volume on the codec - /// - public void VolumeSetToDefault() - { - } + /// + /// Recalls the default volume on the codec + /// + public void VolumeSetToDefault() + { + } - /// - /// - /// - public override void StandbyActivate() - { - // No corresponding function on device - } + /// + /// + /// + public override void StandbyActivate() + { + // No corresponding function on device + } - /// - /// - /// - public override void StandbyDeactivate() - { - // No corresponding function on device - } + /// + /// + /// + public override void StandbyDeactivate() + { + // No corresponding function on device + } - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new ZoomRoomJoinMap(joinStart); + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new ZoomRoomJoinMap(joinStart); - var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - if (customJoins != null) - { - joinMap.SetCustomJoinData(customJoins); - } + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } - LinkVideoCodecToApi(this, trilist, joinMap); + LinkVideoCodecToApi(this, trilist, joinMap); - LinkZoomRoomToApi(trilist, joinMap); - } + LinkZoomRoomToApi(trilist, joinMap); + } - /// - /// Links all the specific Zoom functionality to the API bridge - /// - /// - /// - public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap) - { - var layoutsCodec = this as IHasZoomRoomLayouts; - if (layoutsCodec != null) - { - layoutsCodec.AvailableLayoutsChanged += (o, a) => - { - trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); - trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); - trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); - trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); - }; + /// + /// Links all the specific Zoom functionality to the API bridge + /// + /// + /// + public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap) + { + var layoutsCodec = this as IHasZoomRoomLayouts; + if (layoutsCodec != null) + { + layoutsCodec.AvailableLayoutsChanged += (o, a) => + { + trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); + trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); + trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); + trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll + == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); - layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); - trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); - layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); + // pass the names used to set the layout through the bridge + trilist.SetString(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery.ToString()); + trilist.SetString(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker.ToString()); + trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString()); + trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString()); + }; - layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); - layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); - trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage()); - trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage()); - trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts()); + layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); + trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); + layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); - trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => - { - try - { - var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true); - SetLayout(style); - } - catch (Exception e) - { - Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); - } - }); + layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); + layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); + trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage()); + trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage()); + trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts()); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); - } + trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => + { + try + { + var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true); + SetLayout(style); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); + } + }); - var pinCodec = this as IHasParticipantPinUnpin; + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + } + + var pinCodec = this as IHasParticipantPinUnpin; if (pinCodec != null) { pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]); @@ -1771,370 +1779,370 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // Set the value of the local property to be used when pinning a participant trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); } - } - - public override void ExecuteSwitch(object selector) - { - var action = selector as Action; - if (action == null) - { - return; - } - - action(); - } - - public void AcceptCall() - { - var incomingCall = - ActiveCalls.FirstOrDefault( - c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming)); - - AcceptCall(incomingCall); - } - - public override void AcceptCall(CodecActiveCallItem call) - { - SendText(string.Format("zCommand Call Accept callerJID: {0}", call.Id)); - - call.Status = eCodecCallStatus.Connected; - - OnCallStatusChange(call); - - UpdateCallStatus(); - } - - public void RejectCall() - { - var incomingCall = - ActiveCalls.FirstOrDefault( - c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming)); - - RejectCall(incomingCall); - } - - public override void RejectCall(CodecActiveCallItem call) - { - SendText(string.Format("zCommand Call Reject callerJID: {0}", call.Id)); - - call.Status = eCodecCallStatus.Disconnected; - - OnCallStatusChange(call); - - UpdateCallStatus(); - } - - public override void Dial(Meeting meeting) - { - Debug.Console(1, this,"Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title); - SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id)); - } - - public override void Dial(string number) - { - SendText(string.Format("zCommand Dial Join meetingNumber: {0}", number)); - } - - /// - /// Invites a contact to either a new meeting (if not already in a meeting) or the current meeting. - /// Currently only invites a single user - /// - /// - public override void Dial(IInvitableContact contact) - { - var ic = contact as zStatus.ZoomDirectoryContact; - - if (ic != null) - { - Debug.Console(1, this, "Attempting to Dial (Invite): {0}", ic.Name); - - if (!IsInCall) - { - SendText(string.Format("zCommand Invite Duration: {0} user: {1}", DefaultMeetingDurationMin, - ic.ContactId)); - } - else - { - SendText(string.Format("zCommand Call invite user: {0}", ic.ContactId)); - } - } - } - - public override void EndCall(CodecActiveCallItem call) - { - SendText("zCommand Call Disconnect"); - } - - public override void EndAllCalls() - { - SendText("zCommand Call Disconnect"); - } - - public override void SendDtmf(string s) - { - SendDtmfToPhone(s); - } - - /// - /// Call when directory results are updated - /// - /// - private void OnDirectoryResultReturned(CodecDirectory result) - { - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); - - // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology - var handler = DirectoryResultReturned; - if (handler != null) - { - handler(this, new DirectoryEventArgs - { - Directory = result, - DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue - }); - } - - //PrintDirectory(result); - } - - /// - /// Builds the cameras List by using the Zoom Room zStatus.Cameras data. Could later be modified to build from config data - /// - private void SetUpCameras() - { - SelectedCameraFeedback = new StringFeedback(() => Configuration.Video.Camera.SelectedId); - - ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera); - - foreach (var cam in Status.Cameras) - { - var camera = new ZoomRoomCamera(cam.id, cam.Name, this); - - Cameras.Add(camera); - - if (cam.Selected) - { - SelectedCamera = camera; - } - } - - if (IsInCall) - { - UpdateFarEndCameras(); - } - - _syncState.CamerasSetUp(); - } - - /// - /// Dynamically creates far end cameras for call participants who have far end control enabled. - /// - private void UpdateFarEndCameras() - { - // TODO: set up far end cameras for the current call - } - - #region Implementation of IHasParticipants - - public CodecParticipants Participants { get; private set; } - - #endregion - - #region IHasParticipantAudioMute Members - - public void MuteAudioForParticipant(int userId) - { - SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId)); - } - - public void UnmuteAudioForParticipant(int userId) - { - SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId)); - } - - public void ToggleAudioForParticipant(int userId) - { - var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); - - if (user == null) - { - Debug.Console(2, this, "Unable to find user with id: {0}", userId); - return; - } - - if (user.AudioMuteFb) - { - UnmuteAudioForParticipant(userId); - } - else - { - MuteAudioForParticipant(userId); - } - } - - #endregion - - #region IHasParticipantVideoMute Members - - public void MuteVideoForParticipant(int userId) - { - SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId)); - } - - public void UnmuteVideoForParticipant(int userId) - { - SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId)); - } - - public void ToggleVideoForParticipant(int userId) - { - var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); - - if (user == null) - { - Debug.Console(2, this, "Unable to find user with id: {0}", userId); - return; - } - - if (user.VideoMuteFb) - { - UnmuteVideoForParticipant(userId); - } - else - { - MuteVideoForParticipant(userId); - } - } - - #endregion - - #region IHasParticipantPinUnpin Members + } + + public override void ExecuteSwitch(object selector) + { + var action = selector as Action; + if (action == null) + { + return; + } + + action(); + } + + public void AcceptCall() + { + var incomingCall = + ActiveCalls.FirstOrDefault( + c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming)); + + AcceptCall(incomingCall); + } + + public override void AcceptCall(CodecActiveCallItem call) + { + SendText(string.Format("zCommand Call Accept callerJID: {0}", call.Id)); + + call.Status = eCodecCallStatus.Connected; + + OnCallStatusChange(call); + + UpdateCallStatus(); + } + + public void RejectCall() + { + var incomingCall = + ActiveCalls.FirstOrDefault( + c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming)); + + RejectCall(incomingCall); + } + + public override void RejectCall(CodecActiveCallItem call) + { + SendText(string.Format("zCommand Call Reject callerJID: {0}", call.Id)); + + call.Status = eCodecCallStatus.Disconnected; + + OnCallStatusChange(call); + + UpdateCallStatus(); + } + + public override void Dial(Meeting meeting) + { + Debug.Console(1, this, "Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title); + SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id)); + } + + public override void Dial(string number) + { + SendText(string.Format("zCommand Dial Join meetingNumber: {0}", number)); + } + + /// + /// Invites a contact to either a new meeting (if not already in a meeting) or the current meeting. + /// Currently only invites a single user + /// + /// + public override void Dial(IInvitableContact contact) + { + var ic = contact as zStatus.ZoomDirectoryContact; + + if (ic != null) + { + Debug.Console(1, this, "Attempting to Dial (Invite): {0}", ic.Name); + + if (!IsInCall) + { + SendText(string.Format("zCommand Invite Duration: {0} user: {1}", DefaultMeetingDurationMin, + ic.ContactId)); + } + else + { + SendText(string.Format("zCommand Call invite user: {0}", ic.ContactId)); + } + } + } + + public override void EndCall(CodecActiveCallItem call) + { + SendText("zCommand Call Disconnect"); + } + + public override void EndAllCalls() + { + SendText("zCommand Call Disconnect"); + } + + public override void SendDtmf(string s) + { + SendDtmfToPhone(s); + } + + /// + /// Call when directory results are updated + /// + /// + private void OnDirectoryResultReturned(CodecDirectory result) + { + CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + + // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology + var handler = DirectoryResultReturned; + if (handler != null) + { + handler(this, new DirectoryEventArgs + { + Directory = result, + DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue + }); + } + + //PrintDirectory(result); + } + + /// + /// Builds the cameras List by using the Zoom Room zStatus.Cameras data. Could later be modified to build from config data + /// + private void SetUpCameras() + { + SelectedCameraFeedback = new StringFeedback(() => Configuration.Video.Camera.SelectedId); + + ControllingFarEndCameraFeedback = new BoolFeedback(() => SelectedCamera is IAmFarEndCamera); + + foreach (var cam in Status.Cameras) + { + var camera = new ZoomRoomCamera(cam.id, cam.Name, this); + + Cameras.Add(camera); + + if (cam.Selected) + { + SelectedCamera = camera; + } + } + + if (IsInCall) + { + UpdateFarEndCameras(); + } + + _syncState.CamerasSetUp(); + } + + /// + /// Dynamically creates far end cameras for call participants who have far end control enabled. + /// + private void UpdateFarEndCameras() + { + // TODO: set up far end cameras for the current call + } + + #region Implementation of IHasParticipants + + public CodecParticipants Participants { get; private set; } + + #endregion + + #region IHasParticipantAudioMute Members + + public void MuteAudioForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId)); + } + + public void UnmuteAudioForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId)); + } + + public void ToggleAudioForParticipant(int userId) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + + if (user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } + + if (user.AudioMuteFb) + { + UnmuteAudioForParticipant(userId); + } + else + { + MuteAudioForParticipant(userId); + } + } + + #endregion + + #region IHasParticipantVideoMute Members + + public void MuteVideoForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId)); + } + + public void UnmuteVideoForParticipant(int userId) + { + SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId)); + } + + public void ToggleVideoForParticipant(int userId) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + + if (user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } + + if (user.VideoMuteFb) + { + UnmuteVideoForParticipant(userId); + } + else + { + MuteVideoForParticipant(userId); + } + } + + #endregion + + #region IHasParticipantPinUnpin Members - private Func NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } } + private Func NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } } - public IntFeedback NumberOfScreensFeedback { get; private set; } + public IntFeedback NumberOfScreensFeedback { get; private set; } - public int ScreenIndexToPinUserTo { get; private set; } + public int ScreenIndexToPinUserTo { get; private set; } - public void PinParticipant(int userId, int screenIndex) - { - SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex)); - } + public void PinParticipant(int userId, int screenIndex) + { + SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex)); + } - public void UnPinParticipant(int userId) - { - SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId)); - } + public void UnPinParticipant(int userId) + { + SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId)); + } - public void ToggleParticipantPinState(int userId, int screenIndex) - { - var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); + public void ToggleParticipantPinState(int userId, int screenIndex) + { + var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId)); - if(user == null) - { - Debug.Console(2, this, "Unable to find user with id: {0}", userId); - return; - } + if (user == null) + { + Debug.Console(2, this, "Unable to find user with id: {0}", userId); + return; + } - if (user.IsPinnedFb) - { - UnPinParticipant(userId); - } - else - { - PinParticipant(userId, screenIndex); - } - } + if (user.IsPinnedFb) + { + UnPinParticipant(userId); + } + else + { + PinParticipant(userId, screenIndex); + } + } - #endregion - - #region Implementation of IHasCameraOff + #endregion + + #region Implementation of IHasCameraOff - public BoolFeedback CameraIsOffFeedback { get; private set; } + public BoolFeedback CameraIsOffFeedback { get; private set; } - public void CameraOff() - { - CameraMuteOn(); - } + public void CameraOff() + { + CameraMuteOn(); + } - #endregion + #endregion - public BoolFeedback CameraIsMutedFeedback { get; private set; } + public BoolFeedback CameraIsMutedFeedback { get; private set; } - public void CameraMuteOn() - { - SendText("zConfiguration Call Camera Mute: On"); - } + public void CameraMuteOn() + { + SendText("zConfiguration Call Camera Mute: On"); + } - public void CameraMuteOff() - { - SendText("zConfiguration Call Camera Mute: Off"); - } + public void CameraMuteOff() + { + SendText("zConfiguration Call Camera Mute: Off"); + } - public void CameraMuteToggle() - { - if (CameraIsMutedFeedback.BoolValue) - CameraMuteOff(); - else - CameraMuteOn(); - } + public void CameraMuteToggle() + { + if (CameraIsMutedFeedback.BoolValue) + CameraMuteOff(); + else + CameraMuteOn(); + } - #region Implementation of IHasCameraAutoMode + #region Implementation of IHasCameraAutoMode - //Zoom doesn't support camera auto modes. Setting this to just unmute video - public void CameraAutoModeOn() - { - CameraMuteOff(); - throw new NotImplementedException("Zoom Room Doesn't support camera auto mode"); - } + //Zoom doesn't support camera auto modes. Setting this to just unmute video + public void CameraAutoModeOn() + { + CameraMuteOff(); + throw new NotImplementedException("Zoom Room Doesn't support camera auto mode"); + } - //Zoom doesn't support camera auto modes. Setting this to just unmute video - public void CameraAutoModeOff() - { - SendText("zConfiguration Call Camera Mute: Off"); - } + //Zoom doesn't support camera auto modes. Setting this to just unmute video + public void CameraAutoModeOff() + { + SendText("zConfiguration Call Camera Mute: Off"); + } - public void CameraAutoModeToggle() - { - throw new NotImplementedException("Zoom Room doesn't support camera auto mode"); - } + public void CameraAutoModeToggle() + { + throw new NotImplementedException("Zoom Room doesn't support camera auto mode"); + } - public BoolFeedback CameraAutoModeIsOnFeedback { get; private set; } + public BoolFeedback CameraAutoModeIsOnFeedback { get; private set; } - #endregion + #endregion - #region Implementation of IHasFarEndContentStatus + #region Implementation of IHasFarEndContentStatus - public BoolFeedback ReceivingContent { get; private set; } + public BoolFeedback ReceivingContent { get; private set; } - #endregion + #endregion - #region Implementation of IHasSelfviewPosition + #region Implementation of IHasSelfviewPosition - private CodecCommandWithLabel _currentSelfviewPipPosition; + private CodecCommandWithLabel _currentSelfviewPipPosition; - public StringFeedback SelfviewPipPositionFeedback { get; private set; } + public StringFeedback SelfviewPipPositionFeedback { get; private set; } - public void SelfviewPipPositionSet(CodecCommandWithLabel position) - { - SendText(String.Format("zConfiguration Call Layout Position: {0}", position.Command)); - } + public void SelfviewPipPositionSet(CodecCommandWithLabel position) + { + SendText(String.Format("zConfiguration Call Layout Position: {0}", position.Command)); + } - public void SelfviewPipPositionToggle() - { - if (_currentSelfviewPipPosition != null) - { - var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1; + public void SelfviewPipPositionToggle() + { + if (_currentSelfviewPipPosition != null) + { + var nextPipPositionIndex = SelfviewPipPositions.IndexOf(_currentSelfviewPipPosition) + 1; - if (nextPipPositionIndex >= SelfviewPipPositions.Count) - // Check if we need to loop back to the first item in the list - nextPipPositionIndex = 0; + if (nextPipPositionIndex >= SelfviewPipPositions.Count) + // Check if we need to loop back to the first item in the list + nextPipPositionIndex = 0; - SelfviewPipPositionSet(SelfviewPipPositions[nextPipPositionIndex]); - } - } + SelfviewPipPositionSet(SelfviewPipPositions[nextPipPositionIndex]); + } + } - public List SelfviewPipPositions = new List() + public List SelfviewPipPositions = new List() { new CodecCommandWithLabel("UpLeft", "Center Left"), new CodecCommandWithLabel("UpRight", "Center Right"), @@ -2142,384 +2150,384 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom new CodecCommandWithLabel("DownLeft", "Lower Left") }; - private void ComputeSelfviewPipStatus() - { - _currentSelfviewPipPosition = - SelfviewPipPositions.FirstOrDefault( - p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower())); - } + private void ComputeSelfviewPipStatus() + { + _currentSelfviewPipPosition = + SelfviewPipPositions.FirstOrDefault( + p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower())); + } - #endregion + #endregion - #region Implementation of IHasPhoneDialing + #region Implementation of IHasPhoneDialing - private Func PhoneOffHookFeedbackFunc {get {return () => Status.PhoneCall.OffHook; }} - private Func CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } } - private Func CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } } - - public BoolFeedback PhoneOffHookFeedback { get; private set; } - public StringFeedback CallerIdNameFeedback { get; private set; } - public StringFeedback CallerIdNumberFeedback { get; private set; } - - public void DialPhoneCall(string number) - { - SendText(String.Format("zCommand Dial PhoneCallOut Number: {0}", number)); - } - - public void EndPhoneCall() - { - SendText(String.Format("zCommand Dial PhoneHangUp CallId: {0}", Status.PhoneCall.CallId)); - } - - public void SendDtmfToPhone(string digit) - { - SendText(String.Format("zCommand SendSipDTMF CallId: {0} Key: {1}", Status.PhoneCall.CallId, digit)); - } - - #endregion - - #region IHasZoomRoomLayouts Members + private Func PhoneOffHookFeedbackFunc { get { return () => Status.PhoneCall.OffHook; } } + private Func CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } } + private Func CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } } + + public BoolFeedback PhoneOffHookFeedback { get; private set; } + public StringFeedback CallerIdNameFeedback { get; private set; } + public StringFeedback CallerIdNumberFeedback { get; private set; } + + public void DialPhoneCall(string number) + { + SendText(String.Format("zCommand Dial PhoneCallOut Number: {0}", number)); + } + + public void EndPhoneCall() + { + SendText(String.Format("zCommand Dial PhoneHangUp CallId: {0}", Status.PhoneCall.CallId)); + } + + public void SendDtmfToPhone(string digit) + { + SendText(String.Format("zCommand SendSipDTMF CallId: {0} Key: {1}", Status.PhoneCall.CallId, digit)); + } + + #endregion + + #region IHasZoomRoomLayouts Members - public event EventHandler AvailableLayoutsChanged; - - private Func LayoutViewIsOnFirstPageFeedbackFunc {get {return () => Status.Layout.is_In_First_Page; } } - private Func LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } } - private Func CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } } - private Func ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } } - - public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; } - - public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; } - - public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; } - - public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; } + public event EventHandler AvailableLayoutsChanged; + + private Func LayoutViewIsOnFirstPageFeedbackFunc { get { return () => Status.Layout.is_In_First_Page; } } + private Func LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } } + private Func CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } } + private Func ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } } + + public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; } + + public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; } + + public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; } + + public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; } - public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; } + public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; } - public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; } + public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; } - /// - /// Reads individual properties to determine if which layouts are avalailable - /// - private void ComputeAvailableLayouts() - { - zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; - // TODO: #697 [ ] Compute the avaialble layouts and set the value of AvailableLayouts - // Will need to test and confirm that this logic evaluates correctly - if (Status.Layout.can_Switch_Wall_View) - { - availableLayouts |= zConfiguration.eLayoutStyle.Gallery; - } - - if (Status.Layout.can_Switch_Speaker_View) - { - availableLayouts |= zConfiguration.eLayoutStyle.Speaker; - } - - if (Status.Layout.can_Switch_Share_On_All_Screens) - { - availableLayouts |= zConfiguration.eLayoutStyle.ShareAll; - } - - // There is no property that directly reports if strip mode is valid, but API stipulates - // that strip mode is available if the number of screens is 1 - if (Status.NumberOfScreens.NumOfScreens == 1) - { - availableLayouts |= zConfiguration.eLayoutStyle.Strip; - } - - var handler = AvailableLayoutsChanged; - if (handler != null) - { - handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts }); - } - - AvailableLayouts = availableLayouts; - } - - public void GetAvailableLayouts() - { - SendText("zStatus Call Layout"); - } - - public void SetLayout(zConfiguration.eLayoutStyle layoutStyle) - { - LastSelectedLayout = layoutStyle; - SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString())); - } - - public void SwapContentWithThumbnail() - { - if (CanSwapContentWithThumbnailFeedback.BoolValue) - { - var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state - // TODO: #697 [ ] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback - // to toggle the state - SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); - } - } - - public void LayoutTurnNextPage() - { - SendText("zCommand Call Layout TurnPage Forward: On"); - } - - public void LayoutTurnPreviousPage() - { - SendText("zCommand Call Layout TurnPage Forward: Off"); - } - - #endregion - - #region IHasCodecLayouts Members - - private Func LocalLayoutFeedbackFunc { get { return () => Configuration.Call.Layout.Style.ToString(); } } - - public StringFeedback LocalLayoutFeedback { get; private set; } - - public void LocalLayoutToggle() - { - throw new NotImplementedException(); - } - - public void LocalLayoutToggleSingleProminent() - { - throw new NotImplementedException(); - } - - public void MinMaxLayoutToggle() - { - throw new NotImplementedException(); - } - - #endregion - - } - - /// - /// Zoom Room specific info object - /// - public class ZoomRoomInfo : VideoCodecInfo - { - public ZoomRoomInfo(ZoomRoomStatus status, ZoomRoomConfiguration configuration) - { - Status = status; - Configuration = configuration; - } - - public ZoomRoomStatus Status { get; private set; } - public ZoomRoomConfiguration Configuration { get; private set; } - - public override bool AutoAnswerEnabled - { - get { return Status.SystemUnit.RoomInfo.AutoAnswerIsEnabled; } - } - - public override string E164Alias - { - get - { - if (!string.IsNullOrEmpty(Status.SystemUnit.MeetingNumber)) - { - return Status.SystemUnit.MeetingNumber; - } - return string.Empty; - } - } - - public override string H323Id - { - get - { - if (!string.IsNullOrEmpty(Status.Call.Info.meeting_list_item.third_party.h323_address)) - { - return Status.Call.Info.meeting_list_item.third_party.h323_address; - } - return string.Empty; - } - } - - public override string IpAddress - { - get - { - if (!string.IsNullOrEmpty(Status.SystemUnit.RoomInfo.AccountEmail)) - { - return Status.SystemUnit.RoomInfo.AccountEmail; - } - return string.Empty; - } - } - - public override bool MultiSiteOptionIsEnabled - { - get { return true; } - } - - public override string SipPhoneNumber - { - get - { - if (!string.IsNullOrEmpty(Status.Call.Info.dialIn)) - { - return Status.Call.Info.dialIn; - } - return string.Empty; - } - } - - public override string SipUri - { - get - { - if (!string.IsNullOrEmpty(Status.Call.Info.meeting_list_item.third_party.sip_address)) - { - return Status.Call.Info.meeting_list_item.third_party.sip_address; - } - return string.Empty; - } - } - } - - /// - /// Tracks the initial sycnronization state when establishing a new connection - /// - public class ZoomRoomSyncState : IKeyed - { - private readonly ZoomRoom _parent; - private readonly CrestronQueue _syncQueries; - private bool _initialSyncComplete; - - public ZoomRoomSyncState(string key, ZoomRoom parent) - { - _parent = parent; - Key = key; - _syncQueries = new CrestronQueue(50); - CodecDisconnected(); - } - - public bool InitialSyncComplete - { - get { return _initialSyncComplete; } - private set - { - if (value) - { - var handler = InitialSyncCompleted; - if (handler != null) - { - handler(this, new EventArgs()); - } - } - _initialSyncComplete = value; - } - } - - public bool LoginMessageWasReceived { get; private set; } - - public bool InitialQueryMessagesWereSent { get; private set; } - - public bool LastQueryResponseWasReceived { get; private set; } - - public bool CamerasHaveBeenSetUp { get; private set; } - - #region IKeyed Members - - public string Key { get; private set; } - - #endregion - - public event EventHandler InitialSyncCompleted; - - public void StartSync() - { - DequeueQueries(); - } - - private void DequeueQueries() - { - while (!_syncQueries.IsEmpty) - { - var query = _syncQueries.Dequeue(); - - _parent.SendText(query); - } - - InitialQueryMessagesSent(); - } - - public void AddQueryToQueue(string query) - { - _syncQueries.Enqueue(query); - } - - public void LoginMessageReceived() - { - LoginMessageWasReceived = true; - Debug.Console(1, this, "Login Message Received."); - CheckSyncStatus(); - } - - public void InitialQueryMessagesSent() - { - InitialQueryMessagesWereSent = true; - Debug.Console(1, this, "Query Messages Sent."); - CheckSyncStatus(); - } - - public void LastQueryResponseReceived() - { - LastQueryResponseWasReceived = true; - Debug.Console(1, this, "Last Query Response Received."); - CheckSyncStatus(); - } - - public void CamerasSetUp() - { - CamerasHaveBeenSetUp = true; - Debug.Console(1, this, "Cameras Set Up."); - CheckSyncStatus(); - } - - public void CodecDisconnected() - { - _syncQueries.Clear(); - LoginMessageWasReceived = false; - InitialQueryMessagesWereSent = false; - LastQueryResponseWasReceived = false; - CamerasHaveBeenSetUp = false; - InitialSyncComplete = false; - } - - private void CheckSyncStatus() - { - if (LoginMessageWasReceived && InitialQueryMessagesWereSent && LastQueryResponseWasReceived && - CamerasHaveBeenSetUp) - { - InitialSyncComplete = true; - Debug.Console(1, this, "Initial Codec Sync Complete!"); - } - else - { - InitialSyncComplete = false; - } - } - } - - public class ZoomRoomFactory : EssentialsDeviceFactory - { - public ZoomRoomFactory() - { - TypeNames = new List {"zoomroom"}; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new ZoomRoom Device"); - var comm = CommFactory.CreateCommForDevice(dc); - return new ZoomRoom(dc, comm); - } - } + /// + /// Reads individual properties to determine if which layouts are avalailable + /// + private void ComputeAvailableLayouts() + { + zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; + // TODO: #697 [ ] Compute the avaialble layouts and set the value of AvailableLayouts + // Will need to test and confirm that this logic evaluates correctly + if (Status.Layout.can_Switch_Wall_View) + { + availableLayouts |= zConfiguration.eLayoutStyle.Gallery; + } + + if (Status.Layout.can_Switch_Speaker_View) + { + availableLayouts |= zConfiguration.eLayoutStyle.Speaker; + } + + if (Status.Layout.can_Switch_Share_On_All_Screens) + { + availableLayouts |= zConfiguration.eLayoutStyle.ShareAll; + } + + // There is no property that directly reports if strip mode is valid, but API stipulates + // that strip mode is available if the number of screens is 1 + if (Status.NumberOfScreens.NumOfScreens == 1) + { + availableLayouts |= zConfiguration.eLayoutStyle.Strip; + } + + var handler = AvailableLayoutsChanged; + if (handler != null) + { + handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts }); + } + + AvailableLayouts = availableLayouts; + } + + public void GetAvailableLayouts() + { + SendText("zStatus Call Layout"); + } + + public void SetLayout(zConfiguration.eLayoutStyle layoutStyle) + { + LastSelectedLayout = layoutStyle; + SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString())); + } + + public void SwapContentWithThumbnail() + { + if (CanSwapContentWithThumbnailFeedback.BoolValue) + { + var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state + // TODO: #697 [ ] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback + // to toggle the state + SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); + } + } + + public void LayoutTurnNextPage() + { + SendText("zCommand Call Layout TurnPage Forward: On"); + } + + public void LayoutTurnPreviousPage() + { + SendText("zCommand Call Layout TurnPage Forward: Off"); + } + + #endregion + + #region IHasCodecLayouts Members + + private Func LocalLayoutFeedbackFunc { get { return () => Configuration.Call.Layout.Style.ToString(); } } + + public StringFeedback LocalLayoutFeedback { get; private set; } + + public void LocalLayoutToggle() + { + throw new NotImplementedException(); + } + + public void LocalLayoutToggleSingleProminent() + { + throw new NotImplementedException(); + } + + public void MinMaxLayoutToggle() + { + throw new NotImplementedException(); + } + + #endregion + + } + + /// + /// Zoom Room specific info object + /// + public class ZoomRoomInfo : VideoCodecInfo + { + public ZoomRoomInfo(ZoomRoomStatus status, ZoomRoomConfiguration configuration) + { + Status = status; + Configuration = configuration; + } + + public ZoomRoomStatus Status { get; private set; } + public ZoomRoomConfiguration Configuration { get; private set; } + + public override bool AutoAnswerEnabled + { + get { return Status.SystemUnit.RoomInfo.AutoAnswerIsEnabled; } + } + + public override string E164Alias + { + get + { + if (!string.IsNullOrEmpty(Status.SystemUnit.MeetingNumber)) + { + return Status.SystemUnit.MeetingNumber; + } + return string.Empty; + } + } + + public override string H323Id + { + get + { + if (!string.IsNullOrEmpty(Status.Call.Info.meeting_list_item.third_party.h323_address)) + { + return Status.Call.Info.meeting_list_item.third_party.h323_address; + } + return string.Empty; + } + } + + public override string IpAddress + { + get + { + if (!string.IsNullOrEmpty(Status.SystemUnit.RoomInfo.AccountEmail)) + { + return Status.SystemUnit.RoomInfo.AccountEmail; + } + return string.Empty; + } + } + + public override bool MultiSiteOptionIsEnabled + { + get { return true; } + } + + public override string SipPhoneNumber + { + get + { + if (!string.IsNullOrEmpty(Status.Call.Info.dialIn)) + { + return Status.Call.Info.dialIn; + } + return string.Empty; + } + } + + public override string SipUri + { + get + { + if (!string.IsNullOrEmpty(Status.Call.Info.meeting_list_item.third_party.sip_address)) + { + return Status.Call.Info.meeting_list_item.third_party.sip_address; + } + return string.Empty; + } + } + } + + /// + /// Tracks the initial sycnronization state when establishing a new connection + /// + public class ZoomRoomSyncState : IKeyed + { + private readonly ZoomRoom _parent; + private readonly CrestronQueue _syncQueries; + private bool _initialSyncComplete; + + public ZoomRoomSyncState(string key, ZoomRoom parent) + { + _parent = parent; + Key = key; + _syncQueries = new CrestronQueue(50); + CodecDisconnected(); + } + + public bool InitialSyncComplete + { + get { return _initialSyncComplete; } + private set + { + if (value) + { + var handler = InitialSyncCompleted; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + _initialSyncComplete = value; + } + } + + public bool LoginMessageWasReceived { get; private set; } + + public bool InitialQueryMessagesWereSent { get; private set; } + + public bool LastQueryResponseWasReceived { get; private set; } + + public bool CamerasHaveBeenSetUp { get; private set; } + + #region IKeyed Members + + public string Key { get; private set; } + + #endregion + + public event EventHandler InitialSyncCompleted; + + public void StartSync() + { + DequeueQueries(); + } + + private void DequeueQueries() + { + while (!_syncQueries.IsEmpty) + { + var query = _syncQueries.Dequeue(); + + _parent.SendText(query); + } + + InitialQueryMessagesSent(); + } + + public void AddQueryToQueue(string query) + { + _syncQueries.Enqueue(query); + } + + public void LoginMessageReceived() + { + LoginMessageWasReceived = true; + Debug.Console(1, this, "Login Message Received."); + CheckSyncStatus(); + } + + public void InitialQueryMessagesSent() + { + InitialQueryMessagesWereSent = true; + Debug.Console(1, this, "Query Messages Sent."); + CheckSyncStatus(); + } + + public void LastQueryResponseReceived() + { + LastQueryResponseWasReceived = true; + Debug.Console(1, this, "Last Query Response Received."); + CheckSyncStatus(); + } + + public void CamerasSetUp() + { + CamerasHaveBeenSetUp = true; + Debug.Console(1, this, "Cameras Set Up."); + CheckSyncStatus(); + } + + public void CodecDisconnected() + { + _syncQueries.Clear(); + LoginMessageWasReceived = false; + InitialQueryMessagesWereSent = false; + LastQueryResponseWasReceived = false; + CamerasHaveBeenSetUp = false; + InitialSyncComplete = false; + } + + private void CheckSyncStatus() + { + if (LoginMessageWasReceived && InitialQueryMessagesWereSent && LastQueryResponseWasReceived && + CamerasHaveBeenSetUp) + { + InitialSyncComplete = true; + Debug.Console(1, this, "Initial Codec Sync Complete!"); + } + else + { + InitialSyncComplete = false; + } + } + } + + public class ZoomRoomFactory : EssentialsDeviceFactory + { + public ZoomRoomFactory() + { + TypeNames = new List { "zoomroom" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new ZoomRoom Device"); + var comm = CommFactory.CreateCommForDevice(dc); + return new ZoomRoom(dc, comm); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 61a59fff..07265d20 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -119,7 +119,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Description = "FB Indicates if layout 'Gallery' is available", JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital + JoinType = eJoinType.DigitalSerial }); [JoinName("LayoutSpeakerIsAvailable")] @@ -133,7 +133,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Description = "FB Indicates if layout 'Speaker' is available", JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital + JoinType = eJoinType.DigitalSerial }); [JoinName("LayoutStripIsAvailable")] @@ -147,7 +147,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Description = "FB Indicates if layout 'Strip' is available", JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital + JoinType = eJoinType.DigitalSerial }); [JoinName("LayoutShareAllIsAvailable")] @@ -161,7 +161,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Description = "FB Indicates if layout 'ShareAll' is available", JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital + JoinType = eJoinType.DigitalSerial }); //[JoinName("ParticipantAudioMuteToggleStart")] From 63853739f3b5c087c972af0d86adf2e6bd76d95f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 11 May 2021 17:23:26 -0600 Subject: [PATCH 221/480] Updates object structure to deal with a bug in ZoomRoom 5.6.3 that responds with an incorrect object structure for the layout style property --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 8 ++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 41 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index c8bfd5bf..28e232ea 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1202,6 +1202,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { public string appVersion { get; set; } public string deviceSystem { get; set; } + + // This doesn't belong here, but there's a bug in the object structure of Zoom Room 5.6.3 that puts it here + public zConfiguration.Call Call { get; set; } + + public Client() + { + Call = new zConfiguration.Call(); + } } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 71882d5c..478e61ff 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -515,6 +515,33 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }; + // This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3 + Configuration.Client.Call.Layout.PropertyChanged += (o,a) => + { + switch (a.PropertyName) + { + case "Position": + { + ComputeSelfviewPipStatus(); + + SelfviewPipPositionFeedback.FireUpdate(); + + break; + } + case "ShareThumb": + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } + case "Style": + { + LocalLayoutFeedback.FireUpdate(); + break; + } + + } + }; + Status.Call.Sharing.PropertyChanged += (o, a) => { if (a.PropertyName == "State") @@ -2283,7 +2310,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #region IHasCodecLayouts Members - private Func LocalLayoutFeedbackFunc { get { return () => Configuration.Call.Layout.Style.ToString(); } } + private Func LocalLayoutFeedbackFunc + { + get + { + return () => + { + if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None) + return Configuration.Call.Layout.Style.ToString(); + else + return Configuration.Client.Call.Layout.Style.ToString(); + }; + } + } public StringFeedback LocalLayoutFeedback { get; private set; } From 5fc4ff602782325faf681460dc0ae56d180d2624 Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Tue, 11 May 2021 20:28:15 -0400 Subject: [PATCH 222/480] #700 FIxes issue where ConfigWrite.UpdateDeviceConfig and UpdateRoomConfig do not write config to file --- .../Config/Essentials/ConfigWriter.cs | 14 +++++++------- .../Devices/ReconfigurableDevice.cs | 6 +----- .../Cameras/CameraBase.cs | 6 ++---- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs index b97eeafa..c6224859 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigWriter.cs @@ -54,11 +54,11 @@ namespace PepperDash.Essentials.Core.Config { bool success = false; - var deviceConfig = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key)); + var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key)); - if (deviceConfig >= 0) + if (deviceConfigIndex >= 0) { - ConfigReader.ConfigObject.Devices[deviceConfig] = config; + ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config; Debug.Console(1, "Updated config of device: '{0}'", config.Key); @@ -74,13 +74,13 @@ namespace PepperDash.Essentials.Core.Config { bool success = false; - var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key)); + var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key)); - if (deviceConfig != null) + if (roomConfigIndex >= 0) { - deviceConfig = config; + ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config; - Debug.Console(1, "Updated config of device: '{0}'", config.Key); + Debug.Console(1, "Updated room of device: '{0}'", config.Key); success = true; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs index 60c8db0c..81988199 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs @@ -54,11 +54,7 @@ namespace PepperDash.Essentials.Core.Devices Name = config.Name; } - protected virtual void WriteControlProperty(JToken controlObject) - { - Config.Properties["control"] = JToken.FromObject(controlObject); - CustomSetConfig(Config); - } + /// /// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs index edfd34cb..def22069 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs @@ -81,11 +81,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras } protected CameraBase(string key, string name) : - base (new DeviceConfig{Name = name, Key = key}) + this (new DeviceConfig{Name = name, Key = key}) { - OutputPorts = new RoutingPortCollection(); - - ControlMode = eCameraControlMode.Manual; + } protected void LinkCameraToApi(CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, From ac0d5e59a072913356bbe862a6b25bb933b4a0e0 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 12 May 2021 11:27:33 -0500 Subject: [PATCH 223/480] ZoomRoom.cs, commented out Debug statement @ line 874 to remove 'JSON Curly Brace Count:' messages in console when using debug level 2. --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 478e61ff..1b8c5914 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -870,7 +870,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom _jsonCurlyBraceCounter--; } - Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); + // TODO [X] 2021-05-12, jkd: turned off to reduce console traffic + //Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter) // Check for the beginning of a new JSON message From eac7c91327a00f968b1efbce2390d714a8c2eaad Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 13 May 2021 18:07:03 -0600 Subject: [PATCH 224/480] Create rfi_request.md --- .github/ISSUE_TEMPLATE/rfi_request.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/rfi_request.md diff --git a/.github/ISSUE_TEMPLATE/rfi_request.md b/.github/ISSUE_TEMPLATE/rfi_request.md new file mode 100644 index 00000000..e69ac70f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/rfi_request.md @@ -0,0 +1,26 @@ +--- +name: Request for Information +about: Request specific information about capabilities of the framework +title: "[RFI]-" +labels: RFI +assignees: '' + +--- + +**What is your request?** +Please provide as much detail as possible. + + +**What is the intended use case** +- [ ] Essentials Standalone Application +- [ ] Essentials + SIMPL Windows Hybrid + +**User Interface Requirements** +- [ ] Not Applicable (logic only) +- [ ] Smart Graphics Touchpanel +- [ ] Cisco Touch10 +- [ ] Mobile Control + + +**Additional context** +Add any other context or screenshots about the request here. From 2d36b808008976ab2e037e97fc9d45e3e3c06fb1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 14 May 2021 15:46:12 -0600 Subject: [PATCH 225/480] Adds CH5 option --- .github/ISSUE_TEMPLATE/rfi_request.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/rfi_request.md b/.github/ISSUE_TEMPLATE/rfi_request.md index e69ac70f..8ad25ac6 100644 --- a/.github/ISSUE_TEMPLATE/rfi_request.md +++ b/.github/ISSUE_TEMPLATE/rfi_request.md @@ -17,9 +17,10 @@ Please provide as much detail as possible. **User Interface Requirements** - [ ] Not Applicable (logic only) -- [ ] Smart Graphics Touchpanel +- [ ] Crestron Smart Graphics Touchpanel - [ ] Cisco Touch10 - [ ] Mobile Control +- [ ] Crestron CH5 Touchpanel interface **Additional context** From d00c8bed5ffe602b192b04397af802acd809de24 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 20 May 2021 10:52:12 -0600 Subject: [PATCH 226/480] fix:(EssentialsCore) Add ability for `devjson` command to handle overloads The `devjson` command needs to ability to handle overloads. With this change, if a method is an overloaded method, the command will get all methods on an object that match the entered method name, then get the first entry in the list of methods that matches the length of the provided parameters list. This won't work in all cases, as there may be situations where the parameters of the methods have the same length, but different types. In that situation, it's likely that the conversion from `Object` to the desired type will fail, in which case, the command will notify the user that something went wrong. --- .../Devices/DeviceJsonApi.cs | 81 +++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs index 51d5882f..a1930cf0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs @@ -20,8 +20,23 @@ namespace PepperDash.Essentials.Core /// public static void DoDeviceActionWithJson(string json) { - var action = JsonConvert.DeserializeObject(json); - DoDeviceAction(action); + if (String.IsNullOrEmpty(json)) + { + CrestronConsole.ConsoleCommandResponse( + "Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted."); + return; + } + try + { + var action = JsonConvert.DeserializeObject(json); + + DoDeviceAction(action); + } + catch (Exception ex) + { + CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}"); + } + } @@ -33,29 +48,47 @@ namespace PepperDash.Essentials.Core { var key = action.DeviceKey; var obj = FindObjectOnPath(key); - if (obj == null) - return; + if (obj == null) + { + CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key); + return; + } - CType t = obj.GetType(); - var method = t.GetMethod(action.MethodName); - if (method == null) - { - Debug.Console(0, "Method '{0}' not found", action.MethodName); - return; - } - var mParams = method.GetParameters(); - // Add empty params if not provided - if (action.Params == null) action.Params = new object[0]; - if (mParams.Length > action.Params.Length) - { - Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length); - return; - } - object[] convertedParams = mParams - .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, - System.Globalization.CultureInfo.InvariantCulture)) - .ToArray(); - object ret = method.Invoke(obj, convertedParams); + if (action.Params == null) + { + //no params, so setting action.Params to empty array + action.Params = new object[0]; + } + + CType t = obj.GetType(); + try + { + var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList(); + + var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length); + + if (method == null) + { + CrestronConsole.ConsoleCommandResponse( + "Unable to find method with name {0} and that matches parameters {1}", action.MethodName, + action.Params); + return; + } + var mParams = method.GetParameters(); + + var convertedParams = mParams + .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, + System.Globalization.CultureInfo.InvariantCulture)) + .ToArray(); + var ret = method.Invoke(obj, convertedParams); + + CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name, + action.DeviceKey); + } + catch (Exception ex) + { + CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName, + ex.Message);} } /// From db60f8f1be06128bd25b90a2c8b8da1daf9f5d06 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 20 May 2021 15:43:02 -0500 Subject: [PATCH 227/480] ResponseObject.cs updates: Added and tested SortParticipantListtByHandStatus method. Found an issue with HandStatus response, property names include ': ', updated JsonProperty definitions to account for issues with expected returns vs. actual returns. --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 3097 +++++++++-------- 1 file changed, 1588 insertions(+), 1509 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 28e232ea..b45810ac 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -15,1513 +15,1592 @@ using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { - public enum eZoomRoomResponseType - { - zEvent, - zStatus, - zConfiguration, - zCommand - } - - public abstract class NotifiableObject : INotifyPropertyChanged - { - #region INotifyPropertyChanged Members - - public event PropertyChangedEventHandler PropertyChanged; - - protected void NotifyPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - } - - /// - /// Used to track the current status of a ZoomRoom - /// - public class ZoomRoomStatus - { - public zStatus.Login Login { get; set; } - public zStatus.SystemUnit SystemUnit { get; set; } - public zStatus.Phonebook Phonebook { get; set; } - public zStatus.Call Call { get; set; } - public zStatus.Capabilities Capabilities { get; set; } - public zStatus.Sharing Sharing { get; set; } - public zStatus.NumberOfScreens NumberOfScreens { get; set; } - public zStatus.Layout Layout { get; set; } - public zStatus.Video Video { get; set; } - public zStatus.CameraShare CameraShare { get; set; } - public List AudioInputs { get; set; } - public List AudioOuputs { get; set; } - public List Cameras { get; set; } - public zEvent.PhoneCallStatus PhoneCall { get; set; } - - public ZoomRoomStatus() - { - Login = new zStatus.Login(); - SystemUnit = new zStatus.SystemUnit(); - Phonebook = new zStatus.Phonebook(); - Call = new zStatus.Call(); - Capabilities = new zStatus.Capabilities(); - Sharing = new zStatus.Sharing(); - NumberOfScreens = new zStatus.NumberOfScreens(); - Layout = new zStatus.Layout(); - Video = new zStatus.Video(); - CameraShare = new zStatus.CameraShare(); - AudioInputs = new List(); - AudioOuputs = new List(); - Cameras = new List(); - PhoneCall = new zEvent.PhoneCallStatus(); - } - } - - /// - /// Used to track the current configuration of a ZoomRoom - /// - public class ZoomRoomConfiguration - { - public zConfiguration.Call Call { get; set; } - public zConfiguration.Audio Audio { get; set; } - public zConfiguration.Video Video { get; set; } - public zConfiguration.Client Client { get; set; } - public zConfiguration.Camera Camera { get; set; } - - public ZoomRoomConfiguration() - { - Call = new zConfiguration.Call(); - Audio = new zConfiguration.Audio(); - Video = new zConfiguration.Video(); - Client = new zConfiguration.Client(); - Camera = new zConfiguration.Camera(); - } - } - - /// - /// Represents a response from a ZoomRoom system - /// - public class Response - { - public Status Status { get; set; } - public bool Sync { get; set; } - [JsonProperty("topKey")] - public string TopKey { get; set; } - [JsonProperty("type")] - public string Type { get; set; } - - public Response() - { - Status = new Status(); - } - } - - public class Status - { - [JsonProperty("message")] - public string Message { get; set; } - [JsonProperty("state")] - public string State { get; set; } - } - - - /// - /// zStatus class stucture - /// - public class zStatus - { - public class Login - { - [JsonProperty("ZAAPI Release")] - public string ZAAPIRelease { get; set; } - [JsonProperty("Zoom Room Release")] - public string ZoomRoomRelease { get; set; } - } - - public class SystemUnit - { - [JsonProperty("email")] - public string Email { get; set; } - [JsonProperty("login_type")] - public string LoginType { get; set; } - [JsonProperty("meeting_number")] - public string MeetingNumber { get; set; } - [JsonProperty("platform")] - public string Platform { get; set; } - [JsonProperty("room_info")] - public RoomInfo RoomInfo { get; set; } - [JsonProperty("room_version")] - public string RoomVersion { get; set; } - - public SystemUnit() - { - RoomInfo = new RoomInfo(); - } - } - - public class RoomInfo - { - [JsonProperty("account_email")] - public string AccountEmail { get; set; } - [JsonProperty("display_version")] - public string DisplayVersion { get; set; } - [JsonProperty("is_auto_answer_enabled")] - public bool AutoAnswerIsEnabled { get; set; } - [JsonProperty("is_auto_answer_selected")] - public bool AutoAnswerIsSelected { get; set; } - [JsonProperty("room_name")] - public string RoomName { get; set; } - } - - public class CloudPbxInfo - { - [JsonProperty("company_number")] - public string CompanyNumber { get; set; } - [JsonProperty("extension")] - public string Extension { get; set; } - [JsonProperty("isValid")] - public bool IsValid { get; set; } - } - - public enum ePresence - { - PRESENCE_OFFLINE, - PRESENCE_ONLINE, - PRESENCE_AWAY, - PRESENCE_BUSY, - PRESENCE_DND - } - - public class Contact - { - [JsonProperty("avatarURL")] - public string AvatarURL { get; set; } - [JsonProperty("cloud_pbx_info")] - public CloudPbxInfo CloudPbxInfo { get; set; } - [JsonProperty("email")] - public string Email { get; set; } - [JsonProperty("firstName")] - public string FirstName { get; set; } - [JsonProperty("index")] - public int Index { get; set; } - [JsonProperty("isLegacy")] - public bool IsLegacy { get; set; } - [JsonProperty("isZoomRoom")] - public bool IsZoomRoom { get; set; } - [JsonProperty("jid")] - public string Jid { get; set; } - [JsonProperty("lastName")] - public string LastName { get; set; } - [JsonProperty("onDesktop")] - public bool OnDesktop { get; set; } - [JsonProperty("onMobile")] - public bool OnMobile { get; set; } - [JsonProperty("phoneNumber")] - public string PhoneNumber { get; set; } - [JsonProperty("presence")] - public ePresence Presence { get; set; } - [JsonProperty("presence_status")] - public int PresenceStatus { get; set; } - [JsonProperty("screenName")] - public string ScreenName { get; set; } - [JsonProperty("sip_phone_number")] - public string SipPhoneNumber { get; set; } - - - public Contact() - { - CloudPbxInfo = new CloudPbxInfo(); - } - } - - /// - /// Used to be able to inplement IInvitableContact on DirectoryContact - /// - public class ZoomDirectoryContact : DirectoryContact, IInvitableContact - { - - } - - public class Phonebook - { - [JsonProperty("Contacts")] - public List Contacts { get; set; } - - public Phonebook() - { - Contacts = new List(); - } - - /// - /// Converts from zStatus.Contact types to generic directory items - /// - /// - public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts) - { - var directory = new CodecDirectory(); - - var folders = new List(); - - var roomFolder = new DirectoryFolder(); - - var contactFolder = new DirectoryFolder(); - - var contacts = new List(); - - // Check if there are any zoom rooms - var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom); - - if (zoomRooms.Count > 0) - { - // If so, setup a rooms and contacts folder and add them. - roomFolder.Name = "Rooms"; - roomFolder.ParentFolderId = "root"; - roomFolder.FolderId = "rooms"; - - contactFolder.Name = "Contacts"; - contactFolder.ParentFolderId = "root"; - contactFolder.FolderId = "contacts"; - - folders.Add(roomFolder); - folders.Add(contactFolder); - - directory.AddFoldersToDirectory(folders); - } - - try - { - if (zoomContacts.Count == 0) return directory; - { - foreach (Contact c in zoomContacts) - { - var contact = new ZoomDirectoryContact {Name = c.ScreenName, ContactId = c.Jid}; - - if (folders.Count > 0) - { - contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; - } - - contacts.Add(contact); - } - - directory.AddContactsToDirectory(contacts); - } - } - catch (Exception e) - { - Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e); - } - - return directory; - } - } - - public enum eCallStatus - { - UNKNOWN, - NOT_IN_MEETING, - CONNECTING_MEETING, - IN_MEETING, - LOGGED_OUT - } - - public class ClosedCaption - { - public bool Available { get; set; } - } - - public class Call : NotifiableObject - { - private eCallStatus _status; - private List _participants; - - public bool IsInCall; - - public eCallStatus Status - { - get - { - return _status; - } - set - { - if (value != _status) - { - _status = value; - IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING; - NotifyPropertyChanged("Status"); - } - } - } - public ClosedCaption ClosedCaption { get; set; } - public List Participants - { - get - { - return _participants; - } - set - { - _participants = value; - NotifyPropertyChanged("Participants"); - } - } - public zEvent.SharingState Sharing { get; set; } - - public CallRecordInfo CallRecordInfo { get; set; } - - private zCommand.InfoResult _info; - - public zCommand.InfoResult Info - { - get - { - return _info; - } - set - { - _info = value; - NotifyPropertyChanged("Info"); - } - } - - public Call() - { - ClosedCaption = new ClosedCaption(); - Participants = new List(); - Sharing = new zEvent.SharingState(); - CallRecordInfo = new CallRecordInfo(); - Info = new zCommand.InfoResult(); - } - } - - public class Capabilities - { - public bool aec_Setting_Stored_In_ZR { get; set; } - public bool can_Dtmf_For_Invite_By_Phone { get; set; } - public bool can_Mute_On_Entry { get; set; } - public bool can_Ringing_In_Pstn_Call { get; set; } - public bool can_Switch_To_Specific_Camera { get; set; } - public bool is_Airhost_Disabled { get; set; } - public bool pstn_Call_In_Local_resentation { get; set; } - public bool support_Claim_Host { get; set; } - public bool support_Out_Room_Display { get; set; } - public bool support_Pin_And_Spotlight { get; set; } - public bool supports_Audio_Checkup { get; set; } - public bool supports_CheckIn { get; set; } - public bool supports_Cloud_PBX { get; set; } - public bool supports_Encrypted_Connection { get; set; } - public bool supports_Expel_User_Permanently { get; set; } - public bool supports_H323_DTMF { get; set; } - public bool supports_Hdmi_Cec_Control { get; set; } - public bool supports_Highly_Reverberant_Room { get; set; } - public bool supports_Loading_Contacts_Dynamically { get; set; } - public bool supports_Loading_Participants_Dynamically { get; set; } - public bool supports_Mic_Record_Test { get; set; } - public bool supports_Multi_Share { get; set; } - public bool supports_ShareCamera { get; set; } - public bool supports_Share_For_Floating_And_Content_Only { get; set; } - public bool supports_Sip_Call_out { get; set; } - public bool supports_Software_Audio_Processing { get; set; } - public bool supports_Web_Settings_Push { get; set; } - } - - public class Sharing : NotifiableObject - { - private string _dispState; - private string _password; - - public string directPresentationPairingCode { get; set; } - /// - /// Laptop client sharing key - /// - public string directPresentationSharingKey { get; set; } - public string dispState - { - get - { - return _dispState; - } - set - { - if (value != _dispState) - { - _dispState = value; - NotifyPropertyChanged("dispState"); - } - } - } - public bool isAirHostClientConnected { get; set; } - public bool isBlackMagicConnected { get; set; } - public bool isBlackMagicDataAvailable { get; set; } - public bool isDirectPresentationConnected { get; set; } - public bool isSharingBlackMagic { get; set; } - /// - /// IOS Airplay code - /// - public string password - { - get - { - return _password; - } - set - { - if (value != _password) - { - _password = value; - NotifyPropertyChanged("password"); - } - } - } - public string serverName { get; set; } - public string wifiName { get; set; } - } - - public class NumberOfScreens : NotifiableObject - { - private int _numOfScreens; - - [JsonProperty("NumberOfCECScreens")] - public int NumOfCECScreens { get; set; } - [JsonProperty("NumberOfScreens")] - public int NumOfScreens - { - get - { - return _numOfScreens; - } - set - { - if (value != _numOfScreens) - { - _numOfScreens = value; - NotifyPropertyChanged("NumberOfScreens"); - } - } - } - } - - /// - /// AudioInputLine/AudioOutputLine/VideoCameraLine list item - /// - public class AudioVideoInputOutputLineItem - { - public string Alias { get; set; } - public string Name { get; set; } - public bool Selected { get; set; } - public bool combinedDevice { get; set; } - public string id { get; set; } - public bool manuallySelected { get; set; } - public int numberOfCombinedDevices { get; set; } - public int ptzComId { get; set; } - } - - public class Video - { - public bool Optimizable { get; set; } - } - - public class CameraShare : NotifiableObject - { - private bool _canControlCamera; - private bool _isSharing; - - [JsonProperty("can_Control_Camera")] - public bool CanControlCamera - { - get - { - return _canControlCamera; - } - set - { - if (value != _canControlCamera) - { - _canControlCamera = value; - NotifyPropertyChanged("CanControlCamera"); - } - } - } - public string id { get; set; } - public bool is_Mirrored { get; set; } - [JsonProperty("is_Sharing")] - public bool IsSharing - { - get - { - return _isSharing; - } - set - { - if (value != _isSharing) - { - _isSharing = value; - NotifyPropertyChanged("IsSharing"); - } - } - } - public int pan_Tilt_Speed { get; set; } - - } - - public class Layout : NotifiableObject - { - // backer variables - private bool _can_Switch_Speaker_View; - private bool _can_Switch_Wall_View; - private bool _can_Switch_Share_On_All_Screens; - private bool _is_In_First_Page; - private bool _is_In_Last_Page; - private string _video_type; - - - public bool can_Adjust_Floating_Video { get; set; } - public bool can_Switch_Floating_Share_Content { get; set; } - - /// - /// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors. - /// - [JsonProperty("can_Switch_Share_On_All_Screens")] - public bool can_Switch_Share_On_All_Screens - { - get - { - return _can_Switch_Share_On_All_Screens; - } - set - { - if (value != _can_Switch_Share_On_All_Screens) - { - _can_Switch_Share_On_All_Screens = value; - NotifyPropertyChanged("can_Switch_Share_On_All_Screens"); - } - } - } - - /// - /// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails. - /// - [JsonProperty("can_Switch_Speaker_View")] - public bool can_Switch_Speaker_View - { - get - { - return _can_Switch_Speaker_View; - } - set - { - if (value != _can_Switch_Speaker_View) - { - _can_Switch_Speaker_View = value; - NotifyPropertyChanged("can_Switch_Speaker_View"); - } - } - } - - /// - /// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page. - /// - [JsonProperty("can_Switch_Wall_View")] - public bool can_Switch_Wall_View - { - get - { - return _can_Switch_Wall_View; - } - set - { - if (value != _can_Switch_Wall_View) - { - _can_Switch_Wall_View = value; - NotifyPropertyChanged("can_Switch_Wall_View"); - } - } - } - - [JsonProperty("is_In_First_Page")] - public bool is_In_First_Page - { - get - { - return _is_In_First_Page; - } - set - { - if (value != _is_In_First_Page) - { - _is_In_First_Page = value; - NotifyPropertyChanged("is_In_First_Page"); - } - } - } - - [JsonProperty("is_In_Last_Page")] - public bool is_In_Last_Page - { - get - { - return _is_In_Last_Page; - } - set - { - if (value != _is_In_Last_Page) - { - _is_In_Last_Page = value; - NotifyPropertyChanged("is_In_Last_Page"); - } - } - } - - public bool is_supported { get; set; } - public int video_Count_In_Current_Page { get; set; } - - /// - /// [Gallery | Strip] Indicates which mode applies: Strip or Gallery. - /// - [JsonProperty("video_type")] - public string video_type - { - get - { - return _video_type; - } - set - { - if (value != _video_type) - { - _video_type = value; - NotifyPropertyChanged("video_type"); - } - } - } - } - - public class CallRecordInfo - { - public bool canRecord { get; set; } - public bool emailRequired { get; set; } - public bool amIRecording { get; set; } - public bool meetingIsBeingRecorded { get; set; } - } - } - - /// - /// zEvent Class Structure - /// - public class zEvent - { - public class NeedWaitForHost - { - public bool Wait { get; set; } - } - - public class IncomingCallIndication - { - public string callerJID { get; set; } - public string calleeJID { get; set; } - public string meetingID { get; set; } - public string password { get; set; } - public string meetingOption { get; set; } - public long MeetingNumber { get; set; } - public string callerName { get; set; } - public string avatarURL { get; set; } - public int lifeTime { get; set; } - public bool accepted { get; set; } - } - - public class CallConnectError - { - public int error_code { get; set; } - public string error_message { get; set; } - } - - public class CallDisconnect - { - public bool Successful - { - get - { - return success == "on"; - } - } - - public string success { get; set; } - } - - public class Layout - { - public bool Sharethumb { get; set; } - } - - public class Call - { - public Layout Layout { get; set; } - } - - public class Client - { - public Call Call { get; set; } - } - - public enum eSharingState - { - None, - Connecting, - Sending, - Receiving, - Send_Receiving - } - - public class SharingState : NotifiableObject - { - private bool _paused; - private eSharingState _state; - - public bool IsSharing; - - [JsonProperty("paused")] - public bool Paused - { - get - { - return _paused; - } - set - { - if (value != _paused) - { - _paused = value; - NotifyPropertyChanged("Paused"); - } - } - } - [JsonProperty("state")] - public eSharingState State - { - get - { - return _state; - } - set - { - if (value != _state) - { - _state = value; - IsSharing = _state == eSharingState.Sending; - NotifyPropertyChanged("State"); - } - } - } - } - - public class PinStatusOfScreenNotification - { - - - [JsonProperty("can_be_pinned")] - public bool CanBePinned { get; set; } - [JsonProperty("can_pin_share")] - public bool CanPinShare { get; set; } - [JsonProperty("pinned_share_source_id")] - public int PinnedShareSourceId { get; set; } - [JsonProperty("pinned_user_id")] - public int PinnedUserId { get; set; } - [JsonProperty("screen_index")] - public int ScreenIndex { get; set; } - [JsonProperty("screen_layout")] - public int ScreenLayout { get; set; } - [JsonProperty("share_source_type")] - public int ShareSourceType { get; set; } - [JsonProperty("why_cannot_pin_share")] - public string WhyCannotPinShare { get; set; } - } - - public class PhoneCallStatus:NotifiableObject - { - private bool _isIncomingCall; - private string _peerDisplayName; - private string _peerNumber; - - private bool _offHook; - - public string CallId { get; set; } - public bool IsIncomingCall { - get { return _isIncomingCall; } - set - { - if(value == _isIncomingCall) return; - - _isIncomingCall = value; - NotifyPropertyChanged("IsIncomingCall"); - } } - - public string PeerDisplayName - { - get { return _peerDisplayName; } - set - { - if (value == _peerDisplayName) return; - _peerDisplayName = value; - NotifyPropertyChanged("PeerDisplayName"); - } - } - - public string PeerNumber - { - get { return _peerNumber; } - set - { - if (value == _peerNumber) return; - - _peerNumber = value; - NotifyPropertyChanged("PeerNumber"); - } - } - - public string PeerUri { get; set; } - - private ePhoneCallStatus _status; - public ePhoneCallStatus Status - { - get { return _status; } - set - { - _status = value; - OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted || - _status == ePhoneCallStatus.PhoneCallStatus_InCall || - _status == ePhoneCallStatus.PhoneCallStatus_Init || - _status == ePhoneCallStatus.PhoneCallStatus_Ringing; - } - } - - public bool OffHook - { - get { return _offHook; } - set - { - if (value == _offHook) return; - - _offHook = value; - NotifyPropertyChanged("OffHook"); - } - } - } - - public enum ePhoneCallStatus - { - PhoneCallStatus_Ringing, - PhoneCallStatus_Terminated, - PhoneCallStatus_Accepted, - PhoneCallStatus_InCall, - PhoneCallStatus_Init, - } - } - - /// - /// zConfiguration class structure - /// - public class zConfiguration - { - public class Sharing - { - [JsonProperty("optimize_video_sharing")] - public bool OptimizeVideoSharing { get; set; } - } - - public class Camera : NotifiableObject - { - private bool _mute; - - public bool Mute - { - get { return _mute; } - set - { - Debug.Console(1, "Camera Mute response received: {0}", value); - - if (value == _mute) return; - - _mute = value; - NotifyPropertyChanged("Mute"); - } - } - } - - public class Microphone : NotifiableObject - { - private bool _mute; - - public bool Mute - { - get - { - return _mute; - } - set - { - if(value != _mute) - { - _mute = value; - NotifyPropertyChanged("Mute"); - } - } - } - } - - [Flags] - public enum eLayoutStyle - { - None = 0, - Gallery = 1, - Speaker = 2, - Strip = 4, - ShareAll = 8, - } - - public enum eLayoutSize - { - Off, - Size1, - Size2, - Size3, - Strip - } - - public enum eLayoutPosition - { - Center, - Up, - Right, - UpRight, - Down, - DownRight, - Left, - UpLeft, - DownLeft - } - - public class Layout : NotifiableObject - { - private bool _shareThumb; - private eLayoutStyle _style; - private eLayoutSize _size; - private eLayoutPosition _position; - - public bool ShareThumb - { - get { return _shareThumb; } - set - { - if (value != _shareThumb) - { - _shareThumb = value; - NotifyPropertyChanged("ShareThumb"); - } - } - } - - public eLayoutStyle Style - { - get { return _style; } - set - { - if (value != _style) - { - _style = value; - NotifyPropertyChanged("Style"); - } - } - } - - public eLayoutSize Size - { - get { return _size; } - set - { - if (value != _size) - { - _size = value; - NotifyPropertyChanged("Size"); - } - } - } - - public eLayoutPosition Position - { - get { return _position; } - set - { - if (value != _position) - { - _position = value; - NotifyPropertyChanged("Position"); - } - } - } - } - - public class Lock - { - public bool Enable { get; set; } - } - - public class ClosedCaption - { - public bool Visible { get; set; } - public int FontSize { get; set; } - } - - public class MuteUserOnEntry - { - public bool Enable { get; set; } - } - - public class Call - { - public Sharing Sharing { get; set; } - public Camera Camera { get; set; } - public Microphone Microphone { get; set; } - public Layout Layout { get; set; } - public Lock Lock { get; set; } - public MuteUserOnEntry MuteUserOnEntry { get; set; } - public ClosedCaption ClosedCaption { get; set; } - - - public Call() - { - Sharing = new Sharing(); - Camera = new Camera(); - Microphone = new Microphone(); - Layout = new Layout(); - Lock = new Lock(); - MuteUserOnEntry = new MuteUserOnEntry(); - ClosedCaption = new ClosedCaption(); - } - } - - public class Audio - { - public Input Input { get; set; } - public Output Output { get; set; } - - public Audio() - { - Input = new Input(); - Output = new Output(); - } - } - - public class Input : Output - { - [JsonProperty("reduce_reverb")] - public bool ReduceReverb { get; set; } - } - - public class Output : NotifiableObject - { - private int _volume; - - [JsonProperty("volume")] - public int Volume - { - get - { - return _volume; - } - set - { - if (value != _volume) - { - _volume = value; - NotifyPropertyChanged("Volume"); - } - } - } - [JsonProperty("selectedId")] - public string SelectedId { get; set; } - [JsonProperty("is_sap_disabled")] - public bool IsSapDisabled { get; set; } - } - - public class Video : NotifiableObject - { - private bool _hideConfSelfVideo; - - [JsonProperty("hide_conf_self_video")] - public bool HideConfSelfVideo - { - get - { - return _hideConfSelfVideo; - } - set - { - if (value != _hideConfSelfVideo) - { - _hideConfSelfVideo = value; - NotifyPropertyChanged("HideConfSelfVideo"); - } - } - } - - public VideoCamera Camera { get; set; } - - public Video() - { - Camera = new VideoCamera(); - } - } - - public class VideoCamera : NotifiableObject - { - private string _selectedId; - - [JsonProperty("selectedId")] - public string SelectedId { - get - { - return _selectedId; - } - set - { - if (value != _selectedId) - { - _selectedId = value; - NotifyPropertyChanged("SelectedId"); - } - } - - } - public bool Mirror { get; set; } - } - - public class Client - { - public string appVersion { get; set; } - public string deviceSystem { get; set; } - - // This doesn't belong here, but there's a bug in the object structure of Zoom Room 5.6.3 that puts it here - public zConfiguration.Call Call { get; set; } - - public Client() - { - Call = new zConfiguration.Call(); - } - } - - } - - /// - /// zCommand class structure - /// - public class zCommand - { - public class BookingsListResult - { - [JsonProperty("accessRole")] - public string AccessRole { get; set; } - [JsonProperty("calendarChangeKey")] - public string CalendarChangeKey { get; set; } - [JsonProperty("calendarID")] - public string CalendarId { get; set; } - [JsonProperty("checkIn")] - public bool CheckIn { get; set; } - [JsonProperty("creatorEmail")] - public string CreatorEmail { get; set; } - [JsonProperty("creatorName")] - public string CreatorName { get; set; } - [JsonProperty("endTime")] - public DateTime EndTime { get; set; } - [JsonProperty("hostName")] - public string HostName { get; set; } - [JsonProperty("isInstantMeeting")] - public bool IsInstantMeeting { get; set; } - [JsonProperty("isPrivate")] - public bool IsPrivate { get; set; } - [JsonProperty("location")] - public string Location { get; set; } - [JsonProperty("meetingName")] - public string MeetingName { get; set; } - [JsonProperty("meetingNumber")] - public string MeetingNumber { get; set; } - [JsonProperty("scheduledFrom")] - public string ScheduledFrom { get; set; } - [JsonProperty("startTime")] - public DateTime StartTime { get; set; } - [JsonProperty("third_party")] - public ThirdParty ThirdParty { get; set; } - } - - public static List GetGenericMeetingsFromBookingResult(List bookings, - int minutesBeforeMeetingStart) - { - var rv = GetGenericMeetingsFromBookingResult(bookings); - - foreach (var meeting in rv) - { - meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart; - } - - return rv; - } - /// - /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class - /// - /// - /// - public static List GetGenericMeetingsFromBookingResult(List bookings) - { - var meetings = new List(); - - if (Debug.Level > 0) - { - Debug.Console(1, "Meetings List:\n"); - } - - foreach (var b in bookings) - { - var meeting = new Meeting(); - - if (b.MeetingNumber != null) - meeting.Id = b.MeetingNumber; - if (b.CreatorName != null) - meeting.Organizer = b.CreatorName; - if (b.MeetingName != null) - meeting.Title = b.MeetingName; - //if (b.Agenda != null) - // meeting.Agenda = b.Agenda.Value; - if (b.StartTime != null) - meeting.StartTime = b.StartTime; - if (b.EndTime != null) - meeting.EndTime = b.EndTime; - - meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public; - - // No meeting.Calls data exists for Zoom Rooms. Leaving out for now. - var now = DateTime.Now; - if (meeting.StartTime < now && meeting.EndTime < now) - { - Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title); - continue; - } - - meetings.Add(meeting); - - if (Debug.Level > 0) - { - Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer); - Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration); - Debug.Console(1, " Joinable: {0}\n", meeting.Joinable); - } - } - - meetings.OrderBy(m => m.StartTime); - - return meetings; - } - - public class HandStatus - { - [JsonProperty("is_raise_hand")] - public bool IsRaiseHand { get; set; } - [JsonProperty("is_valid")] - public bool IsValid { get; set; } - [JsonProperty("time_stamp")] - public string TimeStamp { get; set; } - } - - public class ListParticipant - { - [JsonProperty("audio_status state")] - public string AudioStatusState { get; set; } - [JsonProperty("audio_status type")] - public string AudioStatusType { get; set; } - [JsonProperty("avatar_url")] - public string AvatarUrl { get; set; } - [JsonProperty("camera_status am_i_controlling")] - public bool CameraStatusAmIControlling { get; set; } - [JsonProperty("camera_status can_i_request_control")] - public bool CameraStatusCanIRequestConrol { get; set; } - [JsonProperty("camera_status can_move_camera")] - public bool CameraStatusCanMoveCamera { get; set; } - [JsonProperty("camera_status can_switch_camera")] - public bool CameraStatusCanSwitchCamera { get; set; } - [JsonProperty("camera_status can_zoom_camera")] - public bool CameraStatusCanZoomCamera { get; set; } - [JsonProperty("can_edit_closed_caption")] - public bool CanEditClosedCaption { get; set; } - [JsonProperty("can_record")] - public bool CanRecord { get; set; } - [JsonProperty("event")] - public string Event { get; set; } - [JsonProperty("hand_status")] - public HandStatus HandStatus { get; set; } - [JsonProperty("isCohost")] - public bool IsCohost { get; set; } - [JsonProperty("is_client_support_closed_caption")] - public bool IsClientSupportClosedCaption { get; set; } - [JsonProperty("is_client_support_coHost")] - public bool IsClientSupportCoHost { get; set; } - [JsonProperty("is_host")] - public bool IsHost { get; set; } - [JsonProperty("is_myself")] - public bool IsMyself { get; set; } - [JsonProperty("is_recording")] - public bool IsRecording { get; set; } - [JsonProperty("is_video_can_mute_byHost")] - public bool IsVideoCanMuteByHost { get; set; } - [JsonProperty("is_video_can_unmute_byHost")] - public bool IsVideoCanUnmuteByHost { get; set; } - [JsonProperty("local_recording_disabled")] - public bool LocalRecordingDisabled { get; set; } - [JsonProperty("user_id")] - public int UserId { get; set; } - [JsonProperty("user_name")] - public string UserName { get; set; } - [JsonProperty("user_type")] - public string UserType { get; set; } - [JsonProperty("video_status has_source")] - public bool VideoStatusHasSource { get; set; } - [JsonProperty("video_status is_receiving")] - public bool VideoStatusIsReceiving { get; set; } - [JsonProperty("video_status is_sending")] - public bool VideoStatusIsSending { get; set; } - - public ListParticipant() - { - HandStatus = new HandStatus(); - } - - public static List GetGenericParticipantListFromParticipantsResult( - List participants) - { - return - participants.Select( - p => - new Participant - { - UserId = p.UserId, - Name = p.UserName, - IsHost = p.IsHost, - CanMuteVideo = p.IsVideoCanMuteByHost, - CanUnmuteVideo = p.IsVideoCanUnmuteByHost, - AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", - VideoMuteFb = p.VideoStatusIsSending, - HandIsRaisedFb = p.HandStatus.IsValid && p.HandStatus.IsRaiseHand, - }).ToList(); - } - } - - public class CallinCountryList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class CalloutCountryList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class TollFreeCallinList - { - public int code { get; set; } - public string display_number { get; set; } - public string id { get; set; } - public string name { get; set; } - public string number { get; set; } - } - - public class Info - { - public List callin_country_list { get; set; } - public List callout_country_list { get; set; } - public List toll_free_callin_list { get; set; } - } - - public class ThirdParty - { - public string h323_address { get; set; } - public string meeting_number { get; set; } - public string service_provider { get; set; } - public string sip_address { get; set; } - } - - public class MeetingListItem - { - public string accessRole { get; set; } - public string calendarChangeKey { get; set; } - public string calendarID { get; set; } - public bool checkIn { get; set; } - public string creatorEmail { get; set; } - public string creatorName { get; set; } - public string endTime { get; set; } - public string hostName { get; set; } - public bool isInstantMeeting { get; set; } - public bool isPrivate { get; set; } - public string location { get; set; } - public string meetingName { get; set; } - public string meetingNumber { get; set; } - public string scheduledFrom { get; set; } - public string startTime { get; set; } - public ThirdParty third_party { get; set; } - - public MeetingListItem() - { - third_party = new ThirdParty(); - } - } - - public class InfoResult - { - public Info Info { get; set; } - public bool am_i_original_host { get; set; } - public string default_callin_country { get; set; } - public string dialIn { get; set; } - public string international_url { get; set; } - public string invite_email_content { get; set; } - public string invite_email_subject { get; set; } - public bool is_callin_country_list_available { get; set; } - public bool is_calling_room_system_enabled { get; set; } - public bool is_toll_free_callin_list_available { get; set; } - public bool is_view_only { get; set; } - public bool is_waiting_room { get; set; } - public bool is_webinar { get; set; } - public string meeting_id { get; set; } - public MeetingListItem meeting_list_item { get; set; } - public string meeting_password { get; set; } - public string meeting_type { get; set; } - public int my_userid { get; set; } - public int participant_id { get; set; } - public string real_meeting_id { get; set; } - public string schedule_option { get; set; } - public string schedule_option2 { get; set; } - public string support_callout_type { get; set; } - public string toll_free_number { get; set; } - public string user_type { get; set; } - - public InfoResult() - { - Info = new Info(); - meeting_list_item = new MeetingListItem(); - } - } - - public class Phonebook - { - public List Contacts { get; set; } - public int Limit { get; set; } - public int Offset { get; set; } - } - } + public enum eZoomRoomResponseType + { + zEvent, + zStatus, + zConfiguration, + zCommand + } + + public abstract class NotifiableObject : INotifyPropertyChanged + { + #region INotifyPropertyChanged Members + + public event PropertyChangedEventHandler PropertyChanged; + + protected void NotifyPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + #endregion + } + + /// + /// Used to track the current status of a ZoomRoom + /// + public class ZoomRoomStatus + { + public zStatus.Login Login { get; set; } + public zStatus.SystemUnit SystemUnit { get; set; } + public zStatus.Phonebook Phonebook { get; set; } + public zStatus.Call Call { get; set; } + public zStatus.Capabilities Capabilities { get; set; } + public zStatus.Sharing Sharing { get; set; } + public zStatus.NumberOfScreens NumberOfScreens { get; set; } + public zStatus.Layout Layout { get; set; } + public zStatus.Video Video { get; set; } + public zStatus.CameraShare CameraShare { get; set; } + public List AudioInputs { get; set; } + public List AudioOuputs { get; set; } + public List Cameras { get; set; } + public zEvent.PhoneCallStatus PhoneCall { get; set; } + + public ZoomRoomStatus() + { + Login = new zStatus.Login(); + SystemUnit = new zStatus.SystemUnit(); + Phonebook = new zStatus.Phonebook(); + Call = new zStatus.Call(); + Capabilities = new zStatus.Capabilities(); + Sharing = new zStatus.Sharing(); + NumberOfScreens = new zStatus.NumberOfScreens(); + Layout = new zStatus.Layout(); + Video = new zStatus.Video(); + CameraShare = new zStatus.CameraShare(); + AudioInputs = new List(); + AudioOuputs = new List(); + Cameras = new List(); + PhoneCall = new zEvent.PhoneCallStatus(); + } + } + + /// + /// Used to track the current configuration of a ZoomRoom + /// + public class ZoomRoomConfiguration + { + public zConfiguration.Call Call { get; set; } + public zConfiguration.Audio Audio { get; set; } + public zConfiguration.Video Video { get; set; } + public zConfiguration.Client Client { get; set; } + public zConfiguration.Camera Camera { get; set; } + + public ZoomRoomConfiguration() + { + Call = new zConfiguration.Call(); + Audio = new zConfiguration.Audio(); + Video = new zConfiguration.Video(); + Client = new zConfiguration.Client(); + Camera = new zConfiguration.Camera(); + } + } + + /// + /// Represents a response from a ZoomRoom system + /// + public class Response + { + public Status Status { get; set; } + public bool Sync { get; set; } + [JsonProperty("topKey")] + public string TopKey { get; set; } + [JsonProperty("type")] + public string Type { get; set; } + + public Response() + { + Status = new Status(); + } + } + + public class Status + { + [JsonProperty("message")] + public string Message { get; set; } + [JsonProperty("state")] + public string State { get; set; } + } + + + /// + /// zStatus class stucture + /// + public class zStatus + { + public class Login + { + [JsonProperty("ZAAPI Release")] + public string ZAAPIRelease { get; set; } + [JsonProperty("Zoom Room Release")] + public string ZoomRoomRelease { get; set; } + } + + public class SystemUnit + { + [JsonProperty("email")] + public string Email { get; set; } + [JsonProperty("login_type")] + public string LoginType { get; set; } + [JsonProperty("meeting_number")] + public string MeetingNumber { get; set; } + [JsonProperty("platform")] + public string Platform { get; set; } + [JsonProperty("room_info")] + public RoomInfo RoomInfo { get; set; } + [JsonProperty("room_version")] + public string RoomVersion { get; set; } + + public SystemUnit() + { + RoomInfo = new RoomInfo(); + } + } + + public class RoomInfo + { + [JsonProperty("account_email")] + public string AccountEmail { get; set; } + [JsonProperty("display_version")] + public string DisplayVersion { get; set; } + [JsonProperty("is_auto_answer_enabled")] + public bool AutoAnswerIsEnabled { get; set; } + [JsonProperty("is_auto_answer_selected")] + public bool AutoAnswerIsSelected { get; set; } + [JsonProperty("room_name")] + public string RoomName { get; set; } + } + + public class CloudPbxInfo + { + [JsonProperty("company_number")] + public string CompanyNumber { get; set; } + [JsonProperty("extension")] + public string Extension { get; set; } + [JsonProperty("isValid")] + public bool IsValid { get; set; } + } + + public enum ePresence + { + PRESENCE_OFFLINE, + PRESENCE_ONLINE, + PRESENCE_AWAY, + PRESENCE_BUSY, + PRESENCE_DND + } + + public class Contact + { + [JsonProperty("avatarURL")] + public string AvatarURL { get; set; } + [JsonProperty("cloud_pbx_info")] + public CloudPbxInfo CloudPbxInfo { get; set; } + [JsonProperty("email")] + public string Email { get; set; } + [JsonProperty("firstName")] + public string FirstName { get; set; } + [JsonProperty("index")] + public int Index { get; set; } + [JsonProperty("isLegacy")] + public bool IsLegacy { get; set; } + [JsonProperty("isZoomRoom")] + public bool IsZoomRoom { get; set; } + [JsonProperty("jid")] + public string Jid { get; set; } + [JsonProperty("lastName")] + public string LastName { get; set; } + [JsonProperty("onDesktop")] + public bool OnDesktop { get; set; } + [JsonProperty("onMobile")] + public bool OnMobile { get; set; } + [JsonProperty("phoneNumber")] + public string PhoneNumber { get; set; } + [JsonProperty("presence")] + public ePresence Presence { get; set; } + [JsonProperty("presence_status")] + public int PresenceStatus { get; set; } + [JsonProperty("screenName")] + public string ScreenName { get; set; } + [JsonProperty("sip_phone_number")] + public string SipPhoneNumber { get; set; } + + + public Contact() + { + CloudPbxInfo = new CloudPbxInfo(); + } + } + + /// + /// Used to be able to inplement IInvitableContact on DirectoryContact + /// + public class ZoomDirectoryContact : DirectoryContact, IInvitableContact + { + + } + + public class Phonebook + { + [JsonProperty("Contacts")] + public List Contacts { get; set; } + + public Phonebook() + { + Contacts = new List(); + } + + /// + /// Converts from zStatus.Contact types to generic directory items + /// + /// + public static CodecDirectory ConvertZoomContactsToGeneric(List zoomContacts) + { + var directory = new CodecDirectory(); + + var folders = new List(); + + var roomFolder = new DirectoryFolder(); + + var contactFolder = new DirectoryFolder(); + + var contacts = new List(); + + // Check if there are any zoom rooms + var zoomRooms = zoomContacts.FindAll(c => c.IsZoomRoom); + + if (zoomRooms.Count > 0) + { + // If so, setup a rooms and contacts folder and add them. + roomFolder.Name = "Rooms"; + roomFolder.ParentFolderId = "root"; + roomFolder.FolderId = "rooms"; + + contactFolder.Name = "Contacts"; + contactFolder.ParentFolderId = "root"; + contactFolder.FolderId = "contacts"; + + folders.Add(roomFolder); + folders.Add(contactFolder); + + directory.AddFoldersToDirectory(folders); + } + + try + { + if (zoomContacts.Count == 0) return directory; + { + foreach (Contact c in zoomContacts) + { + var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; + + if (folders.Count > 0) + { + contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; + } + + contacts.Add(contact); + } + + directory.AddContactsToDirectory(contacts); + } + } + catch (Exception e) + { + Debug.Console(1, "Error converting Zoom Phonebook results to generic: {0}", e); + } + + return directory; + } + } + + public enum eCallStatus + { + UNKNOWN, + NOT_IN_MEETING, + CONNECTING_MEETING, + IN_MEETING, + LOGGED_OUT + } + + public class ClosedCaption + { + public bool Available { get; set; } + } + + public class Call : NotifiableObject + { + private eCallStatus _status; + private List _participants; + + public bool IsInCall; + + public eCallStatus Status + { + get + { + return _status; + } + set + { + if (value != _status) + { + _status = value; + IsInCall = _status == eCallStatus.IN_MEETING || _status == eCallStatus.CONNECTING_MEETING; + NotifyPropertyChanged("Status"); + } + } + } + public ClosedCaption ClosedCaption { get; set; } + public List Participants + { + get + { + return _participants; + } + set + { + _participants = value; + NotifyPropertyChanged("Participants"); + } + } + public zEvent.SharingState Sharing { get; set; } + + public CallRecordInfo CallRecordInfo { get; set; } + + private zCommand.InfoResult _info; + + public zCommand.InfoResult Info + { + get + { + return _info; + } + set + { + _info = value; + NotifyPropertyChanged("Info"); + } + } + + public Call() + { + ClosedCaption = new ClosedCaption(); + Participants = new List(); + Sharing = new zEvent.SharingState(); + CallRecordInfo = new CallRecordInfo(); + Info = new zCommand.InfoResult(); + } + } + + public class Capabilities + { + public bool aec_Setting_Stored_In_ZR { get; set; } + public bool can_Dtmf_For_Invite_By_Phone { get; set; } + public bool can_Mute_On_Entry { get; set; } + public bool can_Ringing_In_Pstn_Call { get; set; } + public bool can_Switch_To_Specific_Camera { get; set; } + public bool is_Airhost_Disabled { get; set; } + public bool pstn_Call_In_Local_resentation { get; set; } + public bool support_Claim_Host { get; set; } + public bool support_Out_Room_Display { get; set; } + public bool support_Pin_And_Spotlight { get; set; } + public bool supports_Audio_Checkup { get; set; } + public bool supports_CheckIn { get; set; } + public bool supports_Cloud_PBX { get; set; } + public bool supports_Encrypted_Connection { get; set; } + public bool supports_Expel_User_Permanently { get; set; } + public bool supports_H323_DTMF { get; set; } + public bool supports_Hdmi_Cec_Control { get; set; } + public bool supports_Highly_Reverberant_Room { get; set; } + public bool supports_Loading_Contacts_Dynamically { get; set; } + public bool supports_Loading_Participants_Dynamically { get; set; } + public bool supports_Mic_Record_Test { get; set; } + public bool supports_Multi_Share { get; set; } + public bool supports_ShareCamera { get; set; } + public bool supports_Share_For_Floating_And_Content_Only { get; set; } + public bool supports_Sip_Call_out { get; set; } + public bool supports_Software_Audio_Processing { get; set; } + public bool supports_Web_Settings_Push { get; set; } + } + + public class Sharing : NotifiableObject + { + private string _dispState; + private string _password; + + public string directPresentationPairingCode { get; set; } + /// + /// Laptop client sharing key + /// + public string directPresentationSharingKey { get; set; } + public string dispState + { + get + { + return _dispState; + } + set + { + if (value != _dispState) + { + _dispState = value; + NotifyPropertyChanged("dispState"); + } + } + } + public bool isAirHostClientConnected { get; set; } + public bool isBlackMagicConnected { get; set; } + public bool isBlackMagicDataAvailable { get; set; } + public bool isDirectPresentationConnected { get; set; } + public bool isSharingBlackMagic { get; set; } + /// + /// IOS Airplay code + /// + public string password + { + get + { + return _password; + } + set + { + if (value != _password) + { + _password = value; + NotifyPropertyChanged("password"); + } + } + } + public string serverName { get; set; } + public string wifiName { get; set; } + } + + public class NumberOfScreens : NotifiableObject + { + private int _numOfScreens; + + [JsonProperty("NumberOfCECScreens")] + public int NumOfCECScreens { get; set; } + [JsonProperty("NumberOfScreens")] + public int NumOfScreens + { + get + { + return _numOfScreens; + } + set + { + if (value != _numOfScreens) + { + _numOfScreens = value; + NotifyPropertyChanged("NumberOfScreens"); + } + } + } + } + + /// + /// AudioInputLine/AudioOutputLine/VideoCameraLine list item + /// + public class AudioVideoInputOutputLineItem + { + public string Alias { get; set; } + public string Name { get; set; } + public bool Selected { get; set; } + public bool combinedDevice { get; set; } + public string id { get; set; } + public bool manuallySelected { get; set; } + public int numberOfCombinedDevices { get; set; } + public int ptzComId { get; set; } + } + + public class Video + { + public bool Optimizable { get; set; } + } + + public class CameraShare : NotifiableObject + { + private bool _canControlCamera; + private bool _isSharing; + + [JsonProperty("can_Control_Camera")] + public bool CanControlCamera + { + get + { + return _canControlCamera; + } + set + { + if (value != _canControlCamera) + { + _canControlCamera = value; + NotifyPropertyChanged("CanControlCamera"); + } + } + } + public string id { get; set; } + public bool is_Mirrored { get; set; } + [JsonProperty("is_Sharing")] + public bool IsSharing + { + get + { + return _isSharing; + } + set + { + if (value != _isSharing) + { + _isSharing = value; + NotifyPropertyChanged("IsSharing"); + } + } + } + public int pan_Tilt_Speed { get; set; } + + } + + public class Layout : NotifiableObject + { + // backer variables + private bool _can_Switch_Speaker_View; + private bool _can_Switch_Wall_View; + private bool _can_Switch_Share_On_All_Screens; + private bool _is_In_First_Page; + private bool _is_In_Last_Page; + private string _video_type; + + + public bool can_Adjust_Floating_Video { get; set; } + public bool can_Switch_Floating_Share_Content { get; set; } + + /// + /// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors. + /// + [JsonProperty("can_Switch_Share_On_All_Screens")] + public bool can_Switch_Share_On_All_Screens + { + get + { + return _can_Switch_Share_On_All_Screens; + } + set + { + if (value != _can_Switch_Share_On_All_Screens) + { + _can_Switch_Share_On_All_Screens = value; + NotifyPropertyChanged("can_Switch_Share_On_All_Screens"); + } + } + } + + /// + /// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails. + /// + [JsonProperty("can_Switch_Speaker_View")] + public bool can_Switch_Speaker_View + { + get + { + return _can_Switch_Speaker_View; + } + set + { + if (value != _can_Switch_Speaker_View) + { + _can_Switch_Speaker_View = value; + NotifyPropertyChanged("can_Switch_Speaker_View"); + } + } + } + + /// + /// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page. + /// + [JsonProperty("can_Switch_Wall_View")] + public bool can_Switch_Wall_View + { + get + { + return _can_Switch_Wall_View; + } + set + { + if (value != _can_Switch_Wall_View) + { + _can_Switch_Wall_View = value; + NotifyPropertyChanged("can_Switch_Wall_View"); + } + } + } + + [JsonProperty("is_In_First_Page")] + public bool is_In_First_Page + { + get + { + return _is_In_First_Page; + } + set + { + if (value != _is_In_First_Page) + { + _is_In_First_Page = value; + NotifyPropertyChanged("is_In_First_Page"); + } + } + } + + [JsonProperty("is_In_Last_Page")] + public bool is_In_Last_Page + { + get + { + return _is_In_Last_Page; + } + set + { + if (value != _is_In_Last_Page) + { + _is_In_Last_Page = value; + NotifyPropertyChanged("is_In_Last_Page"); + } + } + } + + public bool is_supported { get; set; } + public int video_Count_In_Current_Page { get; set; } + + /// + /// [Gallery | Strip] Indicates which mode applies: Strip or Gallery. + /// + [JsonProperty("video_type")] + public string video_type + { + get + { + return _video_type; + } + set + { + if (value != _video_type) + { + _video_type = value; + NotifyPropertyChanged("video_type"); + } + } + } + } + + public class CallRecordInfo + { + public bool canRecord { get; set; } + public bool emailRequired { get; set; } + public bool amIRecording { get; set; } + public bool meetingIsBeingRecorded { get; set; } + } + } + + /// + /// zEvent Class Structure + /// + public class zEvent + { + public class NeedWaitForHost + { + public bool Wait { get; set; } + } + + public class IncomingCallIndication + { + public string callerJID { get; set; } + public string calleeJID { get; set; } + public string meetingID { get; set; } + public string password { get; set; } + public string meetingOption { get; set; } + public long MeetingNumber { get; set; } + public string callerName { get; set; } + public string avatarURL { get; set; } + public int lifeTime { get; set; } + public bool accepted { get; set; } + } + + public class CallConnectError + { + public int error_code { get; set; } + public string error_message { get; set; } + } + + public class CallDisconnect + { + public bool Successful + { + get + { + return success == "on"; + } + } + + public string success { get; set; } + } + + public class Layout + { + public bool Sharethumb { get; set; } + } + + public class Call + { + public Layout Layout { get; set; } + } + + public class Client + { + public Call Call { get; set; } + } + + public enum eSharingState + { + None, + Connecting, + Sending, + Receiving, + Send_Receiving + } + + public class SharingState : NotifiableObject + { + private bool _paused; + private eSharingState _state; + + public bool IsSharing; + + [JsonProperty("paused")] + public bool Paused + { + get + { + return _paused; + } + set + { + if (value != _paused) + { + _paused = value; + NotifyPropertyChanged("Paused"); + } + } + } + [JsonProperty("state")] + public eSharingState State + { + get + { + return _state; + } + set + { + if (value != _state) + { + _state = value; + IsSharing = _state == eSharingState.Sending; + NotifyPropertyChanged("State"); + } + } + } + } + + public class PinStatusOfScreenNotification + { + + + [JsonProperty("can_be_pinned")] + public bool CanBePinned { get; set; } + [JsonProperty("can_pin_share")] + public bool CanPinShare { get; set; } + [JsonProperty("pinned_share_source_id")] + public int PinnedShareSourceId { get; set; } + [JsonProperty("pinned_user_id")] + public int PinnedUserId { get; set; } + [JsonProperty("screen_index")] + public int ScreenIndex { get; set; } + [JsonProperty("screen_layout")] + public int ScreenLayout { get; set; } + [JsonProperty("share_source_type")] + public int ShareSourceType { get; set; } + [JsonProperty("why_cannot_pin_share")] + public string WhyCannotPinShare { get; set; } + } + + public class PhoneCallStatus : NotifiableObject + { + private bool _isIncomingCall; + private string _peerDisplayName; + private string _peerNumber; + + private bool _offHook; + + public string CallId { get; set; } + public bool IsIncomingCall + { + get { return _isIncomingCall; } + set + { + if (value == _isIncomingCall) return; + + _isIncomingCall = value; + NotifyPropertyChanged("IsIncomingCall"); + } + } + + public string PeerDisplayName + { + get { return _peerDisplayName; } + set + { + if (value == _peerDisplayName) return; + _peerDisplayName = value; + NotifyPropertyChanged("PeerDisplayName"); + } + } + + public string PeerNumber + { + get { return _peerNumber; } + set + { + if (value == _peerNumber) return; + + _peerNumber = value; + NotifyPropertyChanged("PeerNumber"); + } + } + + public string PeerUri { get; set; } + + private ePhoneCallStatus _status; + public ePhoneCallStatus Status + { + get { return _status; } + set + { + _status = value; + OffHook = _status == ePhoneCallStatus.PhoneCallStatus_Accepted || + _status == ePhoneCallStatus.PhoneCallStatus_InCall || + _status == ePhoneCallStatus.PhoneCallStatus_Init || + _status == ePhoneCallStatus.PhoneCallStatus_Ringing; + } + } + + public bool OffHook + { + get { return _offHook; } + set + { + if (value == _offHook) return; + + _offHook = value; + NotifyPropertyChanged("OffHook"); + } + } + } + + public enum ePhoneCallStatus + { + PhoneCallStatus_Ringing, + PhoneCallStatus_Terminated, + PhoneCallStatus_Accepted, + PhoneCallStatus_InCall, + PhoneCallStatus_Init, + } + } + + /// + /// zConfiguration class structure + /// + public class zConfiguration + { + public class Sharing + { + [JsonProperty("optimize_video_sharing")] + public bool OptimizeVideoSharing { get; set; } + } + + public class Camera : NotifiableObject + { + private bool _mute; + + public bool Mute + { + get { return _mute; } + set + { + Debug.Console(1, "Camera Mute response received: {0}", value); + + if (value == _mute) return; + + _mute = value; + NotifyPropertyChanged("Mute"); + } + } + } + + public class Microphone : NotifiableObject + { + private bool _mute; + + public bool Mute + { + get + { + return _mute; + } + set + { + if (value != _mute) + { + _mute = value; + NotifyPropertyChanged("Mute"); + } + } + } + } + + [Flags] + public enum eLayoutStyle + { + None = 0, + Gallery = 1, + Speaker = 2, + Strip = 4, + ShareAll = 8, + } + + public enum eLayoutSize + { + Off, + Size1, + Size2, + Size3, + Strip + } + + public enum eLayoutPosition + { + Center, + Up, + Right, + UpRight, + Down, + DownRight, + Left, + UpLeft, + DownLeft + } + + public class Layout : NotifiableObject + { + private bool _shareThumb; + private eLayoutStyle _style; + private eLayoutSize _size; + private eLayoutPosition _position; + + public bool ShareThumb + { + get { return _shareThumb; } + set + { + if (value != _shareThumb) + { + _shareThumb = value; + NotifyPropertyChanged("ShareThumb"); + } + } + } + + public eLayoutStyle Style + { + get { return _style; } + set + { + if (value != _style) + { + _style = value; + NotifyPropertyChanged("Style"); + } + } + } + + public eLayoutSize Size + { + get { return _size; } + set + { + if (value != _size) + { + _size = value; + NotifyPropertyChanged("Size"); + } + } + } + + public eLayoutPosition Position + { + get { return _position; } + set + { + if (value != _position) + { + _position = value; + NotifyPropertyChanged("Position"); + } + } + } + } + + public class Lock + { + public bool Enable { get; set; } + } + + public class ClosedCaption + { + public bool Visible { get; set; } + public int FontSize { get; set; } + } + + public class MuteUserOnEntry + { + public bool Enable { get; set; } + } + + public class Call + { + public Sharing Sharing { get; set; } + public Camera Camera { get; set; } + public Microphone Microphone { get; set; } + public Layout Layout { get; set; } + public Lock Lock { get; set; } + public MuteUserOnEntry MuteUserOnEntry { get; set; } + public ClosedCaption ClosedCaption { get; set; } + + + public Call() + { + Sharing = new Sharing(); + Camera = new Camera(); + Microphone = new Microphone(); + Layout = new Layout(); + Lock = new Lock(); + MuteUserOnEntry = new MuteUserOnEntry(); + ClosedCaption = new ClosedCaption(); + } + } + + public class Audio + { + public Input Input { get; set; } + public Output Output { get; set; } + + public Audio() + { + Input = new Input(); + Output = new Output(); + } + } + + public class Input : Output + { + [JsonProperty("reduce_reverb")] + public bool ReduceReverb { get; set; } + } + + public class Output : NotifiableObject + { + private int _volume; + + [JsonProperty("volume")] + public int Volume + { + get + { + return _volume; + } + set + { + if (value != _volume) + { + _volume = value; + NotifyPropertyChanged("Volume"); + } + } + } + [JsonProperty("selectedId")] + public string SelectedId { get; set; } + [JsonProperty("is_sap_disabled")] + public bool IsSapDisabled { get; set; } + } + + public class Video : NotifiableObject + { + private bool _hideConfSelfVideo; + + [JsonProperty("hide_conf_self_video")] + public bool HideConfSelfVideo + { + get + { + return _hideConfSelfVideo; + } + set + { + if (value != _hideConfSelfVideo) + { + _hideConfSelfVideo = value; + NotifyPropertyChanged("HideConfSelfVideo"); + } + } + } + + public VideoCamera Camera { get; set; } + + public Video() + { + Camera = new VideoCamera(); + } + } + + public class VideoCamera : NotifiableObject + { + private string _selectedId; + + [JsonProperty("selectedId")] + public string SelectedId + { + get + { + return _selectedId; + } + set + { + if (value != _selectedId) + { + _selectedId = value; + NotifyPropertyChanged("SelectedId"); + } + } + + } + public bool Mirror { get; set; } + } + + public class Client + { + public string appVersion { get; set; } + public string deviceSystem { get; set; } + + // This doesn't belong here, but there's a bug in the object structure of Zoom Room 5.6.3 that puts it here + public zConfiguration.Call Call { get; set; } + + public Client() + { + Call = new zConfiguration.Call(); + } + } + + } + + /// + /// zCommand class structure + /// + public class zCommand + { + public class BookingsListResult + { + [JsonProperty("accessRole")] + public string AccessRole { get; set; } + [JsonProperty("calendarChangeKey")] + public string CalendarChangeKey { get; set; } + [JsonProperty("calendarID")] + public string CalendarId { get; set; } + [JsonProperty("checkIn")] + public bool CheckIn { get; set; } + [JsonProperty("creatorEmail")] + public string CreatorEmail { get; set; } + [JsonProperty("creatorName")] + public string CreatorName { get; set; } + [JsonProperty("endTime")] + public DateTime EndTime { get; set; } + [JsonProperty("hostName")] + public string HostName { get; set; } + [JsonProperty("isInstantMeeting")] + public bool IsInstantMeeting { get; set; } + [JsonProperty("isPrivate")] + public bool IsPrivate { get; set; } + [JsonProperty("location")] + public string Location { get; set; } + [JsonProperty("meetingName")] + public string MeetingName { get; set; } + [JsonProperty("meetingNumber")] + public string MeetingNumber { get; set; } + [JsonProperty("scheduledFrom")] + public string ScheduledFrom { get; set; } + [JsonProperty("startTime")] + public DateTime StartTime { get; set; } + [JsonProperty("third_party")] + public ThirdParty ThirdParty { get; set; } + } + + public static List GetGenericMeetingsFromBookingResult(List bookings, + int minutesBeforeMeetingStart) + { + var rv = GetGenericMeetingsFromBookingResult(bookings); + + foreach (var meeting in rv) + { + meeting.MinutesBeforeMeeting = minutesBeforeMeetingStart; + } + + return rv; + } + /// + /// Extracts the necessary meeting values from the Zoom bookings response and converts them to the generic class + /// + /// + /// + public static List GetGenericMeetingsFromBookingResult(List bookings) + { + var meetings = new List(); + + if (Debug.Level > 0) + { + Debug.Console(1, "Meetings List:\n"); + } + + foreach (var b in bookings) + { + var meeting = new Meeting(); + + if (b.MeetingNumber != null) + meeting.Id = b.MeetingNumber; + if (b.CreatorName != null) + meeting.Organizer = b.CreatorName; + if (b.MeetingName != null) + meeting.Title = b.MeetingName; + //if (b.Agenda != null) + // meeting.Agenda = b.Agenda.Value; + if (b.StartTime != null) + meeting.StartTime = b.StartTime; + if (b.EndTime != null) + meeting.EndTime = b.EndTime; + + meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public; + + // No meeting.Calls data exists for Zoom Rooms. Leaving out for now. + var now = DateTime.Now; + if (meeting.StartTime < now && meeting.EndTime < now) + { + Debug.Console(1, "Skipping meeting {0}. Meeting is in the past.", meeting.Title); + continue; + } + + meetings.Add(meeting); + + if (Debug.Level > 0) + { + Debug.Console(1, "Title: {0}, ID: {1}, Organizer: {2}", meeting.Title, meeting.Id, meeting.Organizer); + Debug.Console(1, " Start Time: {0}, End Time: {1}, Duration: {2}", meeting.StartTime, meeting.EndTime, meeting.Duration); + Debug.Console(1, " Joinable: {0}\n", meeting.Joinable); + } + } + + meetings.OrderBy(m => m.StartTime); + + return meetings; + } + + public class HandStatus + { + // example return of the "hand_status" object + // !!!! Note the properties contain ': ' within the property name !!! + //"hand_status": { + // "is_raise_hand: ": false, + // "is_valid: ": "on", + // "time_stamp: ": "11825083" + //}, + [JsonProperty("is_raise_hand: ")] + public bool IsRaiseHand { get; set; } + [JsonProperty("is_valid: ")] + public string IsValid { get; set; } + [JsonProperty("time_stamp: ")] + public string TimeStamp { get; set; } + /// + /// Retuns a boolean value if the participant hand state is raised and is valid (both need to be true) + /// + public bool HandIsRaisedAndValid + { + get { return IsValid != null && IsValid == "on" && IsRaiseHand; } + } + } + public class ListParticipant + { + [JsonProperty("audio_status state")] + public string AudioStatusState { get; set; } + [JsonProperty("audio_status type")] + public string AudioStatusType { get; set; } + [JsonProperty("avatar_url")] + public string AvatarUrl { get; set; } + [JsonProperty("camera_status am_i_controlling")] + public bool CameraStatusAmIControlling { get; set; } + [JsonProperty("camera_status can_i_request_control")] + public bool CameraStatusCanIRequestConrol { get; set; } + [JsonProperty("camera_status can_move_camera")] + public bool CameraStatusCanMoveCamera { get; set; } + [JsonProperty("camera_status can_switch_camera")] + public bool CameraStatusCanSwitchCamera { get; set; } + [JsonProperty("camera_status can_zoom_camera")] + public bool CameraStatusCanZoomCamera { get; set; } + [JsonProperty("can_edit_closed_caption")] + public bool CanEditClosedCaption { get; set; } + [JsonProperty("can_record")] + public bool CanRecord { get; set; } + [JsonProperty("event")] + public string Event { get; set; } + [JsonProperty("hand_status")] + public HandStatus HandStatus { get; set; } + [JsonProperty("isCohost")] + public bool IsCohost { get; set; } + [JsonProperty("is_client_support_closed_caption")] + public bool IsClientSupportClosedCaption { get; set; } + [JsonProperty("is_client_support_coHost")] + public bool IsClientSupportCoHost { get; set; } + [JsonProperty("is_host")] + public bool IsHost { get; set; } + [JsonProperty("is_myself")] + public bool IsMyself { get; set; } + [JsonProperty("is_recording")] + public bool IsRecording { get; set; } + [JsonProperty("is_video_can_mute_byHost")] + public bool IsVideoCanMuteByHost { get; set; } + [JsonProperty("is_video_can_unmute_byHost")] + public bool IsVideoCanUnmuteByHost { get; set; } + [JsonProperty("local_recording_disabled")] + public bool LocalRecordingDisabled { get; set; } + [JsonProperty("user_id")] + public int UserId { get; set; } + [JsonProperty("user_name")] + public string UserName { get; set; } + [JsonProperty("user_type")] + public string UserType { get; set; } + [JsonProperty("video_status has_source")] + public bool VideoStatusHasSource { get; set; } + [JsonProperty("video_status is_receiving")] + public bool VideoStatusIsReceiving { get; set; } + [JsonProperty("video_status is_sending")] + public bool VideoStatusIsSending { get; set; } + + public ListParticipant() + { + HandStatus = new HandStatus(); + } + + /// + /// Converts ZoomRoom pariticpant list response to an Essentials participant list + /// + /// + /// + public static List GetGenericParticipantListFromParticipantsResult( + List participants) + { + //return participants.Select(p => new Participant + // { + // UserId = p.UserId, + // Name = p.UserName, + // IsHost = p.IsHost, + // CanMuteVideo = p.IsVideoCanMuteByHost, + // CanUnmuteVideo = p.IsVideoCanUnmuteByHost, + // AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", + // VideoMuteFb = p.VideoStatusIsSending, + // HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid, + // }).ToList(); + + var sortedParticipants = SortParticipantListByHandStatus(participants); + return sortedParticipants.Select(p => new Participant + { + UserId = p.UserId, + Name = p.UserName, + IsHost = p.IsHost, + CanMuteVideo = p.IsVideoCanMuteByHost, + CanUnmuteVideo = p.IsVideoCanUnmuteByHost, + AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", + VideoMuteFb = p.VideoStatusIsSending, + HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid, + }).ToList(); + } + + /// + /// Will sort by hand-raise status and then alphabetically + /// + /// Zoom Room response list of participants + /// List + public static List SortParticipantListByHandStatus(List participants) + { + if (participants == null) + { + Debug.Console(1, "SortParticiapntListByHandStatu(participants == null)"); + return null; + } + + // debug testing + foreach (ListParticipant participant in participants) + { + Debug.Console(1, "{0} | IsValid: {1} | IsRaiseHand: {2} | HandIsRaisedAndValid: {3}", + participant.UserName, participant.HandStatus.IsValid, participant.HandStatus.IsRaiseHand.ToString(), participant.HandStatus.HandIsRaisedAndValid.ToString()); + } + + List handRaisedParticipantsList = participants.Where(p => p.HandStatus.HandIsRaisedAndValid).ToList(); + + if (handRaisedParticipantsList != null) + { + IOrderedEnumerable orderByDescending = handRaisedParticipantsList.OrderByDescending(p => p.HandStatus.TimeStamp); + + foreach (var participant in handRaisedParticipantsList) + Debug.Console(1, "handRaisedParticipantList: {0} | {1}", participant.UserName, participant.UserId); + } + + List allOtherParticipantsList = participants.Where(p => !p.HandStatus.HandIsRaisedAndValid).ToList(); + + if (allOtherParticipantsList != null) + { + allOtherParticipantsList.OrderBy(p => p.UserName); + + foreach (var participant in allOtherParticipantsList) + Debug.Console(1, "allOtherParticipantsList: {0} | {1}", participant.UserName, participant.UserId); + } + + // merge the lists + List sortedList = handRaisedParticipantsList.Union(allOtherParticipantsList).ToList(); + + // return the sorted list + return sortedList; + } + + } + + public class CallinCountryList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class CalloutCountryList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class TollFreeCallinList + { + public int code { get; set; } + public string display_number { get; set; } + public string id { get; set; } + public string name { get; set; } + public string number { get; set; } + } + + public class Info + { + public List callin_country_list { get; set; } + public List callout_country_list { get; set; } + public List toll_free_callin_list { get; set; } + } + + public class ThirdParty + { + public string h323_address { get; set; } + public string meeting_number { get; set; } + public string service_provider { get; set; } + public string sip_address { get; set; } + } + + public class MeetingListItem + { + public string accessRole { get; set; } + public string calendarChangeKey { get; set; } + public string calendarID { get; set; } + public bool checkIn { get; set; } + public string creatorEmail { get; set; } + public string creatorName { get; set; } + public string endTime { get; set; } + public string hostName { get; set; } + public bool isInstantMeeting { get; set; } + public bool isPrivate { get; set; } + public string location { get; set; } + public string meetingName { get; set; } + public string meetingNumber { get; set; } + public string scheduledFrom { get; set; } + public string startTime { get; set; } + public ThirdParty third_party { get; set; } + + public MeetingListItem() + { + third_party = new ThirdParty(); + } + } + + public class InfoResult + { + public Info Info { get; set; } + public bool am_i_original_host { get; set; } + public string default_callin_country { get; set; } + public string dialIn { get; set; } + public string international_url { get; set; } + public string invite_email_content { get; set; } + public string invite_email_subject { get; set; } + public bool is_callin_country_list_available { get; set; } + public bool is_calling_room_system_enabled { get; set; } + public bool is_toll_free_callin_list_available { get; set; } + public bool is_view_only { get; set; } + public bool is_waiting_room { get; set; } + public bool is_webinar { get; set; } + public string meeting_id { get; set; } + public MeetingListItem meeting_list_item { get; set; } + public string meeting_password { get; set; } + public string meeting_type { get; set; } + public int my_userid { get; set; } + public int participant_id { get; set; } + public string real_meeting_id { get; set; } + public string schedule_option { get; set; } + public string schedule_option2 { get; set; } + public string support_callout_type { get; set; } + public string toll_free_number { get; set; } + public string user_type { get; set; } + + public InfoResult() + { + Info = new Info(); + meeting_list_item = new MeetingListItem(); + } + } + + public class Phonebook + { + public List Contacts { get; set; } + public int Limit { get; set; } + public int Offset { get; set; } + } + } } \ No newline at end of file From c7cc98bff7b6498f8bcf69ab80599f3866000959 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 20 May 2021 19:32:11 -0500 Subject: [PATCH 228/480] Removed old TODO's from VideoCodecBase.cs. Marked TODO's for Issue #697. --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 4 ++-- .../VideoCodec/VideoCodecBase.cs | 12 ++---------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 5 ++--- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 00787a69..a8805a21 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -27,8 +27,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { event EventHandler AvailableLayoutsChanged; - BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func - BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [ ] Consider modifying to report button visibility in func + BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func + BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } 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 14f23082..dc9228ce 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 @@ -673,7 +673,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); } - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues private List _currentMeetings = new List(); private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) @@ -685,7 +684,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec codec.CodecSchedule.MeetingWarningMinutes = i; }); - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => { var mtg = 1; @@ -695,7 +693,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (_currentMeetings[index] != null) Dial(_currentMeetings[index]); }); - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => { var mtg = 2; @@ -705,7 +703,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (_currentMeetings[index] != null) Dial(_currentMeetings[index]); }); - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => { var mtg = 3; @@ -730,14 +728,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { var currentTime = DateTime.Now; - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues - // - changed var currentMeetings >> field _currentMeetings - //_currentMeetings.Clear(); _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); - // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues - // - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi - var meetingsData = UpdateMeetingsListXSig(_currentMeetings); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 1b8c5914..2301e544 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -870,7 +870,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom _jsonCurlyBraceCounter--; } - // TODO [X] 2021-05-12, jkd: turned off to reduce console traffic //Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter) @@ -2242,7 +2241,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void ComputeAvailableLayouts() { zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; - // TODO: #697 [ ] Compute the avaialble layouts and set the value of AvailableLayouts + // TODO: #697 [X] Compute the avaialble layouts and set the value of AvailableLayouts // Will need to test and confirm that this logic evaluates correctly if (Status.Layout.can_Switch_Wall_View) { @@ -2291,7 +2290,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (CanSwapContentWithThumbnailFeedback.BoolValue) { var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state - // TODO: #697 [ ] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback + // TODO: #697 [*] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback // to toggle the state SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); } From afe2046c812f34f92c977a27cd24d95aa3030bc6 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 7 Jun 2021 14:45:40 -0500 Subject: [PATCH 229/480] Added methods to select Call Layout Size. --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 4 + .../VideoCodec/ZoomRoom/ZoomRoom.cs | 39 ++++++- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 107 +++++++++++++++++- 3 files changed, 148 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index a8805a21..36499281 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -31,6 +31,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } + //StringFeedback LayoutSizeFeedback { get; } // TOOD: #714 [ ] Feature Layout Size ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } @@ -41,6 +42,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void LayoutTurnNextPage(); void LayoutTurnPreviousPage(); + + void GetCurrentLayoutSize(); // TOOD: #714 [ ] Feature Layout Size + void SetLayoutSize(ZoomRoom.zConfiguration.eLayoutSize layoutSize); // TOOD: #714 [ ] Feature Layout Size } public class LayoutInfoChangedEventArgs : EventArgs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 2301e544..ceead746 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1795,7 +1795,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + + // TOOD: #714 [ ] Feature Layout Size + trilist.SetSigFalseAction(joinMap.SetLayoutSizeOff.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Off)); + trilist.SetSigFalseAction(joinMap.SetLayoutSize1.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size1)); + trilist.SetSigFalseAction(joinMap.SetLayoutSize2.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size2)); + trilist.SetSigFalseAction(joinMap.SetLayoutSize3.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size3)); + trilist.SetSigFalseAction(joinMap.SetLayoutSizeStrip.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Strip)); + // TOOD: #714 [ ] Feature Layout Size + trilist.SetSigFalseAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, layoutsCodec.GetCurrentLayoutSize); + trilist.SetStringSigAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, (s) => + { + try + { + var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); + SetLayoutSize(size); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e); + } + }); } var pinCodec = this as IHasParticipantPinUnpin; @@ -2306,6 +2327,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("zCommand Call Layout TurnPage Forward: Off"); } + // TOOD: #714 [ ] Feature Layout Size + public zConfiguration.eLayoutSize LastSelectedLayoutSize { get; private set; } + + // TOOD: #714 [ ] Feature Layout Size + public void GetCurrentLayoutSize() + { + SendText("zConfiguration Call Layout Size"); + } + + // TOOD: #714 [ ] Feature Layout Size + public void SetLayoutSize(zConfiguration.eLayoutSize layoutSize) + { + LastSelectedLayoutSize = layoutSize; + SendText(String.Format("zConfiguration Call Layout Size: {0}", layoutSize.ToString())); + } + #endregion #region IHasCodecLayouts Members diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 07265d20..24cf65e8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -164,6 +164,96 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.DigitalSerial }); + // TOOD: #714 [ ] Feature Layout Size + //[JoinName("GetCurrentLayoutSize")] + //public JoinDataComplete GetCurrentLayoutSize = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 230, + // JoinSpan = 1 + // }, + // new JoinMetadata + // { + // Description = "Poll for the current layout size", + // JoinCapabilities = eJoinCapabilities.FromSIMPL, + // JoinType = eJoinType.Digital + // }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("SetLayoutSizeOff")] + public JoinDataComplete SetLayoutSizeOff = new JoinDataComplete( + new JoinData + { + JoinNumber = 231, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout size off", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("SetLayoutSize1")] + public JoinDataComplete SetLayoutSize1 = new JoinDataComplete( + new JoinData + { + JoinNumber = 232, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout size 1", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("SetLayoutSize2")] + public JoinDataComplete SetLayoutSize2 = new JoinDataComplete( + new JoinData + { + JoinNumber = 233, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout size 2", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("SetLayoutSize3")] + public JoinDataComplete SetLayoutSize3 = new JoinDataComplete( + new JoinData + { + JoinNumber = 234, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout size 3", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("SetLayoutSizeStrip")] + public JoinDataComplete SetLayoutSizeStrip = new JoinDataComplete( + new JoinData + { + JoinNumber = 235, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout size strip", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + //[JoinName("ParticipantAudioMuteToggleStart")] //public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( // new JoinData @@ -256,7 +346,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial - }); + }); + + // TOOD: #714 [ ] Feature Layout Size + [JoinName("GetSetCurrentLayoutSize")] + public JoinDataComplete GetSetCurrentLayoutSize = new JoinDataComplete( + new JoinData + { + JoinNumber = 230, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets and reports the current layout size.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.DigitalSerial + }); #endregion From 492e593263c847bd64ac01447421824456fc4373 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 7 Jun 2021 22:22:00 -0500 Subject: [PATCH 230/480] Updated IHasCodecLayouts to implement Layout Position selection and feedback, updated bridge map to map Layout Position signals. Updated ZoomRoom to implement Layout Position selection and feedback. --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 10 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 115 ++++++++++- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 180 +++++++++++++++--- 3 files changed, 274 insertions(+), 31 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 36499281..97ac35c5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -31,7 +31,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } - //StringFeedback LayoutSizeFeedback { get; } // TOOD: #714 [ ] Feature Layout Size + StringFeedback LayoutSizeFeedback { get; } // TODO: #714 [ ] Feature Layout Size + StringFeedback LayoutPositionFeedback { get; } // TODO: #714 [ ] Feature Layout Size ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } @@ -43,8 +44,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void LayoutTurnNextPage(); void LayoutTurnPreviousPage(); - void GetCurrentLayoutSize(); // TOOD: #714 [ ] Feature Layout Size - void SetLayoutSize(ZoomRoom.zConfiguration.eLayoutSize layoutSize); // TOOD: #714 [ ] Feature Layout Size + void GetCurrentLayoutSize(); // TODO: #714 [ ] Feature Layout Size + void SetLayoutSize(ZoomRoom.zConfiguration.eLayoutSize layoutSize); // TODO: #714 [ ] Feature Layout Size + + void GetCurrentLayoutPosition(); // TODO: #714 [ ] Feature Layout Size + void SetLayoutPosition(ZoomRoom.zConfiguration.eLayoutPosition layoutPosition); // TODO: #714 [ ] Feature Layout Size } public class LayoutInfoChangedEventArgs : EventArgs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index ceead746..85de4dec 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -126,6 +126,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); + // TODO: #714 [ ] Feature Layout Size + LayoutSizeFeedback = new StringFeedback(LayoutSizeFeedbackFunc); + LayoutPositionFeedback = new StringFeedback(LayoutPositionFeedbackFunc); + + LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); @@ -1797,13 +1802,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size trilist.SetSigFalseAction(joinMap.SetLayoutSizeOff.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Off)); trilist.SetSigFalseAction(joinMap.SetLayoutSize1.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size1)); trilist.SetSigFalseAction(joinMap.SetLayoutSize2.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size2)); trilist.SetSigFalseAction(joinMap.SetLayoutSize3.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size3)); - trilist.SetSigFalseAction(joinMap.SetLayoutSizeStrip.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Strip)); - // TOOD: #714 [ ] Feature Layout Size + trilist.SetSigFalseAction(joinMap.SetLayoutSizeStrip.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Strip)); trilist.SetSigFalseAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, layoutsCodec.GetCurrentLayoutSize); trilist.SetStringSigAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, (s) => { @@ -1817,6 +1821,41 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e); } }); + layoutsCodec.LayoutSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutSize.JoinNumber]); + + // TODO: #714 [ ] Feature Layout Size + trilist.SetSigFalseAction(joinMap.SetLayoutPositionCenter.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Center)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionUp.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Up)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionRight.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Right)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionUpRight.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.UpRight)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionDown.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Down)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionDownRight.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.DownRight)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionLeft.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Left)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionUpLeft.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.UpLeft)); + trilist.SetSigFalseAction(joinMap.SetLayoutPositionDownLeft.JoinNumber, + () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.DownLeft)); + trilist.SetSigFalseAction(joinMap.GetSetCurrentLayoutPosition.JoinNumber, layoutsCodec.GetCurrentLayoutPosition); + trilist.SetStringSigAction(joinMap.GetSetCurrentLayoutPosition.JoinNumber, (s) => + { + try + { + var position = (zConfiguration.eLayoutPosition) Enum.Parse(typeof (zConfiguration.eLayoutPosition), s, true); + SetLayoutPosition(position); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutPosition: {1}", s, e); + } + }); + } var pinCodec = this as IHasParticipantPinUnpin; @@ -2327,22 +2366,86 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("zCommand Call Layout TurnPage Forward: Off"); } - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size + /// + /// Stores last selected layout size + /// public zConfiguration.eLayoutSize LastSelectedLayoutSize { get; private set; } - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size + /// + /// Queries for current layout size + /// public void GetCurrentLayoutSize() { SendText("zConfiguration Call Layout Size"); } - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size + /// + /// Sets selected layout size + /// + /// zConfiguration.eLayoutSize public void SetLayoutSize(zConfiguration.eLayoutSize layoutSize) { LastSelectedLayoutSize = layoutSize; SendText(String.Format("zConfiguration Call Layout Size: {0}", layoutSize.ToString())); } + // TODO: #714 [ ] Feature Layout Size + private Func LayoutSizeFeedbackFunc + { + get + { + return () => Configuration.Call.Layout.Size.ToString(); + } + } + + /// + /// Layout size feedback + /// + public StringFeedback LayoutSizeFeedback { get; private set; } + + // TODO: #714 [ ] Feature Layout Size + /// + /// Stores last selected layout position + /// + public zConfiguration.eLayoutPosition LastSelectedLayoutPosition { get; private set; } + + // TODO: #714 [ ] Feature Layout Size + /// + /// Queries for current layout position + /// + public void GetCurrentLayoutPosition() + { + SendText("zConfiguration Call Layout Position"); + } + + // TODO: #714 [ ] Feature Layout Size + /// + /// Sets selected layout position + /// + /// + public void SetLayoutPosition(zConfiguration.eLayoutPosition layoutPosition) + { + LastSelectedLayoutPosition = layoutPosition; + SendText(String.Format("zConfiguration Call Layout Position: {0}", layoutPosition.ToString())); + } + + // TODO: #714 [ ] Feature Layout Size + private Func LayoutPositionFeedbackFunc + { + get + { + return () => Configuration.Call.Layout.Position.ToString(); + } + } + + /// + /// Layout position feedback + /// + public StringFeedback LayoutPositionFeedback { get; private set; } + #endregion #region IHasCodecLayouts Members diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 24cf65e8..fe9e0691 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -162,24 +162,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "FB Indicates if layout 'ShareAll' is available", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.DigitalSerial - }); + }); - // TOOD: #714 [ ] Feature Layout Size - //[JoinName("GetCurrentLayoutSize")] - //public JoinDataComplete GetCurrentLayoutSize = new JoinDataComplete( - // new JoinData - // { - // JoinNumber = 230, - // JoinSpan = 1 - // }, - // new JoinMetadata - // { - // Description = "Poll for the current layout size", - // JoinCapabilities = eJoinCapabilities.FromSIMPL, - // JoinType = eJoinType.Digital - // }); - - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("SetLayoutSizeOff")] public JoinDataComplete SetLayoutSizeOff = new JoinDataComplete( new JoinData @@ -194,7 +179,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("SetLayoutSize1")] public JoinDataComplete SetLayoutSize1 = new JoinDataComplete( new JoinData @@ -209,7 +194,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("SetLayoutSize2")] public JoinDataComplete SetLayoutSize2 = new JoinDataComplete( new JoinData @@ -224,7 +209,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("SetLayoutSize3")] public JoinDataComplete SetLayoutSize3 = new JoinDataComplete( new JoinData @@ -239,7 +224,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("SetLayoutSizeStrip")] public JoinDataComplete SetLayoutSizeStrip = new JoinDataComplete( new JoinData @@ -252,6 +237,141 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "Sets layout size strip", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionCenter")] + public JoinDataComplete SetLayoutPositionCenter = new JoinDataComplete( + new JoinData + { + JoinNumber = 241, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to center", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionUp")] + public JoinDataComplete SetLayoutPositionUp = new JoinDataComplete( + new JoinData + { + JoinNumber = 242, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to up", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionRight")] + public JoinDataComplete SetLayoutPositionRight = new JoinDataComplete( + new JoinData + { + JoinNumber = 243, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to right", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionUpRight")] + public JoinDataComplete SetLayoutPositionUpRight = new JoinDataComplete( + new JoinData + { + JoinNumber = 244, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to up right", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionDown")] + public JoinDataComplete SetLayoutPositionDown = new JoinDataComplete( + new JoinData + { + JoinNumber = 245, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to down", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionDownRight")] + public JoinDataComplete SetLayoutPositionDownRight = new JoinDataComplete( + new JoinData + { + JoinNumber = 246, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to down right", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionLeft")] + public JoinDataComplete SetLayoutPositionLeft = new JoinDataComplete( + new JoinData + { + JoinNumber = 247, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position todown left", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionUpLeft")] + public JoinDataComplete SetLayoutPositionUpLeft = new JoinDataComplete( + new JoinData + { + JoinNumber = 248, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to up left", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO: #714 [ ] Feature Layout Size + [JoinName("SetLayoutPositionDownLeft")] + public JoinDataComplete SetLayoutPositionDownLeft = new JoinDataComplete( + new JoinData + { + JoinNumber = 249, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets layout position to down left", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital }); //[JoinName("ParticipantAudioMuteToggleStart")] @@ -348,7 +468,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Serial }); - // TOOD: #714 [ ] Feature Layout Size + // TODO: #714 [ ] Feature Layout Size [JoinName("GetSetCurrentLayoutSize")] public JoinDataComplete GetSetCurrentLayoutSize = new JoinDataComplete( new JoinData @@ -363,6 +483,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.DigitalSerial }); + // TODO: #714 [ ] Feature Layout Size + [JoinName("GetSetCurrentLayoutPosition")] + public JoinDataComplete GetSetCurrentLayoutPosition = new JoinDataComplete( + new JoinData + { + JoinNumber = 240, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets and reports the current layout position.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + #endregion public ZoomRoomJoinMap(uint joinStart) From 7de0251188e4a7e824dd4d079b6343b3b3192dd6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Jun 2021 11:44:09 -0600 Subject: [PATCH 231/480] add ConvertType method to convert type This method should allow for using a string value in place of an enum as a parameter. Integers will still fail. --- .../Devices/DeviceJsonApi.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs index a1930cf0..2dda0bf8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs @@ -77,10 +77,9 @@ namespace PepperDash.Essentials.Core var mParams = method.GetParameters(); var convertedParams = mParams - .Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType, - System.Globalization.CultureInfo.InvariantCulture)) + .Select((p, i) => ConvertType(action.Params[i], p.ParameterType)) .ToArray(); - var ret = method.Invoke(obj, convertedParams); + method.Invoke(obj, convertedParams); CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name, action.DeviceKey); @@ -91,6 +90,23 @@ namespace PepperDash.Essentials.Core ex.Message);} } + private static object ConvertType(object value, Type conversionType) + { + if (!conversionType.IsEnum) + { + return Convert.ChangeType(value, conversionType, System.Globalization.CultureInfo.InvariantCulture); + } + + var stringValue = Convert.ToString(value); + + if (String.IsNullOrEmpty(stringValue)) + { + throw new InvalidCastException( + String.Format("{0} cannot be converted to a string prior to conversion to enum")); + } + return Enum.Parse(conversionType, stringValue, true); + } + /// /// Gets the properties on a device /// @@ -275,6 +291,8 @@ namespace PepperDash.Essentials.Core //var props = t.GetProperties().Select(p => new PropertyNameType(p, obj)); //return JsonConvert.SerializeObject(props, Formatting.Indented); } + + } public class DeviceActionWrapper From 1ebacf3f0f50f5d248d9bd73979207bd7b502996 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 8 Jun 2021 12:12:59 -0600 Subject: [PATCH 232/480] Fix formatting issue --- .../PepperDashEssentialsBase/Devices/DeviceManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index cca16ec7..aac38dfa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -435,7 +435,7 @@ namespace PepperDash.Essentials.Core var min = Convert.ToUInt32(timeout); device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min); - Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min); + Debug.Console(0, "Device: '{0}' debug level set to {1} for {2} minutes", deviceKey, debugSetting, min); } catch (Exception e) From 655bb954fa7ab51b392c64535de127afff92a2f0 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 8 Jun 2021 14:38:33 -0500 Subject: [PATCH 233/480] Updated IHasCodecLayouts and ZoomRoom to test feedback of Layout Size and Layout Position. --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 2 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 43 ++++++++++++------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 97ac35c5..209fc3b3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -32,7 +32,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } StringFeedback LayoutSizeFeedback { get; } // TODO: #714 [ ] Feature Layout Size - StringFeedback LayoutPositionFeedback { get; } // TODO: #714 [ ] Feature Layout Size + //StringFeedback LayoutPositionFeedback { get; } // TODO: #714 [ ] Feature Layout Size ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 85de4dec..69fefbf5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -108,6 +108,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); + // TODO: #714 [ ] Feature Layout Size + // Testing to see if the below is needed or if Selfview PiP Postion handles the feedback + //LayoutPositionFeedback = new StringFeedback(LayoutPositionFeedbackFunc); SetUpFeedbackActions(); @@ -127,8 +130,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); // TODO: #714 [ ] Feature Layout Size - LayoutSizeFeedback = new StringFeedback(LayoutSizeFeedbackFunc); - LayoutPositionFeedback = new StringFeedback(LayoutPositionFeedbackFunc); + LayoutSizeFeedback = new StringFeedback(LayoutSizeFeedbackFunc); LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); @@ -516,6 +518,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LocalLayoutFeedback.FireUpdate(); break; } + case "Size": + { + + break; + } } }; @@ -1488,7 +1495,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom return; } - Debug.Console(1, this, "****************************Call Participants***************************"); + Debug.Console(1, this, "*************************** Call Participants **************************"); foreach (var participant in Participants.CurrentParticipants) { Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name, @@ -1575,7 +1582,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } - Debug.Console(1, this, "****************************Active Calls*********************************"); + Debug.Console(1, this, "*************************** Active Calls ********************************"); // Clean up any disconnected calls left in the list for (int i = 0; i < ActiveCalls.Count; i++) @@ -1591,7 +1598,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (!call.IsActiveCall) { - Debug.Console(1, this, "******Removing Inactive Call: {0}******", call.Name); + Debug.Console(1, this, "***** Removing Inactive Call: {0} *****", call.Name); ActiveCalls.Remove(call); } } @@ -1855,7 +1862,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutPosition: {1}", s, e); } }); - + //layoutsCodec.LayoutPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutPosition.JoinNumber]); + SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutPosition.JoinNumber]); } var pinCodec = this as IHasParticipantPinUnpin; @@ -2411,7 +2419,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// Stores last selected layout position /// public zConfiguration.eLayoutPosition LastSelectedLayoutPosition { get; private set; } - + // TODO: #714 [ ] Feature Layout Size /// /// Queries for current layout position @@ -2433,18 +2441,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } // TODO: #714 [ ] Feature Layout Size - private Func LayoutPositionFeedbackFunc - { - get - { - return () => Configuration.Call.Layout.Position.ToString(); - } - } + // commented out to test if SelfviewPipPositionFeedback & (Func) would provide feedback + // --> in testing, feedback of the current position is still not updating + //private Func LayoutPositionFeedbackFunc + //{ + // get + // { + // return () => Configuration.Call.Layout.Position.ToString(); + // } + //} /// /// Layout position feedback /// - public StringFeedback LayoutPositionFeedback { get; private set; } + //public StringFeedback LayoutPositionFeedback { get; private set; } + #endregion @@ -2479,7 +2490,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void MinMaxLayoutToggle() { throw new NotImplementedException(); - } + } #endregion From ca8207f2bd64496fd17aff74f10fd29bcf0258cf Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 8 Jun 2021 15:20:42 -0500 Subject: [PATCH 234/480] Removed Layout Position properties and methods. Using SelfviewPipPosition properties and methods. --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 4 - .../VideoCodec/ZoomRoom/ZoomRoom.cs | 88 +--------- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 153 ------------------ 3 files changed, 2 insertions(+), 243 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 209fc3b3..555dfdb6 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -32,7 +32,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } StringFeedback LayoutSizeFeedback { get; } // TODO: #714 [ ] Feature Layout Size - //StringFeedback LayoutPositionFeedback { get; } // TODO: #714 [ ] Feature Layout Size ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } @@ -46,9 +45,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void GetCurrentLayoutSize(); // TODO: #714 [ ] Feature Layout Size void SetLayoutSize(ZoomRoom.zConfiguration.eLayoutSize layoutSize); // TODO: #714 [ ] Feature Layout Size - - void GetCurrentLayoutPosition(); // TODO: #714 [ ] Feature Layout Size - void SetLayoutPosition(ZoomRoom.zConfiguration.eLayoutPosition layoutPosition); // TODO: #714 [ ] Feature Layout Size } public class LayoutInfoChangedEventArgs : EventArgs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 69fefbf5..5e14c8df 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -108,10 +108,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); - // TODO: #714 [ ] Feature Layout Size - // Testing to see if the below is needed or if Selfview PiP Postion handles the feedback - //LayoutPositionFeedback = new StringFeedback(LayoutPositionFeedbackFunc); - + SetUpFeedbackActions(); Cameras = new List(); @@ -132,7 +129,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // TODO: #714 [ ] Feature Layout Size LayoutSizeFeedback = new StringFeedback(LayoutSizeFeedbackFunc); - LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); @@ -1828,42 +1824,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e); } }); - layoutsCodec.LayoutSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutSize.JoinNumber]); - - // TODO: #714 [ ] Feature Layout Size - trilist.SetSigFalseAction(joinMap.SetLayoutPositionCenter.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Center)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionUp.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Up)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionRight.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Right)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionUpRight.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.UpRight)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionDown.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Down)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionDownRight.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.DownRight)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionLeft.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.Left)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionUpLeft.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.UpLeft)); - trilist.SetSigFalseAction(joinMap.SetLayoutPositionDownLeft.JoinNumber, - () => layoutsCodec.SetLayoutPosition(zConfiguration.eLayoutPosition.DownLeft)); - trilist.SetSigFalseAction(joinMap.GetSetCurrentLayoutPosition.JoinNumber, layoutsCodec.GetCurrentLayoutPosition); - trilist.SetStringSigAction(joinMap.GetSetCurrentLayoutPosition.JoinNumber, (s) => - { - try - { - var position = (zConfiguration.eLayoutPosition) Enum.Parse(typeof (zConfiguration.eLayoutPosition), s, true); - SetLayoutPosition(position); - } - catch (Exception e) - { - Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutPosition: {1}", s, e); - } - }); - //layoutsCodec.LayoutPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutPosition.JoinNumber]); - SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutPosition.JoinNumber]); + layoutsCodec.LayoutSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutSize.JoinNumber]); } var pinCodec = this as IHasParticipantPinUnpin; @@ -2309,8 +2270,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void ComputeAvailableLayouts() { zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; - // TODO: #697 [X] Compute the avaialble layouts and set the value of AvailableLayouts - // Will need to test and confirm that this logic evaluates correctly if (Status.Layout.can_Switch_Wall_View) { availableLayouts |= zConfiguration.eLayoutStyle.Gallery; @@ -2414,49 +2373,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// public StringFeedback LayoutSizeFeedback { get; private set; } - // TODO: #714 [ ] Feature Layout Size - /// - /// Stores last selected layout position - /// - public zConfiguration.eLayoutPosition LastSelectedLayoutPosition { get; private set; } - - // TODO: #714 [ ] Feature Layout Size - /// - /// Queries for current layout position - /// - public void GetCurrentLayoutPosition() - { - SendText("zConfiguration Call Layout Position"); - } - - // TODO: #714 [ ] Feature Layout Size - /// - /// Sets selected layout position - /// - /// - public void SetLayoutPosition(zConfiguration.eLayoutPosition layoutPosition) - { - LastSelectedLayoutPosition = layoutPosition; - SendText(String.Format("zConfiguration Call Layout Position: {0}", layoutPosition.ToString())); - } - - // TODO: #714 [ ] Feature Layout Size - // commented out to test if SelfviewPipPositionFeedback & (Func) would provide feedback - // --> in testing, feedback of the current position is still not updating - //private Func LayoutPositionFeedbackFunc - //{ - // get - // { - // return () => Configuration.Call.Layout.Position.ToString(); - // } - //} - - /// - /// Layout position feedback - /// - //public StringFeedback LayoutPositionFeedback { get; private set; } - - #endregion #region IHasCodecLayouts Members diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index fe9e0691..8c34bdeb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -6,8 +6,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { public class ZoomRoomJoinMap : VideoCodecControllerJoinMap { - // TODO: #697 [X] Set join numbers - #region Digital [JoinName("CanSwapContentWithThumbnail")] @@ -237,141 +235,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "Sets layout size strip", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionCenter")] - public JoinDataComplete SetLayoutPositionCenter = new JoinDataComplete( - new JoinData - { - JoinNumber = 241, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to center", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionUp")] - public JoinDataComplete SetLayoutPositionUp = new JoinDataComplete( - new JoinData - { - JoinNumber = 242, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to up", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionRight")] - public JoinDataComplete SetLayoutPositionRight = new JoinDataComplete( - new JoinData - { - JoinNumber = 243, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to right", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionUpRight")] - public JoinDataComplete SetLayoutPositionUpRight = new JoinDataComplete( - new JoinData - { - JoinNumber = 244, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to up right", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionDown")] - public JoinDataComplete SetLayoutPositionDown = new JoinDataComplete( - new JoinData - { - JoinNumber = 245, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to down", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionDownRight")] - public JoinDataComplete SetLayoutPositionDownRight = new JoinDataComplete( - new JoinData - { - JoinNumber = 246, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to down right", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionLeft")] - public JoinDataComplete SetLayoutPositionLeft = new JoinDataComplete( - new JoinData - { - JoinNumber = 247, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position todown left", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionUpLeft")] - public JoinDataComplete SetLayoutPositionUpLeft = new JoinDataComplete( - new JoinData - { - JoinNumber = 248, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to up left", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutPositionDownLeft")] - public JoinDataComplete SetLayoutPositionDownLeft = new JoinDataComplete( - new JoinData - { - JoinNumber = 249, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout position to down left", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital }); //[JoinName("ParticipantAudioMuteToggleStart")] @@ -483,22 +346,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.DigitalSerial }); - // TODO: #714 [ ] Feature Layout Size - [JoinName("GetSetCurrentLayoutPosition")] - public JoinDataComplete GetSetCurrentLayoutPosition = new JoinDataComplete( - new JoinData - { - JoinNumber = 240, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets and reports the current layout position.", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - #endregion public ZoomRoomJoinMap(uint joinStart) From 1805ebaf0fa0b4899725b30f9d479a8cb4b00ace Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 8 Jun 2021 17:56:00 -0500 Subject: [PATCH 235/480] Converted ZoomRoom Layout Size properties and methods to interface, IHasSelfviewSize, following the patterns implemented for IHasSelfviewPosition and SelfviewPipPosition. --- .../Essentials Devices Common.csproj | 1 + .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 4 - .../VideoCodec/Interfaces/IHasSelfviewSize.cs | 13 ++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 151 ++++++++++-------- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 78 ++------- 5 files changed, 104 insertions(+), 143 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasSelfviewSize.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 3d9e5d30..21821d22 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -122,6 +122,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 555dfdb6..a8805a21 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -31,7 +31,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func BoolFeedback CanSwapContentWithThumbnailFeedback { get; } BoolFeedback ContentSwappedWithThumbnailFeedback { get; } - StringFeedback LayoutSizeFeedback { get; } // TODO: #714 [ ] Feature Layout Size ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; } ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; } @@ -42,9 +41,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void LayoutTurnNextPage(); void LayoutTurnPreviousPage(); - - void GetCurrentLayoutSize(); // TODO: #714 [ ] Feature Layout Size - void SetLayoutSize(ZoomRoom.zConfiguration.eLayoutSize layoutSize); // TODO: #714 [ ] Feature Layout Size } public class LayoutInfoChangedEventArgs : EventArgs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasSelfviewSize.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasSelfviewSize.cs new file mode 100644 index 00000000..91ac3ec8 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasSelfviewSize.cs @@ -0,0 +1,13 @@ +using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; + +namespace PepperDash.Essentials.Core.DeviceTypeInterfaces +{ + public interface IHasSelfviewSize + { + StringFeedback SelfviewPipSizeFeedback { get; } + + void SelfviewPipSizeSet(CodecCommandWithLabel size); + + void SelfviewPipSizeToggle(); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 5e14c8df..601d3346 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, - IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute + IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute, IHasSelfviewSize { private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; @@ -108,6 +108,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); + + // TODO: #714 [ ] SelfviewPipSizeFeedback + SelfviewPipSizeFeedback = new StringFeedback(SelfviewPipSizeFeedbackFunc); SetUpFeedbackActions(); @@ -126,9 +129,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc); - // TODO: #714 [ ] Feature Layout Size - LayoutSizeFeedback = new StringFeedback(LayoutSizeFeedbackFunc); - LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc); LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc); CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc); @@ -231,6 +231,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + // TODO: #714 [ ] SelfviewPipSizeFeedbackFunc + protected Func SelfviewPipSizeFeedbackFunc + { + get + { + return + () => + _currentSelfviewPipSize != null + ? _currentSelfviewPipSize.Command ?? "Unknown" + : "Unknown"; + } + } + protected Func LocalLayoutIsProminentFeedbackFunc { get { return () => false; } @@ -498,7 +511,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { case "Position": { - ComputeSelfviewPipStatus(); + ComputeSelfviewPipPositionStatus(); SelfviewPipPositionFeedback.FireUpdate(); @@ -516,7 +529,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } case "Size": { - + // TODO: #714 [ ] SetupFeedbackActions >> Size + ComputeSelfviewPipSizeStatus(); + + SelfviewPipSizeFeedback.FireUpdate(); + break; } @@ -530,7 +547,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { case "Position": { - ComputeSelfviewPipStatus(); + ComputeSelfviewPipPositionStatus(); SelfviewPipPositionFeedback.FireUpdate(); @@ -1803,28 +1820,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); - - // TODO: #714 [ ] Feature Layout Size - trilist.SetSigFalseAction(joinMap.SetLayoutSizeOff.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Off)); - trilist.SetSigFalseAction(joinMap.SetLayoutSize1.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size1)); - trilist.SetSigFalseAction(joinMap.SetLayoutSize2.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size2)); - trilist.SetSigFalseAction(joinMap.SetLayoutSize3.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Size3)); - trilist.SetSigFalseAction(joinMap.SetLayoutSizeStrip.JoinNumber, () => layoutsCodec.SetLayoutSize(zConfiguration.eLayoutSize.Strip)); - trilist.SetSigFalseAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, layoutsCodec.GetCurrentLayoutSize); - trilist.SetStringSigAction(joinMap.GetSetCurrentLayoutSize.JoinNumber, (s) => - { - try - { - var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); - SetLayoutSize(size); - } - catch (Exception e) - { - Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e); - } - }); - layoutsCodec.LayoutSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayoutSize.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); } var pinCodec = this as IHasParticipantPinUnpin; @@ -1835,6 +1831,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // Set the value of the local property to be used when pinning a participant trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); } + + // TODO: #714 [ ] LinkZoomRoomToApi >> layoutSizeCoodec + var layoutSizeCodec = this as IHasSelfviewSize; + if (layoutSizeCodec != null) + { + trilist.SetSigFalseAction(joinMap.GetSetSelfviewPipSize.JoinNumber, layoutSizeCodec.SelfviewPipSizeToggle); + + layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); + } + } public override void ExecuteSwitch(object selector) @@ -2206,13 +2212,58 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom new CodecCommandWithLabel("DownLeft", "Lower Left") }; - private void ComputeSelfviewPipStatus() + private void ComputeSelfviewPipPositionStatus() { _currentSelfviewPipPosition = SelfviewPipPositions.FirstOrDefault( p => p.Command.ToLower().Equals(Configuration.Call.Layout.Position.ToString().ToLower())); } + #endregion + + // TODO: #714 [ ] Implementation of IHasSelfviewPipSize + #region Implementation of IHasSelfviewPipSize + + private CodecCommandWithLabel _currentSelfviewPipSize; + + public StringFeedback SelfviewPipSizeFeedback { get; private set; } + + public void SelfviewPipSizeSet(CodecCommandWithLabel size) + { + SendText(String.Format("zConfiguration Call Layout Size: {0}", size.Command)); + } + + public void SelfviewPipSizeToggle() + { + if (_currentSelfviewPipSize != null) + { + var nextPipSizeIndex = SelfviewPipSizes.IndexOf(_currentSelfviewPipSize) + 1; + + if (nextPipSizeIndex >= SelfviewPipSizes.Count) + // Check if we need to loop back to the first item in the list + nextPipSizeIndex = 0; + + SelfviewPipSizeSet(SelfviewPipSizes[nextPipSizeIndex]); + } + } + + public List SelfviewPipSizes = new List() + { + new CodecCommandWithLabel("Off", "Off"), + new CodecCommandWithLabel("Size1", "Size 1"), + new CodecCommandWithLabel("Size2", "Size 2"), + new CodecCommandWithLabel("Size3", "Size 3"), + new CodecCommandWithLabel("Strip", "Strip") + }; + + private void ComputeSelfviewPipSizeStatus() + { + _currentSelfviewPipSize = + SelfviewPipSizes.FirstOrDefault( + p => p.Command.ToLower().Equals(Configuration.Call.Layout.Size.ToString().ToLower())); + } + + #endregion #region Implementation of IHasPhoneDialing @@ -2333,46 +2384,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("zCommand Call Layout TurnPage Forward: Off"); } - // TODO: #714 [ ] Feature Layout Size - /// - /// Stores last selected layout size - /// - public zConfiguration.eLayoutSize LastSelectedLayoutSize { get; private set; } - - // TODO: #714 [ ] Feature Layout Size - /// - /// Queries for current layout size - /// - public void GetCurrentLayoutSize() - { - SendText("zConfiguration Call Layout Size"); - } - - // TODO: #714 [ ] Feature Layout Size - /// - /// Sets selected layout size - /// - /// zConfiguration.eLayoutSize - public void SetLayoutSize(zConfiguration.eLayoutSize layoutSize) - { - LastSelectedLayoutSize = layoutSize; - SendText(String.Format("zConfiguration Call Layout Size: {0}", layoutSize.ToString())); - } - - // TODO: #714 [ ] Feature Layout Size - private Func LayoutSizeFeedbackFunc - { - get - { - return () => Configuration.Call.Layout.Size.ToString(); - } - } - - /// - /// Layout size feedback - /// - public StringFeedback LayoutSizeFeedback { get; private set; } - #endregion #region IHasCodecLayouts Members diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 8c34bdeb..f70c48bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -162,9 +162,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.DigitalSerial }); - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutSizeOff")] - public JoinDataComplete SetLayoutSizeOff = new JoinDataComplete( + // TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle + [JoinName("SelfviewPipSizeToggle")] + public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete( new JoinData { JoinNumber = 231, @@ -172,70 +172,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom }, new JoinMetadata { - Description = "Sets layout size off", + Description = "Toggles the selfview pip size, (aka layout size)", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutSize1")] - public JoinDataComplete SetLayoutSize1 = new JoinDataComplete( - new JoinData - { - JoinNumber = 232, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout size 1", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutSize2")] - public JoinDataComplete SetLayoutSize2 = new JoinDataComplete( - new JoinData - { - JoinNumber = 233, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout size 2", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutSize3")] - public JoinDataComplete SetLayoutSize3 = new JoinDataComplete( - new JoinData - { - JoinNumber = 234, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout size 3", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - // TODO: #714 [ ] Feature Layout Size - [JoinName("SetLayoutSizeStrip")] - public JoinDataComplete SetLayoutSizeStrip = new JoinDataComplete( - new JoinData - { - JoinNumber = 235, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets layout size strip", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); + }); //[JoinName("ParticipantAudioMuteToggleStart")] //public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( @@ -331,9 +271,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Serial }); - // TODO: #714 [ ] Feature Layout Size - [JoinName("GetSetCurrentLayoutSize")] - public JoinDataComplete GetSetCurrentLayoutSize = new JoinDataComplete( + // TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize + [JoinName("GetSetSelfviewPipSize")] + public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete( new JoinData { JoinNumber = 230, @@ -341,7 +281,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom }, new JoinMetadata { - Description = "Sets and reports the current layout size.", + Description = "Sets and reports the selfview pip size, (aka layout size).", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalSerial }); From f5305197b35d9e0ec8a986367544138c77907f58 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 9 Jun 2021 13:37:01 -0500 Subject: [PATCH 236/480] Updates to LinkZoomRoomApi method --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 601d3346..8ee5f7e4 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -621,21 +621,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Layout.PropertyChanged += (o, a) => { - switch (a.PropertyName) + Debug.Console(1, this, "Status.Layout.PropertyChanged a.PropertyName: {0}", a.PropertyName); + switch (a.PropertyName.ToLower()) { - case "can_Switch_Speaker_View": - case "can_Switch_Wall_View": - case "can_Switch_Share_On_All_Screens": + case "can_switch_speaker_view": + case "can_switch_wall_view": + case "can_switch_share_on_all_screens": { ComputeAvailableLayouts(); break; } - case "is_In_First_Page": + case "is_in_first_page": { LayoutViewIsOnFirstPageFeedback.FireUpdate(); break; } - case "is_In_Last_Page": + case "is_in_last_page": { LayoutViewIsOnLastPageFeedback.FireUpdate(); break; @@ -1766,7 +1767,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LinkVideoCodecToApi(this, trilist, joinMap); - LinkZoomRoomToApi(trilist, joinMap); + LinkZoomRoomToApi(trilist, joinMap); } /// @@ -1837,11 +1838,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (layoutSizeCodec != null) { trilist.SetSigFalseAction(joinMap.GetSetSelfviewPipSize.JoinNumber, layoutSizeCodec.SelfviewPipSizeToggle); + trilist.SetStringSigAction(joinMap.GetSetSelfviewPipSize.JoinNumber, (s) => + { + try + { + var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); + var cmd = SelfviewPipSizes.FirstOrDefault(c => c.Command.Equals(size.ToString())); + SelfviewPipSizeSet(cmd); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutSize: {1}", s, e); + } + }); layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); } - } + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + layoutsCodec.LocalLayoutFeedback.FireUpdate(); + pinCodec.NumberOfScreensFeedback.FireUpdate(); + layoutSizeCodec.SelfviewPipSizeFeedback.FireUpdate(); + }; + } public override void ExecuteSwitch(object selector) { @@ -2320,6 +2342,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// private void ComputeAvailableLayouts() { + Debug.Console(1, this, "Computing available layouts..."); zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None; if (Status.Layout.can_Switch_Wall_View) { @@ -2343,6 +2366,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom availableLayouts |= zConfiguration.eLayoutStyle.Strip; } + Debug.Console(1, this, "Available layouts: {0}", availableLayouts); + var handler = AvailableLayoutsChanged; if (handler != null) { From 1c06e8381b7a3439077026d907406328bdcebab1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 13:30:36 -0600 Subject: [PATCH 237/480] Fixed inverted video mute FB and adds debug statements to help see participant pin status --- .../VideoCodec/VideoCodecBase.cs | 31 +++++++++++++++++++ .../VideoCodec/ZoomRoom/ResponseObjects.cs | 2 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 5 ++- 3 files changed, 36 insertions(+), 2 deletions(-) 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 dc9228ce..38ae0295 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 @@ -613,6 +613,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (meetingIndex >= maxParticipants * offset) break; + Debug.Console(2, this, +@"Updating Participant on xsig: +Name: {0} (s{8}) +AudioMute: {1} (d{9}) +VideoMute: {2} (d{10}) +CanMuteVideo: {3} ({d11}) +IsHost: {4} (d{12}) +HandIsRaised: {5} (d{13}) +IsPinned: {6} (d{14}) +ScreenIndexIsPinnedTo: {7} (a{15}) +", + participant.Name, + participant.AudioMuteFb, + participant.VideoMuteFb, + participant.CanMuteVideo, + participant.IsHost, + participant.HandIsRaisedFb, + participant.IsPinnedFb, + participant.ScreenIndexIsPinnedToFb, + stringIndex + 1, + digitalIndex + 1, + digitalIndex + 2, + digitalIndex + 3, + digitalIndex + 4, + digitalIndex + 5, + digitalIndex + 6, + digitalIndex + 7, + analogIndex + 1 + ); + + //digitals tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb); tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index b45810ac..468b611b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1440,7 +1440,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom CanMuteVideo = p.IsVideoCanMuteByHost, CanUnmuteVideo = p.IsVideoCanUnmuteByHost, AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", - VideoMuteFb = p.VideoStatusIsSending, + VideoMuteFb = !p.VideoStatusIsSending, HandIsRaisedFb = p.HandStatus.HandIsRaisedAndValid, }).ToList(); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 8ee5f7e4..556c9d85 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1345,6 +1345,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var status = responseObj.ToObject(); + Debug.Console(1, this, "Pin Status notificatino for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); + var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); if (participant != null) @@ -1358,11 +1360,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (participant == null) { - Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); + Debug.Console(1, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); return; } else { + Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex); participant.IsPinnedFb = false; participant.ScreenIndexIsPinnedToFb = -1; } From 7ac3f81ea5ecfb3dfa027f21e63c43768c7ace2f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 16:14:18 -0600 Subject: [PATCH 238/480] Initialize SreenIndexIsPinnedToFb to -1. Adds debugging for xsig tokens --- .../VideoCodec/Interfaces/IHasParticipants.cs | 6 ++ .../VideoCodec/VideoCodecBase.cs | 72 ++++++++++++------- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index f03c1984..f6d32149 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -90,5 +90,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public bool HandIsRaisedFb { get; set; } public bool IsPinnedFb { get; set; } public int ScreenIndexIsPinnedToFb { get; set; } + + public Participant() + { + // Initialize to -1 (no screen) + ScreenIndexIsPinnedToFb = -1; + } } } \ No newline at end of file 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 38ae0295..fc38a647 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 @@ -530,28 +530,43 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { + // make sure to update the values when the EISC comes online + trilist.OnlineStatusChange += (sender, args) => + { + if (sender.IsOnline) + { + UpdateParticipantsXSig(codec, trilist, joinMap); + } + }; + + // set actions and update the values when the list changes codec.Participants.ParticipantsListHasChanged += (sender, args) => { - string participantsXSig; - - if (codec.Participants.CurrentParticipants.Count == 0) - { - participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); - return; - } - SetParticipantActions(trilist, joinMap, codec.Participants.CurrentParticipants); - participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); - - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + UpdateParticipantsXSig(codec, trilist, joinMap); }; } + private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + string participantsXSig; + + if (codec.Participants.CurrentParticipants.Count == 0) + { + participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + return; + } + + participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); + + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + } + /// /// Sets the actions for each participant in the list /// @@ -615,19 +630,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(2, this, @"Updating Participant on xsig: -Name: {0} (s{8}) -AudioMute: {1} (d{9}) -VideoMute: {2} (d{10}) -CanMuteVideo: {3} ({d11}) -IsHost: {4} (d{12}) -HandIsRaised: {5} (d{13}) -IsPinned: {6} (d{14}) -ScreenIndexIsPinnedTo: {7} (a{15}) +Name: {0} (s{9}) +AudioMute: {1} (d{10}) +VideoMute: {2} (d{11}) +CanMuteVideo: {3} (d{12}) +CanUMuteVideo: {4} (d{13}) +IsHost: {5} (d{14}) +HandIsRaised: {6} (d{15}) +IsPinned: {7} (d{16}) +ScreenIndexIsPinnedTo: {8} (a{17}) ", participant.Name, participant.AudioMuteFb, participant.VideoMuteFb, participant.CanMuteVideo, + participant.CanUnmuteVideo, participant.IsHost, participant.HandIsRaisedFb, participant.IsPinnedFb, @@ -653,6 +670,8 @@ ScreenIndexIsPinnedTo: {7} (a{15}) tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb); tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb); + Debug.Console(2, this, "Index: {0} byte value: {1}", digitalIndex + 7, ComTextHelper.GetEscapedText(tokenArray[digitalIndex + 6].GetBytes())); + //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); @@ -688,7 +707,12 @@ ScreenIndexIsPinnedTo: {7} (a{15}) analogIndex += maxAnalogs; } - return GetXSigString(tokenArray); + var returnString = GetXSigString(tokenArray); + + //Debug.Console(2, this, "{0}", ComTextHelper.GetEscapedText(Encoding.GetEncoding(28591).GetBytes(returnString))); + + + return returnString; } private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) From 25e7e9634acd620cef3da76192a7dea8b5b6f9de Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 16:56:56 -0600 Subject: [PATCH 239/480] updates PD Core version to include xsig token fixes --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index b60e8578..ee22bc9c 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 08f4d8e9a2a285c1d656a9fc6d62a2408a26d859 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 16:57:42 -0600 Subject: [PATCH 240/480] Attempts to unpin participant from same screenIndex if one is already pinned. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 556c9d85..a6b8c469 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2113,6 +2113,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void PinParticipant(int userId, int screenIndex) { + // Try to see if anyone is already pinned to this screen + var pinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(screenIndex)); + + if (pinnedParticipant != null) + { + // If we find a participant already pinned, unpin this one and clear the feedback values + UnPinParticipant(pinnedParticipant.UserId); + pinnedParticipant.IsPinnedFb = false; + pinnedParticipant.ScreenIndexIsPinnedToFb = -1; + } + SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex)); } From 0c56da112cc47482e5ed534086e4193506627436 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 17:07:25 -0600 Subject: [PATCH 241/480] Changes to respond to new pinned participant message by clearing out already pinned participant fb first. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a6b8c469..079762e2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1345,7 +1345,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var status = responseObj.ToObject(); - Debug.Console(1, this, "Pin Status notificatino for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); + Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); + + // Check for a participant already pinned to the same screen index. + var alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. + if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) + { + Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", + alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); + alreadyPinnedParticipant.IsPinnedFb = false; + alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; + } var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); @@ -2113,17 +2125,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void PinParticipant(int userId, int screenIndex) { - // Try to see if anyone is already pinned to this screen - var pinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(screenIndex)); - - if (pinnedParticipant != null) - { - // If we find a participant already pinned, unpin this one and clear the feedback values - UnPinParticipant(pinnedParticipant.UserId); - pinnedParticipant.IsPinnedFb = false; - pinnedParticipant.ScreenIndexIsPinnedToFb = -1; - } - SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex)); } From b71523bd2dd5ebb4db8ba9e74e558e52dfee7acc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 17:38:50 -0600 Subject: [PATCH 242/480] Adds condition to not check for already pinned participant if incoming message has user id < 0 --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 079762e2..a1f1dfd7 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1348,15 +1348,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); // Check for a participant already pinned to the same screen index. - var alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); - - // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. - if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) + if (status.PinnedUserId > 0) { - Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", - alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); - alreadyPinnedParticipant.IsPinnedFb = false; - alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; + var alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. + if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) + { + Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", + alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); + alreadyPinnedParticipant.IsPinnedFb = false; + alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; + } } var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); From cb35aa13f5fe0afe025b705f089ec1fcf64d2130 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 9 Jun 2021 17:55:55 -0600 Subject: [PATCH 243/480] lets it fall through conditions to fire the ParticipantsChanged event if an already pinned participant is found --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a1f1dfd7..96d5c1c9 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1347,10 +1347,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); + Participant alreadyPinnedParticipant = null; + // Check for a participant already pinned to the same screen index. if (status.PinnedUserId > 0) { - var alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) @@ -1373,12 +1375,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); - if (participant == null) + if (participant == null && alreadyPinnedParticipant == null) { Debug.Console(1, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); return; } - else + else if (participant != null) { Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex); participant.IsPinnedFb = false; From 6beff106ec701c72be6b6de0dc0cd332926ec977 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 10 Jun 2021 17:45:23 -0500 Subject: [PATCH 244/480] Updated packages.config to track latest PepperDash Core release. Updated ZoomRoom LinkZoomRoomToApi to update the bridge when it comes online. --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 20 +++++++++---------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 12 ++++++++--- packages.config | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 468b611b..708abe34 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1454,16 +1454,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { if (participants == null) { - Debug.Console(1, "SortParticiapntListByHandStatu(participants == null)"); + //Debug.Console(1, "SortParticiapntListByHandStatu(participants == null)"); return null; } // debug testing - foreach (ListParticipant participant in participants) - { - Debug.Console(1, "{0} | IsValid: {1} | IsRaiseHand: {2} | HandIsRaisedAndValid: {3}", - participant.UserName, participant.HandStatus.IsValid, participant.HandStatus.IsRaiseHand.ToString(), participant.HandStatus.HandIsRaisedAndValid.ToString()); - } + //foreach (ListParticipant participant in participants) + //{ + // Debug.Console(1, "{0} | IsValid: {1} | IsRaiseHand: {2} | HandIsRaisedAndValid: {3}", + // participant.UserName, participant.HandStatus.IsValid, participant.HandStatus.IsRaiseHand.ToString(), participant.HandStatus.HandIsRaisedAndValid.ToString()); + //} List handRaisedParticipantsList = participants.Where(p => p.HandStatus.HandIsRaisedAndValid).ToList(); @@ -1471,8 +1471,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { IOrderedEnumerable orderByDescending = handRaisedParticipantsList.OrderByDescending(p => p.HandStatus.TimeStamp); - foreach (var participant in handRaisedParticipantsList) - Debug.Console(1, "handRaisedParticipantList: {0} | {1}", participant.UserName, participant.UserId); + //foreach (var participant in handRaisedParticipantsList) + // Debug.Console(1, "handRaisedParticipantList: {0} | {1}", participant.UserName, participant.UserId); } List allOtherParticipantsList = participants.Where(p => !p.HandStatus.HandIsRaisedAndValid).ToList(); @@ -1481,8 +1481,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { allOtherParticipantsList.OrderBy(p => p.UserName); - foreach (var participant in allOtherParticipantsList) - Debug.Console(1, "allOtherParticipantsList: {0} | {1}", participant.UserName, participant.UserId); + //foreach (var participant in allOtherParticipantsList) + // Debug.Console(1, "allOtherParticipantsList: {0} | {1}", participant.UserName, participant.UserId); } // merge the lists diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 96d5c1c9..fc3f14a9 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1817,9 +1817,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString()); trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString()); }; + + trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); - trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); @@ -1879,7 +1880,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { if (!args.DeviceOnLine) return; - layoutsCodec.LocalLayoutFeedback.FireUpdate(); + ComputeAvailableLayouts(); + layoutsCodec.LocalLayoutFeedback.FireUpdate(); + layoutsCodec.CanSwapContentWithThumbnailFeedback.FireUpdate(); + layoutsCodec.ContentSwappedWithThumbnailFeedback.FireUpdate(); + layoutsCodec.LayoutViewIsOnFirstPageFeedback.FireUpdate(); + layoutsCodec.LayoutViewIsOnLastPageFeedback.FireUpdate(); pinCodec.NumberOfScreensFeedback.FireUpdate(); layoutSizeCodec.SelfviewPipSizeFeedback.FireUpdate(); }; @@ -2386,7 +2392,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom availableLayouts |= zConfiguration.eLayoutStyle.Strip; } - Debug.Console(1, this, "Available layouts: {0}", availableLayouts); + Debug.Console(1, this, "availablelayouts: {0}", availableLayouts); var handler = AvailableLayoutsChanged; if (handler != null) diff --git a/packages.config b/packages.config index ee22bc9c..3876040a 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From cc742f4291a56ed2f6e1b799daf15023889ffbd6 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 16 Jun 2021 13:11:45 -0600 Subject: [PATCH 245/480] adds check for abstract class before attempting to create instance --- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index ba4ffab4..7437d75a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -375,7 +375,7 @@ namespace PepperDash.Essentials { try { - if (typeof (IPluginDeviceFactory).IsAssignableFrom(type)) + if (typeof (IPluginDeviceFactory).IsAssignableFrom(type) && !type.IsAbstract) { var plugin = (IPluginDeviceFactory) Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); From 5c9996e7287542415b153a18736c7a8e84d9ccf4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 17 Jun 2021 13:49:09 -0600 Subject: [PATCH 246/480] adds new type options to use EISCClient and EISCServer in eiscapiadvanced --- .../PepperDashEssentialsBase/Bridges/BridgeBase.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 11ede5a1..a1326770 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -385,7 +385,7 @@ namespace PepperDash.Essentials.Core.Bridges { public EiscApiAdvancedFactory() { - TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" }; + TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) @@ -403,6 +403,16 @@ namespace PepperDash.Essentials.Core.Bridges controlProperties.TcpSshProperties.Address, Global.ControlSystem); return new EiscApiAdvanced(dc, eisc); } + case "eiscapiadvancedserver": + { + var eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem); + return new EiscApiAdvanced(dc, eisc); + } + case "eiscapiadvancedclient": + { + var eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem); + return new EiscApiAdvanced(dc, eisc); + } case "vceiscapiadv": case "vceiscapiadvanced": { From a76f4c15dc81dae7789f5155d92e564ab5b27fe3 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 29 Jun 2021 09:47:56 -0600 Subject: [PATCH 247/480] Updates to IHasScheduleAwareness --- .../Codec/iHasScheduleAwareness.cs | 18 ++++++++++++++++++ .../VideoCodec/MockVC/MockVC.cs | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs index 7d6acdc2..8799b33b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Devices.Common.Codec { public enum eMeetingEventChangeType @@ -115,17 +117,24 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public class Meeting { + [JsonProperty("minutesBeforeMeeting")] public int MinutesBeforeMeeting; + [JsonProperty("id")] public string Id { get; set; } + [JsonProperty("organizer")] public string Organizer { get; set; } + [JsonProperty("title")] public string Title { get; set; } + [JsonProperty("agenda")] public string Agenda { get; set; } + [JsonProperty("meetingWarningMinutes")] public TimeSpan MeetingWarningMinutes { get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); } } + [JsonProperty("timeToMeetingStart")] public TimeSpan TimeToMeetingStart { get @@ -133,6 +142,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec return StartTime - DateTime.Now; } } + [JsonProperty("timeToMeetingEnd")] public TimeSpan TimeToMeetingEnd { get @@ -140,8 +150,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec return EndTime - DateTime.Now; } } + [JsonProperty("startTime")] public DateTime StartTime { get; set; } + [JsonProperty("endTime")] public DateTime EndTime { get; set; } + [JsonProperty("duration")] public TimeSpan Duration { get @@ -149,7 +162,9 @@ namespace PepperDash.Essentials.Devices.Common.Codec return EndTime - StartTime; } } + [JsonProperty("privacy")] public eMeetingPrivacy Privacy { get; set; } + [JsonProperty("joinable")] public bool Joinable { get @@ -159,9 +174,12 @@ namespace PepperDash.Essentials.Devices.Common.Codec } } //public string ConferenceNumberToDial { get; set; } + [JsonProperty("conferencePassword")] public string ConferencePassword { get; set; } + [JsonProperty("isOneButtonToPushMeeting")] public bool IsOneButtonToPushMeeting { get; set; } + [JsonProperty("calls")] public List Calls { get; private set; } public Meeting() diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index c4bfa298..a947a1d1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -396,10 +396,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0 || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) { - _CodecSchedule = new CodecScheduleAwareness(); + _CodecSchedule = new CodecScheduleAwareness(10000); for (int i = 0; i < 5; i++) { var m = new Meeting(); + m.Id = i.ToString(); + m.Organizer = "Employee " + 1; m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i); m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30); m.Title = "Meeting " + i; From 840934502bb0f3b27e0c341a123d3f9782edc8fe Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 29 Jun 2021 17:35:22 -0600 Subject: [PATCH 248/480] Working on getting meeting change events to trigger properly --- .../UI/JoinConstants/UIBoolJoin.cs | 4 ++ .../Codec/iHasScheduleAwareness.cs | 45 ++++++++++++++----- .../VideoCodec/MockVC/MockVC.cs | 20 +++++++-- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index 23ab797e..293fddd5 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -764,6 +764,10 @@ namespace PepperDash.Essentials /// public const uint NextMeetingModalVisible = 15049; /// + /// 15050 + /// + public const uint NextMeetingNotificationRibbonVisible = 15050; + /// /// 15051 /// public const uint Display1SelectPressAndFb = 15051; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs index 8799b33b..5e2b1c23 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs @@ -4,13 +4,15 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.Codec { public enum eMeetingEventChangeType { - Unkown = 0, + Unknown = 0, MeetingStartWarning, MeetingStart, MeetingEndWarning, @@ -34,6 +36,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec private int _meetingWarningMinutes = 5; + private Meeting _previousChangedMeeting; + + private eMeetingEventChangeType _previousChangeType = eMeetingEventChangeType.Unknown; + public int MeetingWarningMinutes { get { return _meetingWarningMinutes; } @@ -90,24 +96,39 @@ namespace PepperDash.Essentials.Devices.Common.Codec { // Iterate the meeting list and check if any meeting need to do anythingk - const double meetingTimeEpsilon = 0.0001; + const double meetingTimeEpsilon = 0.05; foreach (var m in Meetings) { - var changeType = eMeetingEventChangeType.Unkown; + var changeType = eMeetingEventChangeType.Unknown; - if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start + //Debug.Console(2, "Math.Abs(m.TimeToMeetingEnd.TotalMinutes) = {0}", Math.Abs(m.TimeToMeetingEnd.TotalMinutes)); + if (_previousChangeType != eMeetingEventChangeType.MeetingStartWarning && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start + { + Debug.Console(2, "MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds); changeType = eMeetingEventChangeType.MeetingStartWarning; - else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start + } + else if (_previousChangeType != eMeetingEventChangeType.MeetingStart && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting Start + { + Debug.Console(2, "MeetingStart"); changeType = eMeetingEventChangeType.MeetingStart; - else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end + } + else if (_previousChangeType != eMeetingEventChangeType.MeetingEndWarning && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end changeType = eMeetingEventChangeType.MeetingEndWarning; - else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended + else if (_previousChangeType != eMeetingEventChangeType.MeetingEnd && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended changeType = eMeetingEventChangeType.MeetingEnd; - if (changeType != eMeetingEventChangeType.Unkown) - OnMeetingChange(changeType, m); - } + if (changeType != eMeetingEventChangeType.Unknown) + { + // check to make sure this is not a redundant event for one that was fired last + if (_previousChangedMeeting == null || (_previousChangedMeeting != m && _previousChangeType != changeType)) + { + _previousChangeType = changeType; + _previousChangedMeeting = m; + OnMeetingChange(changeType, m); + } + } + } } } @@ -169,8 +190,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec { get { - return StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now + var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now && DateTime.Now <= EndTime; //.AddMinutes(-5); + Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable); + return joinable; } } //public string ConferenceNumberToDial { get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index a947a1d1..b87f1fa8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -139,7 +139,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public override void Dial(Meeting meeting) { - throw new NotImplementedException(); + Debug.Console(1, this, "Dial Meeting: {0}", meeting.Id); + var call = new CodecActiveCallItem() { Name = meeting.Title, Number = meeting.Id, Id = meeting.Id, Status = eCodecCallStatus.Dialing, Direction = eCodecCallDirection.Outgoing, Type = eCodecCallType.Video }; + ActiveCalls.Add(call); + OnCallStatusChange(call); + + //ActiveCallCountFeedback.FireUpdate(); + // Simulate 2-second ring, then connecting, then connected + new CTimer(o => + { + call.Type = eCodecCallType.Video; + SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connecting, call); + new CTimer(oo => SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus.Connected, call), 1000); + }, 2000); + } /// @@ -396,14 +409,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec if (_CodecSchedule == null || _CodecSchedule.Meetings.Count == 0 || _CodecSchedule.Meetings[_CodecSchedule.Meetings.Count - 1].StartTime < DateTime.Now) { - _CodecSchedule = new CodecScheduleAwareness(10000); + _CodecSchedule = new CodecScheduleAwareness(1000); for (int i = 0; i < 5; i++) { var m = new Meeting(); + m.MinutesBeforeMeeting = 5; m.Id = i.ToString(); m.Organizer = "Employee " + 1; m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i); - m.EndTime = DateTime.Now.AddHours(i).AddMinutes(30); + m.EndTime = DateTime.Now.AddHours(i).AddMinutes(55); m.Title = "Meeting " + i; m.Calls.Add(new Call() { Number = i + "meeting@fake.com"}); _CodecSchedule.Meetings.Add(m); From e964172200d777bd940d698145a343a6ef703e5f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 2 Jul 2021 15:01:17 -0600 Subject: [PATCH 249/480] #729 Updates to get CheckSchedule method working as designed --- .../Display/MockDisplay.cs | 3 + .../Codec/iHasScheduleAwareness.cs | 76 +++++++++++++------ .../VideoCodec/MockVC/MockVC.cs | 4 +- 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs index dcdba6d8..eb529376 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Display/MockDisplay.cs @@ -59,6 +59,9 @@ namespace PepperDash.Essentials.Core VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; }); MuteFeedback = new BoolFeedback("MuteOn", () => _IsMuted); + + WarmupTime = 10000; + CooldownTime = 5000; } public override void PowerOn() diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs index 5e2b1c23..24f1968b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs @@ -10,13 +10,14 @@ using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.Codec { + [Flags] public enum eMeetingEventChangeType { Unknown = 0, - MeetingStartWarning, - MeetingStart, - MeetingEndWarning, - MeetingEnd + MeetingStartWarning = 1, + MeetingStart = 2, + MeetingEndWarning = 4, + MeetingEnd = 8 } public interface IHasScheduleAwareness @@ -83,50 +84,69 @@ namespace PepperDash.Essentials.Devices.Common.Codec _scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime); } + /// + /// Helper method to fire MeetingEventChange. Should only fire once for each changeType on each meeting + /// + /// + /// private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting) { - var handler = MeetingEventChange; - if (handler != null) + Debug.Console(2, "*****************OnMeetingChange. id: {0} changeType: {1}**********************", meeting.Id, changeType); + if (changeType != (changeType & meeting.NotifiedChangeTypes)) { - handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting }); + // Add this change type to the NotifiedChangeTypes + meeting.NotifiedChangeTypes |= changeType; + + var handler = MeetingEventChange; + if (handler != null) + { + handler(this, new MeetingEventArgs() { ChangeType = changeType, Meeting = meeting }); + } + } + else + { + Debug.Console(2, "Meeting: {0} already notified of changeType: {1}", meeting.Id, changeType); } } + + /// + /// Checks the schedule to see if any MeetingEventChange updates should be fired + /// + /// private void CheckSchedule(object o) { - // Iterate the meeting list and check if any meeting need to do anythingk + // Iterate the meeting list and check if any meeting need to do anything const double meetingTimeEpsilon = 0.05; foreach (var m in Meetings) { var changeType = eMeetingEventChangeType.Unknown; - //Debug.Console(2, "Math.Abs(m.TimeToMeetingEnd.TotalMinutes) = {0}", Math.Abs(m.TimeToMeetingEnd.TotalMinutes)); - if (_previousChangeType != eMeetingEventChangeType.MeetingStartWarning && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start + if (eMeetingEventChangeType.MeetingStartWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStartWarning) && m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingStart.Seconds > 0) // Meeting is about to start { - Debug.Console(2, "MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds); + Debug.Console(2, "********************* MeetingStartWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingStart.TotalMinutes, m.TimeToMeetingStart.Seconds); changeType = eMeetingEventChangeType.MeetingStartWarning; } - else if (_previousChangeType != eMeetingEventChangeType.MeetingStart && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting Start + else if (eMeetingEventChangeType.MeetingStart != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingStart) && Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start { - Debug.Console(2, "MeetingStart"); + Debug.Console(2, "********************* MeetingStart"); changeType = eMeetingEventChangeType.MeetingStart; } - else if (_previousChangeType != eMeetingEventChangeType.MeetingEndWarning && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end + else if (eMeetingEventChangeType.MeetingEndWarning != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEndWarning) && m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes && m.TimeToMeetingEnd.Seconds > 0) // Meeting is about to end + { + Debug.Console(2, "********************* MeetingEndWarning. TotalMinutes: {0} Seconds: {1}", m.TimeToMeetingEnd.TotalMinutes, m.TimeToMeetingEnd.Seconds); changeType = eMeetingEventChangeType.MeetingEndWarning; - else if (_previousChangeType != eMeetingEventChangeType.MeetingEnd && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended + } + else if (eMeetingEventChangeType.MeetingEnd != (m.NotifiedChangeTypes & eMeetingEventChangeType.MeetingEnd) && Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended + { + Debug.Console(2, "********************* MeetingEnd"); changeType = eMeetingEventChangeType.MeetingEnd; + } if (changeType != eMeetingEventChangeType.Unknown) { - // check to make sure this is not a redundant event for one that was fired last - if (_previousChangedMeeting == null || (_previousChangedMeeting != m && _previousChangeType != changeType)) - { - _previousChangeType = changeType; - _previousChangedMeeting = m; - - OnMeetingChange(changeType, m); - } + OnMeetingChange(changeType, m); } } @@ -191,8 +211,8 @@ namespace PepperDash.Essentials.Devices.Common.Codec get { var joinable = StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now - && DateTime.Now <= EndTime; //.AddMinutes(-5); - Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable); + && DateTime.Now <= EndTime.AddMinutes(-5); + //Debug.Console(2, "Meeting Id: {0} joinable: {1}", Id, joinable); return joinable; } } @@ -205,6 +225,12 @@ namespace PepperDash.Essentials.Devices.Common.Codec [JsonProperty("calls")] public List Calls { get; private set; } + /// + /// Tracks the change types that have already been notified for + /// + [JsonIgnore] + public eMeetingEventChangeType NotifiedChangeTypes { get; set; } + public Meeting() { Calls = new List(); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index b87f1fa8..ca199957 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -416,8 +416,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec m.MinutesBeforeMeeting = 5; m.Id = i.ToString(); m.Organizer = "Employee " + 1; - m.StartTime = DateTime.Now.AddMinutes(3).AddHours(i); - m.EndTime = DateTime.Now.AddHours(i).AddMinutes(55); + m.StartTime = DateTime.Now.AddMinutes(6).AddHours(i); + m.EndTime = DateTime.Now.AddHours(i).AddMinutes(16); m.Title = "Meeting " + i; m.Calls.Add(new Call() { Number = i + "meeting@fake.com"}); _CodecSchedule.Meetings.Add(m); From d95ee27979219fc1df0470ca28b415371549b493 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 2 Jul 2021 15:01:51 -0600 Subject: [PATCH 250/480] #728 corrects casing of folder name in Global.FilePathPrefix at startup --- PepperDashEssentials/ControlSystem.cs | 35 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index a8002f7e..e4c521b5 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -131,29 +131,46 @@ namespace PepperDash.Essentials if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString()); + string userFolder; + string nvramFolder; + bool is4series = false; + + if (eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4)) // Handle 4-series + { + is4series = true; + // Set path to user/ + userFolder = "user"; + nvramFolder = "nvram"; + } + else + { + userFolder = "User"; + nvramFolder = "Nvram"; + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, is4series ? "4-series" : "3-series"); // Check if User/ProgramX exists - if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" + if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + userFolder + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) { - Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); - filePathPrefix = directoryPrefix + dirSeparator + "User" + Debug.Console(0, @"{0}/program{1} directory found", userFolder, InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + userFolder + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; } // Check if Nvram/Programx exists - else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram" + else if (Directory.Exists(directoryPrefix + dirSeparator + nvramFolder + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) { - Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber); - filePathPrefix = directoryPrefix + dirSeparator + "Nvram" + Debug.Console(0, @"{0}/program{1} directory found", nvramFolder, InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + nvramFolder + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; } // If neither exists, set path to User/ProgramX else { - Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber); - filePathPrefix = directoryPrefix + dirSeparator + "User" + Debug.Console(0, @"No previous directory found. Using {0}/program{1}", userFolder, InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + userFolder + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; } } From d0dbbe095f5b5a346c31c2a64bd7521bad98dede Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 8 Jul 2021 11:16:41 -0600 Subject: [PATCH 251/480] ci: Remove condition on upload to release --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d429cdc0..a74ca03e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -90,7 +90,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Upload the build package to the release - name: Upload Release Package - if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-') id: upload_release uses: actions/upload-release-asset@v1 with: From 2181410927cc69b0b9ca24b87eb4640539ec923d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 12 Jul 2021 17:22:36 -0600 Subject: [PATCH 252/480] #736 Adds IEssentialsRoom and IEssentialsHuddleSpaceRoom interfaces Refactors all references to EssentialsRoomBase and EssentialsHuddleSpaceRoom to use the new interfaces instead --- PepperDashEssentials/ControlSystem.cs | 6 +- .../PepperDashEssentials.csproj | 1 + .../Room/Config/EssentialsRoomConfig.cs | 4 +- .../EsentialsRoomEmergencyContactClosure.cs | 4 +- .../Room/Types/EssentialsDualDisplayRoom.cs | 4 +- .../Room/Types/EssentialsHuddleSpaceRoom.cs | 2 +- .../Room/Types/EssentialsHuddleVtc1Room.cs | 6 +- .../Room/Types/IEssentialsHuddleSpaceRoom.cs | 28 +++ .../UI/EssentialsTouchpanelController.cs | 4 +- .../UIDrivers/DualDisplayRouting.cs | 6 +- .../Essentials/EssentialsHeaderDriver.cs | 6 +- ...tialsPresentationPanelAvFunctionsDriver.cs | 6 +- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 14 +- .../UIDrivers/SmartObjectRoomsList.cs | 6 +- .../UIDrivers/SourceChangeArgs.cs | 2 +- .../DeviceTypeInterfaces/IMobileControl.cs | 2 +- .../Devices/EssentialsDevice.cs | 222 +++++++++--------- .../Devices/IProjectorInterfaces.cs | 8 +- .../Devices/IReconfigurableDevice.cs | 19 ++ .../Devices/ReconfigurableDevice.cs | 2 +- ...lsHuddleSpaceFusionSystemControllerBase.cs | 4 +- .../Fusion/FusionCustomPropertiesBridge.cs | 2 +- .../PepperDash_Essentials_Core.csproj | 2 + .../RoomOnToDefaultSourceWhenOccupied.cs | 4 +- .../Room/EssentialsRoomBase.cs | 2 +- .../Room/IEssentialsRoom.cs | 66 ++++++ .../Room/Interfaces.cs | 5 +- 27 files changed, 278 insertions(+), 159 deletions(-) create mode 100644 PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IReconfigurableDevice.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index e4c521b5..6d3ca5c6 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -452,7 +452,7 @@ namespace PepperDash.Essentials foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) { - var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; + var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom; if (room != null) { // default IPID @@ -474,7 +474,7 @@ namespace PepperDash.Essentials } } - if (room is EssentialsHuddleSpaceRoom) + if (room is IEssentialsHuddleSpaceRoom) { DeviceManager.AddDevice(room); @@ -524,7 +524,7 @@ namespace PepperDash.Essentials } - private static void CreateMobileControlBridge(EssentialsRoomBase room) + private static void CreateMobileControlBridge(IEssentialsRoom room) { var mobileControl = GetMobileControlDevice(); diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 7b548dd5..14bd450a 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -149,6 +149,7 @@ + diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 6a59cc56..5ec0565d 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Room.Config /// Gets and operating, standalone emergegncy object that can be plugged into a room. /// Returns null if there is no emergency defined /// - public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room) + public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room) { // This emergency var emergency = props.Emergency; @@ -96,7 +96,7 @@ namespace PepperDash.Essentials.Room.Config if (behaviour == "trackroomstate") { // Tie LED enable to room power state - var essRoom = room as EssentialsRoomBase; + var essRoom = room as IEssentialsRoom; essRoom.OnFeedback.OutputChange += (o, a) => { if (essRoom.OnFeedback.BoolValue) diff --git a/PepperDashEssentials/Room/Emergency/EsentialsRoomEmergencyContactClosure.cs b/PepperDashEssentials/Room/Emergency/EsentialsRoomEmergencyContactClosure.cs index ab40d2fe..c40ed496 100644 --- a/PepperDashEssentials/Room/Emergency/EsentialsRoomEmergencyContactClosure.cs +++ b/PepperDashEssentials/Room/Emergency/EsentialsRoomEmergencyContactClosure.cs @@ -17,11 +17,11 @@ namespace PepperDash.Essentials.Room public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase { - EssentialsRoomBase Room; + IEssentialsRoom Room; string Behavior; bool TriggerOnClose; - public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) : + public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) : base(key) { Room = room; diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index ccce0af5..d58f6ac7 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -645,9 +645,9 @@ namespace PepperDash.Essentials public static void AllRoomsOff() { var allRooms = DeviceManager.AllDevices.Where(d => - d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); + d is IEssentialsHuddleSpaceRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); foreach (var room in allRooms) - (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as EssentialsHuddleSpaceRoom).SourceListKey); + (room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey); } #region IPrivacy Members diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 9f388252..7a57e9c1 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config; namespace PepperDash.Essentials { - public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay + public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom { public event EventHandler CurrentVolumeDeviceChange; public event SourceInfoChangeHandler CurrentSourceChange; diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 85cfe90f..e6b12f4e 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -733,10 +733,10 @@ namespace PepperDash.Essentials /// public static void AllRoomsOff() { - var allRooms = DeviceManager.AllDevices.Where(d => - d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); + var allRooms = DeviceManager.AllDevices.Where(d => + d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); foreach (var room in allRooms) - (room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); + (room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); } diff --git a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs new file mode 100644 index 00000000..6feff235 --- /dev/null +++ b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Room.Config; +using PepperDash.Essentials.Core.Devices; + +using PepperDash.Core; + +namespace PepperDash.Essentials +{ + public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay + { + bool ExcludeFromGlobalFunctions { get; } + + void RunRouteAction(string routeKey); + + EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; } + + IBasicVolumeControls CurrentVolumeControls { get; } + + event EventHandler CurrentVolumeDeviceChange; + } +} \ No newline at end of file diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 65039872..5c4349fd 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -222,7 +222,7 @@ namespace PepperDash.Essentials // spin up different room drivers depending on room type var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); - if (room is EssentialsHuddleSpaceRoom) + if (room is IEssentialsHuddleSpaceRoom) { // Screen Saver Driver mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); @@ -236,7 +236,7 @@ namespace PepperDash.Essentials var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); avDriver.DefaultRoomKey = props.DefaultRoomKey; mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; + avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom; // Environment Driver if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) diff --git a/PepperDashEssentials/UIDrivers/DualDisplayRouting.cs b/PepperDashEssentials/UIDrivers/DualDisplayRouting.cs index 1aeb7a3c..4b29061d 100644 --- a/PepperDashEssentials/UIDrivers/DualDisplayRouting.cs +++ b/PepperDashEssentials/UIDrivers/DualDisplayRouting.cs @@ -146,18 +146,18 @@ // } -// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) +// void CurrentRoom_CurrentSourceInfoChange(IEssentialsRoom room, SourceListItem info, ChangeType type) // { // } -// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) +// void CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type) // { // TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName; // } -// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) +// void CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type) // { // TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName; // } diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index ccaedd9c..df87c8f4 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -52,7 +52,7 @@ namespace PepperDash.Essentials CaretInterlock = new JoinedSigInterlock(TriList); } - void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom) + void SetUpGear(IAVDriver avDriver, IEssentialsRoom currentRoom) { // Gear TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear"); @@ -105,7 +105,7 @@ namespace PepperDash.Essentials { string message = null; var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey) - as EssentialsHuddleSpaceRoom; + as IEssentialsHuddleSpaceRoom; if (room != null) message = room.PropertiesConfig.HelpMessage; else @@ -283,7 +283,7 @@ namespace PepperDash.Essentials /// /// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type /// - public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom) + public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, IEssentialsHuddleSpaceRoom currentRoom) { HeaderButtonsAreSetUp = false; diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs index 4a8cb53c..9c8514ea 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPresentationPanelAvFunctionsDriver.cs @@ -983,7 +983,7 @@ // /// // /// Handles source change // /// -// void _CurrentRoom_SourceInfoChange(EssentialsRoomBase room, +// void _CurrentRoom_SourceInfoChange(IEssentialsRoom room, // SourceListItem info, ChangeType change) // { // if (change == ChangeType.WillChange) @@ -995,7 +995,7 @@ // /// // /// // /// -// void _CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) +// void _CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type) // { // if (type == ChangeType.DidChange) // { @@ -1021,7 +1021,7 @@ // /// // /// // /// -// void _CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) +// void _CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type) // { // if (type == ChangeType.DidChange) // { diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index f22565e5..a0d5947c 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -78,7 +78,7 @@ namespace PepperDash.Essentials /// /// /// - public EssentialsHuddleSpaceRoom CurrentRoom + public IEssentialsHuddleSpaceRoom CurrentRoom { get { return _CurrentRoom; } set @@ -86,7 +86,7 @@ namespace PepperDash.Essentials SetCurrentRoom(value); } } - EssentialsHuddleSpaceRoom _CurrentRoom; + IEssentialsHuddleSpaceRoom _CurrentRoom; /// /// @@ -498,7 +498,7 @@ namespace PepperDash.Essentials TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true; // Run default source when room is off and share is pressed if (!CurrentRoom.OnFeedback.BoolValue) - CurrentRoom.RunDefaultPresentRoute(); + (CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute(); } @@ -583,7 +583,7 @@ namespace PepperDash.Essentials void UiSelectSource(string key) { // Run the route and when it calls back, show the source - CurrentRoom.RunRouteAction(key, new Action(() => { })); + CurrentRoom.RunRouteAction(key); } /// @@ -745,7 +745,7 @@ namespace PepperDash.Essentials /// /// Helper for property setter. Sets the panel to the given room, latching up all functionality /// - public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room) + public void RefreshCurrentRoom(IEssentialsHuddleSpaceRoom room) { if (_CurrentRoom != null) { @@ -836,7 +836,7 @@ namespace PepperDash.Essentials } } - void SetCurrentRoom(EssentialsHuddleSpaceRoom room) + void SetCurrentRoom(IEssentialsHuddleSpaceRoom room) { if (_CurrentRoom == room) return; // Disconnect current (probably never called) @@ -871,7 +871,7 @@ namespace PepperDash.Essentials UpdateMCJoins(_CurrentRoom); } - void UpdateMCJoins(EssentialsHuddleSpaceRoom room) + void UpdateMCJoins(IEssentialsHuddleSpaceRoom room) { TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); diff --git a/PepperDashEssentials/UIDrivers/SmartObjectRoomsList.cs b/PepperDashEssentials/UIDrivers/SmartObjectRoomsList.cs index e43abc09..2543e664 100644 --- a/PepperDashEssentials/UIDrivers/SmartObjectRoomsList.cs +++ b/PepperDashEssentials/UIDrivers/SmartObjectRoomsList.cs @@ -38,7 +38,7 @@ namespace PepperDash.Essentials /// /// Sets feedback for the given room /// - public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room) + public void SetFeedbackForRoom(IEssentialsHuddleSpaceRoom room) { var itemToSet = Items.FirstOrDefault(i => i.Room == room); if (itemToSet != null) @@ -48,11 +48,11 @@ namespace PepperDash.Essentials public class SmartObjectRoomsListItem { - public EssentialsHuddleSpaceRoom Room { get; private set; } + public IEssentialsHuddleSpaceRoom Room { get; private set; } SmartObjectRoomsList Parent; public uint Index { get; private set; } - public SmartObjectRoomsListItem(EssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent, + public SmartObjectRoomsListItem(IEssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent, Action buttonAction) { Room = room; diff --git a/PepperDashEssentials/UIDrivers/SourceChangeArgs.cs b/PepperDashEssentials/UIDrivers/SourceChangeArgs.cs index c777c08e..5c034084 100644 --- a/PepperDashEssentials/UIDrivers/SourceChangeArgs.cs +++ b/PepperDashEssentials/UIDrivers/SourceChangeArgs.cs @@ -12,5 +12,5 @@ namespace PepperDash.Essentials ///// ///// The handler type for a Room's SourceInfoChange ///// - //public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type); + //public delegate void SourceInfoChangeHandler(IEssentialsRoom room, SourceListItem info, ChangeType type); } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index c87e7865..a2dda43a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// public interface IMobileControl : IKeyed { - void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent); + void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent); void LinkSystemMonitorToAppServer(); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 8d7f2c8d..781101d4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -1,113 +1,113 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharp.Reflection; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Config; - -namespace PepperDash.Essentials.Core -{ - /// - /// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class - /// - [Description("The base Essentials Device Class")] - public abstract class EssentialsDevice : Device - { - protected EssentialsDevice(string key) - : base(key) - { - - } - - protected EssentialsDevice(string key, string name) - : base(key, name) - { - - } - } - - [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] - public class DescriptionAttribute : Attribute - { - private string _Description; - - public DescriptionAttribute(string description) - { - Debug.Console(2, "Setting Description: {0}", description); - _Description = description; - } - - public string Description - { - get { return _Description; } - } - } - - [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] - public class ConfigSnippetAttribute : Attribute - { - private string _ConfigSnippet; - - public ConfigSnippetAttribute(string configSnippet) - { - Debug.Console(2, "Setting Config Snippet {0}", configSnippet); - _ConfigSnippet = configSnippet; - } - - public string ConfigSnippet - { - get { return _ConfigSnippet; } - } - } - - /// - /// Devices the basic needs for a Device Factory - /// - public abstract class EssentialsDeviceFactory : IDeviceFactory where T:EssentialsDevice - { - #region IDeviceFactory Members - - /// - /// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device - /// - public List TypeNames { get; protected set; } - - /// - /// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list - /// - public void LoadTypeFactories() - { - foreach (var typeName in TypeNames) - { - Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); - var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core +{ + /// + /// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class + /// + [Description("The base Essentials Device Class")] + public abstract class EssentialsDevice : Device + { + protected EssentialsDevice(string key) + : base(key) + { + + } + + protected EssentialsDevice(string key, string name) + : base(key, name) + { + + } + } + + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] + public class DescriptionAttribute : Attribute + { + private string _Description; + + public DescriptionAttribute(string description) + { + Debug.Console(2, "Setting Description: {0}", description); + _Description = description; + } + + public string Description + { + get { return _Description; } + } + } + + [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] + public class ConfigSnippetAttribute : Attribute + { + private string _ConfigSnippet; + + public ConfigSnippetAttribute(string configSnippet) + { + Debug.Console(2, "Setting Config Snippet {0}", configSnippet); + _ConfigSnippet = configSnippet; + } + + public string ConfigSnippet + { + get { return _ConfigSnippet; } + } + } + + /// + /// Devices the basic needs for a Device Factory + /// + public abstract class EssentialsDeviceFactory : IDeviceFactory where T:EssentialsDevice + { + #region IDeviceFactory Members + + /// + /// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device + /// + public List TypeNames { get; protected set; } + + /// + /// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list + /// + public void LoadTypeFactories() + { + foreach (var typeName in TypeNames) + { + Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); + var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; string description = descriptionAttribute[0].Description; - var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[]; - DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice); - } - } - - /// - /// The method that will build the device - /// - /// The device config - /// An instance of the device - public abstract EssentialsDevice BuildDevice(DeviceConfig dc); - - #endregion - } - - /// - /// Devices the basic needs for a Device Factory - /// - public abstract class EssentialsPluginDeviceFactory : EssentialsDeviceFactory, IPluginDeviceFactory where T : EssentialsDevice - { - /// - /// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33") - /// - public string MinimumEssentialsFrameworkVersion { get; protected set; } - } + var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[]; + DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice); + } + } + + /// + /// The method that will build the device + /// + /// The device config + /// An instance of the device + public abstract EssentialsDevice BuildDevice(DeviceConfig dc); + + #endregion + } + + /// + /// Devices the basic needs for a Device Factory + /// + public abstract class EssentialsPluginDeviceFactory : EssentialsDeviceFactory, IPluginDeviceFactory where T : EssentialsDevice + { + /// + /// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33") + /// + public string MinimumEssentialsFrameworkVersion { get; protected set; } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IProjectorInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IProjectorInterfaces.cs index 6efb7776..70e2e215 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IProjectorInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IProjectorInterfaces.cs @@ -1,7 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; using Crestron.SimplSharp; namespace PepperDash.Essentials.Core diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IReconfigurableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IReconfigurableDevice.cs new file mode 100644 index 00000000..ab0e37c3 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IReconfigurableDevice.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core.Config; + + +namespace PepperDash.Essentials.Core.Devices +{ + public interface IReconfigurableDevice + { + event EventHandler ConfigChanged; + + DeviceConfig Config { get; } + + void SetConfig(DeviceConfig config); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs index 81988199..3239e192 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/ReconfigurableDevice.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core.Devices /// /// /// - public abstract class ReconfigurableDevice : EssentialsDevice + public abstract class ReconfigurableDevice : EssentialsDevice, IReconfigurableDevice { public event EventHandler ConfigChanged; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index b26b1980..a172ab49 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -33,7 +33,7 @@ namespace PepperDash.Essentials.Core.Fusion protected FusionRoom FusionRoom; protected Dictionary FusionStaticAssets; public long PushNotificationTimeout = 5000; - protected EssentialsRoomBase Room; + protected IEssentialsRoom Room; public long SchedulePollInterval = 300000; private Event _currentMeeting; @@ -86,7 +86,7 @@ namespace PepperDash.Essentials.Core.Fusion #endregion - public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId, string joinMapKey) + public EssentialsHuddleSpaceFusionSystemControllerBase(IEssentialsRoom room, uint ipId, string joinMapKey) : base(room.Key + "-fusion") { try diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionCustomPropertiesBridge.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionCustomPropertiesBridge.cs index 01b230f9..89b9fcdb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionCustomPropertiesBridge.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/FusionCustomPropertiesBridge.cs @@ -82,7 +82,7 @@ namespace PepperDash.Essentials.Core.Fusion deviceConfig.Properties = JToken.FromObject(devProps); } - else if (device is EssentialsRoomBase) + else if (device is IEssentialsRoom) { // Set the room name if (!string.IsNullOrEmpty(roomInfo.Name)) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index e65b081b..6e48fd66 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -197,6 +197,7 @@ + @@ -288,6 +289,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs index f24daf82..81cbff9e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs @@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core ScheduledEventGroup FeatureEventGroup; - public EssentialsRoomBase Room { get; private set; } + public IEssentialsRoom Room { get; private set; } private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom; @@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core /// void SetUpDevice() { - Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as EssentialsRoomBase; + Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IEssentialsRoom; if (Room != null) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index cae027f5..0d8e9803 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core /// /// /// - public abstract class EssentialsRoomBase : ReconfigurableDevice + public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom { /// /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs new file mode 100644 index 00000000..e83c4b2f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Room.Config; +using PepperDash.Essentials.Core.Devices; + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + /// + /// Describes the basic functionality of an EssentialsRoom + /// + public interface IEssentialsRoom : IKeyName, IReconfigurableDevice + { + BoolFeedback OnFeedback { get; } + + event EventHandler RoomOccupancyIsSet; + + BoolFeedback IsWarmingUpFeedback { get; } + BoolFeedback IsCoolingDownFeedback { get; } + + IOccupancyStatusProvider RoomOccupancy { get; } + bool OccupancyStatusProviderIsRemote { get; } + + bool IsMobileControlEnabled { get; } + IMobileControlRoomBridge MobileControlRoomBridge { get; } + + string SourceListKey { get; } + + SecondsCountdownTimer ShutdownPromptTimer { get; } + int ShutdownPromptSeconds { get; } + int ShutdownVacancySeconds { get; } + eShutdownType ShutdownType { get; } + + EssentialsRoomEmergencyBase Emergency { get; } + + Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; } + + string LogoUrlLightBkgnd { get; } + string LogoUrlDarkBkgnd { get; } + + eVacancyMode VacancyMode { get; } + + bool ZeroVolumeWhenSwtichingVolumeDevices { get; } + + void StartShutdown(eShutdownType type); + void StartRoomVacancyTimer(eVacancyMode mode); + + void Shutdown(); + + void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes); + + void PowerOnToDefaultOrLastSource(); + bool RunDefaultPresentRoute(); + + void SetDefaultLevels(); + + void RoomVacatedForTimeoutPeriod(object o); + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs index 82871228..592b0bd9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; + namespace PepperDash.Essentials.Core { /// @@ -64,5 +65,7 @@ namespace PepperDash.Essentials.Core { bool RunDefaultCallRoute(); } - + + + } \ No newline at end of file From a37814ab3c01c3370ab57a148bc90083491a7292 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 12 Jul 2021 21:49:54 -0600 Subject: [PATCH 253/480] #736 adds IEssentialsHuddleVtc1Room and refactors to use interface rather than EssentialsHudleVtc1Room --- PepperDashEssentials/ControlSystem.cs | 4 ++-- .../EssentialsHuddleVtc1FusionController.cs | 22 +++++++++---------- .../Room/Types/EssentialsHuddleVtc1Room.cs | 3 +-- .../Room/Types/IEssentialsHuddleSpaceRoom.cs | 20 +++++++++++++++++ .../UI/EssentialsTouchpanelController.cs | 6 ++--- .../Essentials/EssentialsHeaderDriver.cs | 2 +- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 16 +++++++------- 7 files changed, 46 insertions(+), 27 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 6d3ca5c6..033d82fe 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -486,12 +486,12 @@ namespace PepperDash.Essentials CreateMobileControlBridge(room); } - else if (room is EssentialsHuddleVtc1Room) + else if (room is IEssentialsHuddleVtc1Room) { DeviceManager.AddDevice(room); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index c4a68d4e..54d936f0 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Fusion { BooleanSigData CodecIsInCall; - public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey) + public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey) : base(room, ipId, joinMapKey) { @@ -37,7 +37,7 @@ namespace PepperDash.Essentials.Fusion { try { - var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec; if (codec == null) { @@ -141,7 +141,7 @@ namespace PepperDash.Essentials.Fusion void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e) { - var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec; CodecIsInCall.InputSig.BoolValue = codec.IsInCall; } @@ -174,11 +174,11 @@ namespace PepperDash.Essentials.Fusion // Moved to CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly); // Don't think we need to get current status of this as nothing should be alive yet. - (Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; + (Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; - FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; @@ -187,7 +187,7 @@ namespace PepperDash.Essentials.Fusion protected override void SetUpSources() { // Sources - var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); + var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey); if (dict != null) { // NEW PROCESS: @@ -238,7 +238,7 @@ namespace PepperDash.Essentials.Fusion else { Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", - (Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); + (Room as IEssentialsHuddleVtc1Room).SourceListKey, Room.Key); } } @@ -259,7 +259,7 @@ namespace PepperDash.Essentials.Fusion display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); } - var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; + var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; if (defaultDisplay == null) { Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); @@ -332,7 +332,7 @@ namespace PepperDash.Essentials.Fusion string displayName = string.Format("Display {0} - ", displayIndex); - if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) + if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay) { // Power on var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); @@ -351,7 +351,7 @@ namespace PepperDash.Essentials.Fusion // Current Source var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); - defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ; + defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ; } } } diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index e6b12f4e..5e7b5c37 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -17,8 +17,7 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces; namespace PepperDash.Essentials { - public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, - IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback + public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room { private bool _codecExternalSourceChange; public event EventHandler CurrentVolumeDeviceChange; diff --git a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs index 6feff235..efc126f6 100644 --- a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs @@ -8,6 +8,10 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.AudioCodec; + using PepperDash.Core; @@ -25,4 +29,20 @@ namespace PepperDash.Essentials event EventHandler CurrentVolumeDeviceChange; } + + public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, + IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback + { + EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } + + void RunRouteAction(string routeKey); + + IHasScheduleAwareness ScheduleSource { get; } + + BoolFeedback InCallFeedback { get; } + + BoolFeedback PrivacyModeIsOnFeedback { get; } + + string DefaultCodecRouteString { get; } + } } \ No newline at end of file diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 5c4349fd..7873bf42 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -270,7 +270,7 @@ namespace PepperDash.Essentials tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); } } - else if (room is EssentialsHuddleVtc1Room) + else if (room is IEssentialsHuddleVtc1Room) { Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); @@ -284,11 +284,11 @@ namespace PepperDash.Essentials var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props); var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, - (room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); + (room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); avDriver.SetVideoCodecDriver(codecDriver); avDriver.DefaultRoomKey = props.DefaultRoomKey; mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; + avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room; // Environment Driver if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index df87c8f4..fa6f67d5 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -221,7 +221,7 @@ namespace PepperDash.Essentials /// /// Sets up Header Buttons for the EssentialsHuddleVtc1Room type /// - public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom) + public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, IEssentialsHuddleVtc1Room currentRoom) { HeaderButtonsAreSetUp = false; diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index a4e88e7e..6280f54e 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -50,7 +50,7 @@ namespace PepperDash.Essentials /// /// /// - public EssentialsHuddleVtc1Room CurrentRoom + public IEssentialsHuddleVtc1Room CurrentRoom { get { return _CurrentRoom; } set @@ -58,7 +58,7 @@ namespace PepperDash.Essentials SetCurrentRoom(value); } } - EssentialsHuddleVtc1Room _CurrentRoom; + IEssentialsHuddleVtc1Room _CurrentRoom; /// /// For hitting feedbacks @@ -652,7 +652,7 @@ namespace PepperDash.Essentials if (!CurrentRoom.OnFeedback.BoolValue) { // If there's no default, show UI elements - if (!CurrentRoom.RunDefaultPresentRoute()) + if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); } } @@ -743,7 +743,7 @@ namespace PepperDash.Essentials void UiSelectSource(string key) { // Run the route and when it calls back, show the source - CurrentRoom.RunRouteAction(key, new Action(() => { })); + CurrentRoom.RunRouteAction(key); } /// @@ -894,7 +894,7 @@ namespace PepperDash.Essentials /// /// Helper for property setter. Sets the panel to the given room, latching up all functionality /// - void RefreshCurrentRoom(EssentialsHuddleVtc1Room room) + void RefreshCurrentRoom(IEssentialsHuddleVtc1Room room) { if (_CurrentRoom != null) @@ -969,7 +969,7 @@ namespace PepperDash.Essentials } } - void SetCurrentRoom(EssentialsHuddleVtc1Room room) + void SetCurrentRoom(IEssentialsHuddleVtc1Room room) { if (_CurrentRoom == room) return; // Disconnect current (probably never called) @@ -1004,7 +1004,7 @@ namespace PepperDash.Essentials UpdateMCJoins(_CurrentRoom); } - void UpdateMCJoins(EssentialsHuddleVtc1Room room) + void UpdateMCJoins(IEssentialsHuddleVtc1Room room) { TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl); TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl); @@ -1443,7 +1443,7 @@ namespace PepperDash.Essentials /// public interface IAVWithVCDriver : IAVDriver { - EssentialsHuddleVtc1Room CurrentRoom { get; } + IEssentialsHuddleVtc1Room CurrentRoom { get; } PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; } /// From 4c50d6980fbbe86c53bbf45e7c4ec55f0b02c4c8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 14 Jul 2021 14:38:18 -0600 Subject: [PATCH 254/480] #740 Adds IPartitionStateProvider interface and adds to GlsParitionSensorController --- .../GlsPartitionSensorController.cs | 2 +- .../PartitionSensor/IPartitionStateProvider.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index b0b58f34..768e476b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -13,7 +13,7 @@ using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core { [Description("Wrapper class for GLS Cresnet Partition Sensor")] - public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice + public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider { private GlsPartCn _partitionSensor; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs new file mode 100644 index 00000000..0080e472 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Describes the functionality of a device that senses and provides partition state + /// + public interface IPartitionStateProvider + { + BoolFeedback PartitionSensedFeedback { get; } + } +} \ No newline at end of file From d97ca6d5a437b8be80b8cca25518de7f16476670 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 14 Jul 2021 14:42:13 -0600 Subject: [PATCH 255/480] #741 Adds EssentialsRoomCombinerPropertiesConfig --- .../PepperDash_Essentials_Core.csproj | 2 + .../EssentialsRoomCombinerPropertiesConfig.cs | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 6e48fd66..7e18606f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -233,6 +233,7 @@ + @@ -287,6 +288,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs new file mode 100644 index 00000000..5f1adcfa --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core.Room +{ + /// + /// Config properties for an EssentialsRoomCombiner device + /// + public class EssentialsRoomCombinerPropertiesConfig + { + [JsonProperty("partitions")] + public List Partitions {get; set;} + + [JsonProperty("scenarios")] + public List Scenarios { get; set; } + + [JsonProperty("rooms")] + public List Rooms {get; set;} + } + + /// + /// Config properties for a partition that separates rooms + /// + public class PartitionConfig : IKeyName + { + /// + /// Key of the device that implements IPartitionStateProvider to provide the state of the partition + /// + [JsonProperty("deviceKey")] + public string DeviceKey { get; set; } + + /// + /// Keys of the rooms that this partion would be located between + /// + [JsonProperty("roomKeys")] + public List RoomKeys { get; set; } + } + + /// + /// Config propeties for a room combination scenario + /// + public class RoomCombinationScenario : IKeyName + { + [JsonProperty("partitionStates")] + public List PartitionStates { get; set; } + + [JsonProperty("enabledRoomKeys")] + public List EnabledRoomKeys { get; set; } + + [JsonProperty("actions")] + public List Actions { get; set; } + } + + /// + /// Config properties to represent the state of a partition sensor in a RoomCombinationScenario + /// + public class PartitionState + { + [JsonProperty("partitionKey")] + public string PartitionKey { get; set; } + + [JsonProperty("partitionSensedState")] + public bool PartitionSensedState { get; set; } + } +} \ No newline at end of file From 06a3dda2e47983d40d8a278dff60ff7e3f8872e3 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 14 Jul 2021 22:12:41 -0600 Subject: [PATCH 256/480] Starts on interfaces for room combination --- .../IPartitionStateProvider.cs | 13 +++++- .../PepperDash_Essentials_Core.csproj | 2 + .../EssentialsRoomCombinerPropertiesConfig.cs | 21 +++++++--- .../Room/Combining/IEssentialsRoomCombiner.cs | 41 +++++++++++++++++++ .../Room/Combining/RoomCombinationScenario.cs | 17 ++++++++ 5 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs index 0080e472..08b8012b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs @@ -4,13 +4,24 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + namespace PepperDash.Essentials.Core { /// /// Describes the functionality of a device that senses and provides partition state /// - public interface IPartitionStateProvider + public interface IPartitionStateProvider : IKeyName { BoolFeedback PartitionSensedFeedback { get; } } + + public interface IManualPartitionSensor : IPartitionStateProvider + { + void SetPartitionStatePresent(); + + void SetPartitionStateNotPresent(); + + void ToggglePartitionState(); + } } \ 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 7e18606f..b65cfd62 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -289,6 +289,8 @@ + + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 5f1adcfa..74d5ebda 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -8,21 +8,30 @@ using PepperDash.Core; using Newtonsoft.Json; -namespace PepperDash.Essentials.Core.Room +namespace PepperDash.Essentials.Core { /// /// Config properties for an EssentialsRoomCombiner device /// public class EssentialsRoomCombinerPropertiesConfig { + /// + /// The list of partitions that device the rooms + /// [JsonProperty("partitions")] public List Partitions {get; set;} + /// + /// The list of combinations scenarios for the rooms + /// [JsonProperty("scenarios")] - public List Scenarios { get; set; } + public List Scenarios { get; set; } - [JsonProperty("rooms")] - public List Rooms {get; set;} + /// + /// The list of rooms that can be combined + /// + [JsonProperty("roomMap")] + public Dictionary RoomMap {get; set;} } /// @@ -46,7 +55,7 @@ namespace PepperDash.Essentials.Core.Room /// /// Config propeties for a room combination scenario /// - public class RoomCombinationScenario : IKeyName + public class RoomCombinationScenarioConfig : IKeyName { [JsonProperty("partitionStates")] public List PartitionStates { get; set; } @@ -67,6 +76,6 @@ namespace PepperDash.Essentials.Core.Room public string PartitionKey { get; set; } [JsonProperty("partitionSensedState")] - public bool PartitionSensedState { get; set; } + public bool PartitionPresent { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs new file mode 100644 index 00000000..894dd098 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + /// + /// Describes the functionality for an EssentailsRoomCombiner device + /// + public interface IEssentialsRoomCombiner + { + // TODO: Update the EventArgs class as needed to specify scenario change + event EventHandler RoomCombinationScenarioChanged; + + BoolFeedback IsInAutoModeFeedback {get;} + + void SetAutoMode(); + + void SetManualMode(); + + void ToggleMode(); + + List Scenarios { get; } + + List Partitions { get; } + + void TogglePartitionState(string partitionKey); + } + + public interface IRoomCombinationScenario : IKeyName + { + BoolFeedback IsActive { get; } + + void Activate(); + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs new file mode 100644 index 00000000..965428cb --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Represents a room combination scenario + /// + public class RoomCombinationScenario: IRoomCombinationScenario + { + + } + +} \ No newline at end of file From 7fd52814a012efb10cfdab442836571a247f0797 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 15 Jul 2021 10:11:27 -0600 Subject: [PATCH 257/480] implements IKeyName as required on config classes --- .../EssentialsRoomCombinerPropertiesConfig.cs | 12 ++++++++++++ .../Room/Combining/RoomCombinationScenario.cs | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 74d5ebda..4576ac4d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -39,6 +39,12 @@ namespace PepperDash.Essentials.Core /// public class PartitionConfig : IKeyName { + [JsonProperty("key")] + public string Key { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + /// /// Key of the device that implements IPartitionStateProvider to provide the state of the partition /// @@ -57,6 +63,12 @@ namespace PepperDash.Essentials.Core /// public class RoomCombinationScenarioConfig : IKeyName { + [JsonProperty("key")] + public string Key { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("partitionStates")] public List PartitionStates { get; set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs index 965428cb..94e2ed0a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Core { /// @@ -11,6 +13,18 @@ namespace PepperDash.Essentials.Core /// public class RoomCombinationScenario: IRoomCombinationScenario { + [JsonProperty("key")] + public string Key { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } + + public BoolFeedback IsActive { get; private set; } + + public void Activate() + { + + } } From c2e5bd290a01675cee4488266f00ef8c90416572 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 15 Jul 2021 16:40:25 -0600 Subject: [PATCH 258/480] #742 Adding EssentialsRoomCombiner device (in progress) --- .../PepperDash_Essentials_Core.csproj | 1 + .../Room/Combining/EssentialsRoomCombiner.cs | 133 ++++++++++++++++++ .../EssentialsRoomCombinerPropertiesConfig.cs | 31 ++-- .../Room/Combining/IEssentialsRoomCombiner.cs | 49 ++++++- .../Room/Combining/RoomCombinationScenario.cs | 58 +++++++- 5 files changed, 257 insertions(+), 15 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index b65cfd62..38a532ba 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -288,6 +288,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs new file mode 100644 index 00000000..6e9a0afb --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner + { + private EssentialsRoomCombinerPropertiesConfig _propertiesConfig; + + private IRoomCombinationScenario _currentScenario; + + private List _rooms; + + private bool isInAutoMode; + + public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props) + : base(key) + { + _propertiesConfig = props; + + IsInAutoModeFeedback = new BoolFeedback(() => isInAutoMode); + + // default to auto mode + isInAutoMode = true; + + if (_propertiesConfig.defaultToManualMode) + { + isInAutoMode = false; + } + + IsInAutoModeFeedback.FireUpdate(); + + CreateScenarios(); + + SetupPartitionStateProviders(); + + SetRooms(); + } + + void CreateScenarios() + { + foreach (var scenarioConfig in _propertiesConfig.Scenarios) + { + var scenario = new RoomCombinationScenario(scenarioConfig); + } + } + + void SetRooms() + { + foreach (var roomKey in _propertiesConfig.RoomKeys) + { + var room = DeviceManager.GetDeviceForKey(roomKey) as IEssentialsRoom; + if (room != null) + { + _rooms.Add(room); + } + } + } + + void SetupPartitionStateProviders() + { + + } + + #region IEssentialsRoomCombiner Members + + public event EventHandler RoomCombinationScenarioChanged; + + public IRoomCombinationScenario CurrentScenario + { + get + { + return _currentScenario; + } + set + { + if (value != _currentScenario) + { + _currentScenario = value; + var handler = RoomCombinationScenarioChanged; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + } + } + + public BoolFeedback IsInAutoModeFeedback { get; private set; } + + public void SetAutoMode() + { + isInAutoMode = true; + IsInAutoModeFeedback.FireUpdate(); + } + + public void SetManualMode() + { + isInAutoMode = false; + IsInAutoModeFeedback.FireUpdate(); + } + + public void ToggleMode() + { + isInAutoMode = !isInAutoMode; + IsInAutoModeFeedback.FireUpdate(); + } + + public List RoomCombinationScenarios { get; private set; } + + public List PartitionStateProviders { get; private set; } + + public void TogglePartitionState(string partitionKey) + { + var partition = PartitionStateProviders.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IManualPartitionSensor; + + if (partition != null) + { + partition.ToggglePartitionState(); + } + } + + public void SetRoomCombinationScenario(string scenarioKey) + { + + } + + #endregion + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 4576ac4d..95b97c35 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -28,10 +28,22 @@ namespace PepperDash.Essentials.Core public List Scenarios { get; set; } /// - /// The list of rooms that can be combined + /// The list of rooms keys that can be combined /// [JsonProperty("roomMap")] - public Dictionary RoomMap {get; set;} + public List RoomKeys {get; set;} + + /// + /// Set to true to default to manual mode + /// + [JsonProperty("defaultToManualMode")] + public bool defaultToManualMode { get; set; } + + /// + /// The key of the scenario to default to at system startup if in manual mode + /// + [JsonProperty("defaultScenarioKey")] + public string defaultScenarioKey { get; set; } } /// @@ -54,8 +66,8 @@ namespace PepperDash.Essentials.Core /// /// Keys of the rooms that this partion would be located between /// - [JsonProperty("roomKeys")] - public List RoomKeys { get; set; } + [JsonProperty("adjacentRoomKeys")] + public List AdjacentRoomKeys { get; set; } } /// @@ -72,11 +84,14 @@ namespace PepperDash.Essentials.Core [JsonProperty("partitionStates")] public List PartitionStates { get; set; } - [JsonProperty("enabledRoomKeys")] - public List EnabledRoomKeys { get; set; } + [JsonProperty("roomMap")] + public Dictionary RoomMap { get; set; } - [JsonProperty("actions")] - public List Actions { get; set; } + [JsonProperty("activationActions")] + public List ActivationActions { get; set; } + + [JsonProperty("deactivationActions")] + public List DeactivationActions { get; set; } } /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs index 894dd098..142e066c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs @@ -13,28 +13,69 @@ namespace PepperDash.Essentials.Core /// public interface IEssentialsRoomCombiner { - // TODO: Update the EventArgs class as needed to specify scenario change + /// + /// Indicates that the room combination scenario has changed + /// event EventHandler RoomCombinationScenarioChanged; + /// + /// The current room combination scenario + /// + IRoomCombinationScenario CurrentScenario { get; } + + /// + /// When true, indicates the current mode is auto mode + /// BoolFeedback IsInAutoModeFeedback {get;} + /// + /// Sets auto mode + /// void SetAutoMode(); + /// + /// Sets manual mode + /// void SetManualMode(); + /// + /// Toggles the current mode between auto and manual + /// void ToggleMode(); - List Scenarios { get; } + /// + /// The available room combinatino scenarios + /// + List RoomCombinationScenarios { get; } - List Partitions { get; } + /// + /// The partition + /// + List PartitionStateProviders { get; } + /// + /// Toggles the state of a manual partition sensor + /// + /// void TogglePartitionState(string partitionKey); + + /// + /// Sets the room combination scenario (if in manual mode) + /// + /// + void SetRoomCombinationScenario(string scenarioKey); } public interface IRoomCombinationScenario : IKeyName { - BoolFeedback IsActive { get; } + /// + /// When true, indicates that this room combination scenario is active + /// + BoolFeedback IsActiveFeedback { get; } + /// + /// Activates this room combination scenario + /// void Activate(); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs index 94e2ed0a..c1d75c3e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs @@ -13,17 +13,69 @@ namespace PepperDash.Essentials.Core /// public class RoomCombinationScenario: IRoomCombinationScenario { - [JsonProperty("key")] + private RoomCombinationScenarioConfig _config; + public string Key { get; set; } - [JsonProperty("name")] public string Name { get; set; } - public BoolFeedback IsActive { get; private set; } + public List PartitionStates { get; private set; } + + public Dictionary EnabledRoomMap { get; set; } + + private bool _isActive; + + public BoolFeedback IsActiveFeedback { get; private set; } + + List activationActions; + + List deactivationActions; + + public RoomCombinationScenario(RoomCombinationScenarioConfig config) + { + Key = config.Key; + + Name = config.Name; + + PartitionStates = config.PartitionStates; + + EnabledRoomMap = config.RoomMap; + + activationActions = config.ActivationActions; + + deactivationActions = config.DeactivationActions; + + _config = config; + + IsActiveFeedback = new BoolFeedback(() => _isActive); + } public void Activate() { + if (activationActions != null) + { + foreach (var action in activationActions) + { + DeviceJsonApi.DoDeviceAction(action); + } + } + _isActive = true; + IsActiveFeedback.FireUpdate(); + } + + public void Deactivate() + { + if (deactivationActions != null) + { + foreach (var action in deactivationActions) + { + DeviceJsonApi.DoDeviceAction(action); + } + } + + _isActive = false; + IsActiveFeedback.FireUpdate(); } } From e3920132bfa5acbd0b6c00ba9fd7458dc3d32f73 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 16 Jul 2021 14:11:27 -0600 Subject: [PATCH 259/480] #743 Adds SetValueFunc() to all Feedback types --- .../PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs | 5 +++++ .../PepperDashEssentialsBase/Feedbacks/IntFeedback.cs | 6 ++++++ .../PepperDashEssentialsBase/Feedbacks/StringFeedback.cs | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs index f46b4767..055ed5b6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs @@ -62,6 +62,11 @@ namespace PepperDash.Essentials.Core ValueFunc = valueFunc; } + public void SetValueFunc(Func newFunc) + { + ValueFunc = newFunc; + } + public override void FireUpdate() { bool newValue = InTestMode ? TestValue : ValueFunc.Invoke(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs index 25390c2c..53bae09a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs @@ -51,6 +51,12 @@ namespace PepperDash.Essentials.Core ValueFunc = valueFunc; } + public void SetValueFunc(Func newFunc) + { + ValueFunc = newFunc; + } + + public override void FireUpdate() { var newValue = InTestMode ? TestValue : ValueFunc.Invoke(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs index 56251a2e..fb5cccb5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs @@ -52,7 +52,10 @@ namespace PepperDash.Essentials.Core ValueFunc = valueFunc; } - + public void SetValueFunc(Func newFunc) + { + ValueFunc = newFunc; + } public override void FireUpdate() { From 7b7ec533558ee74d93b13f6b035ffa65d2ecce9e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 16 Jul 2021 15:35:52 -0600 Subject: [PATCH 260/480] #742 Updates to room combination interfaces and EssentialsRoomCombiner and EssentialsPartitionController --- .../EssentialsPartitionController.cs | 149 ++++++++++++++++++ .../GlsPartitionSensorController.cs | 10 +- .../IPartitionStateProvider.cs | 13 +- .../PepperDash_Essentials_Core.csproj | 1 + .../Room/Combining/EssentialsRoomCombiner.cs | 38 ++++- .../EssentialsRoomCombinerPropertiesConfig.cs | 4 +- .../Room/Combining/IEssentialsRoomCombiner.cs | 14 +- .../Room/Combining/RoomCombinationScenario.cs | 4 +- 8 files changed, 218 insertions(+), 15 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/EssentialsPartitionController.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/EssentialsPartitionController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/EssentialsPartitionController.cs new file mode 100644 index 00000000..7066be0e --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/EssentialsPartitionController.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Represents an abstract controller device for a partition dividing rooms that are combinable + /// + /// In Auto mode, it can use a partition sensor to automatically determine whether the partition is present. + /// + /// In Manual mode it accepts user input to tell it whether the partition is present. + /// + public class EssentialsPartitionController : IPartitionController + { + private IPartitionStateProvider _partitionSensor; + + private bool isInAutoMode; + + private bool partitionPresent; + + public EssentialsPartitionController(string key, string name, IPartitionStateProvider sensor, bool defaultToManualMode, List adjacentRoomKeys) + { + Key = key; + + Name = name; + + AdjacentRoomKeys = adjacentRoomKeys; + + if (sensor != null) + { + _partitionSensor = sensor; + + if (!defaultToManualMode) + { + SetAutoMode(); + } + else + { + SetManualMode(); + } + } + else + { + SetManualMode(); + } + + PartitionPresentFeedback.FireUpdate(); + } + + void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e) + { + if (isInAutoMode) + { + PartitionPresentFeedback.FireUpdate(); + } + } + + #region IPartitionController Members + + public List AdjacentRoomKeys { get; private set; } + + public void SetAutoMode() + { + isInAutoMode = true; + if (PartitionPresentFeedback != null) + { + PartitionPresentFeedback.SetValueFunc(() => _partitionSensor.PartitionPresentFeedback.BoolValue); + } + else + { + PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionPresentFeedback.BoolValue); + } + + if (_partitionSensor != null) + { + _partitionSensor.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange; + } + } + + public void SetManualMode() + { + isInAutoMode = false; + if (PartitionPresentFeedback != null) + { + PartitionPresentFeedback.SetValueFunc(() => partitionPresent); + } + else + { + PartitionPresentFeedback = new BoolFeedback(() => partitionPresent); + } + + if (_partitionSensor != null) + { + _partitionSensor.PartitionPresentFeedback.OutputChange -= PartitionPresentFeedback_OutputChange; + } + } + + + public void SetPartitionStatePresent() + { + if (!isInAutoMode) + { + partitionPresent = true; + PartitionPresentFeedback.FireUpdate(); + } + } + + public void SetPartitionStateNotPresent() + { + if (!isInAutoMode) + { + partitionPresent = false; + PartitionPresentFeedback.FireUpdate(); + } + } + + public void ToggglePartitionState() + { + if (!isInAutoMode) + { + partitionPresent = !partitionPresent; + PartitionPresentFeedback.FireUpdate(); + } + } + + #endregion + + #region IPartitionStateProvider Members + + public BoolFeedback PartitionPresentFeedback { get; private set; } + + #endregion + + #region IKeyName Members + + public string Name { get; private set; } + + #endregion + + #region IKeyed Members + + public string Key { get; private set; } + + #endregion + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 768e476b..752a7107 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Core public StringFeedback NameFeedback { get; private set; } public BoolFeedback EnableFeedback { get; private set; } - public BoolFeedback PartitionSensedFeedback { get; private set; } + public BoolFeedback PartitionPresentFeedback { get; private set; } public BoolFeedback PartitionNotSensedFeedback { get; private set; } public IntFeedback SensitivityFeedback { get; private set; } @@ -40,7 +40,7 @@ namespace PepperDash.Essentials.Core NameFeedback = new StringFeedback(() => Name); EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue); - PartitionSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue); + PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue); PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue); SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue); @@ -61,7 +61,7 @@ namespace PepperDash.Essentials.Core } case (GlsPartCn.PartitionSensedFeedbackEventId): { - PartitionSensedFeedback.FireUpdate(); + PartitionPresentFeedback.FireUpdate(); break; } case (GlsPartCn.PartitionNotSensedFeedbackEventId): @@ -186,7 +186,7 @@ namespace PepperDash.Essentials.Core // link output to simpl IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]); - PartitionSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]); + PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]); PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]); SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]); @@ -216,7 +216,7 @@ namespace PepperDash.Essentials.Core IsOnline.FireUpdate(); NameFeedback.FireUpdate(); EnableFeedback.FireUpdate(); - PartitionSensedFeedback.FireUpdate(); + PartitionPresentFeedback.FireUpdate(); PartitionNotSensedFeedback.FireUpdate(); SensitivityFeedback.FireUpdate(); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs index 08b8012b..faf84015 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs @@ -13,15 +13,24 @@ namespace PepperDash.Essentials.Core /// public interface IPartitionStateProvider : IKeyName { - BoolFeedback PartitionSensedFeedback { get; } + BoolFeedback PartitionPresentFeedback { get; } } - public interface IManualPartitionSensor : IPartitionStateProvider + /// + /// Describes the functionality of a device that can provide partition state either manually via user input or optionally via a sensor state + /// + public interface IPartitionController : IPartitionStateProvider { + List AdjacentRoomKeys { get; set; } + void SetPartitionStatePresent(); void SetPartitionStateNotPresent(); void ToggglePartitionState(); + + void SetManualMode(); + + void SetAutoMode(); } } \ 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 38a532ba..53779a0d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -233,6 +233,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index 6e9a0afb..bb3040ff 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -42,14 +42,19 @@ namespace PepperDash.Essentials.Core void CreateScenarios() { + RoomCombinationScenarios = new List(); + foreach (var scenarioConfig in _propertiesConfig.Scenarios) { var scenario = new RoomCombinationScenario(scenarioConfig); + RoomCombinationScenarios.Add(scenario); } } void SetRooms() { + _rooms = new List(); + foreach (var roomKey in _propertiesConfig.RoomKeys) { var room = DeviceManager.GetDeviceForKey(roomKey) as IEssentialsRoom; @@ -62,7 +67,36 @@ namespace PepperDash.Essentials.Core void SetupPartitionStateProviders() { + foreach (var pConfig in _propertiesConfig.Partitions) + { + var sensor = DeviceManager.GetDeviceForKey(pConfig.DeviceKey) as IPartitionStateProvider; + var partition = new EssentialsPartitionController(pConfig.Key, pConfig.Name, sensor, _propertiesConfig.defaultToManualMode, pConfig.AdjacentRoomKeys); + + partition.PartitionPresentFeedback.OutputChange += PartitionPresentFeedback_OutputChange; + + Partitions.Add(partition); + } + } + + void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e) + { + DetermineRoomCombinationScenario(); + } + + + /// + /// Determines the current room combination scenario based on the state of the partition sensors + /// + void DetermineRoomCombinationScenario() + { + //RoomCombinationScenarios.FirstOrDefault((s) => + //{ + // foreach (var partitionState in s.PartitionStates) + // { + // var partition = Partitions.FirstOrDefault( + // } + //}); } #region IEssentialsRoomCombiner Members @@ -111,11 +145,11 @@ namespace PepperDash.Essentials.Core public List RoomCombinationScenarios { get; private set; } - public List PartitionStateProviders { get; private set; } + public List Partitions { get; private set; } public void TogglePartitionState(string partitionKey) { - var partition = PartitionStateProviders.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IManualPartitionSensor; + var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionKey)) as IPartitionController; if (partition != null) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 95b97c35..7fa215d5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -84,8 +84,8 @@ namespace PepperDash.Essentials.Core [JsonProperty("partitionStates")] public List PartitionStates { get; set; } - [JsonProperty("roomMap")] - public Dictionary RoomMap { get; set; } + [JsonProperty("uiMap")] + public Dictionary UiMap { get; set; } [JsonProperty("activationActions")] public List ActivationActions { get; set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs index 142e066c..c5fa0c50 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs @@ -11,7 +11,7 @@ namespace PepperDash.Essentials.Core /// /// Describes the functionality for an EssentailsRoomCombiner device /// - public interface IEssentialsRoomCombiner + public interface IEssentialsRoomCombiner : IKeyed { /// /// Indicates that the room combination scenario has changed @@ -51,7 +51,7 @@ namespace PepperDash.Essentials.Core /// /// The partition /// - List PartitionStateProviders { get; } + List Partitions { get; } /// /// Toggles the state of a manual partition sensor @@ -77,6 +77,16 @@ namespace PepperDash.Essentials.Core /// Activates this room combination scenario /// void Activate(); + + /// + /// The state of the partitions that would activate this scenario + /// + List PartitionStates { get; } + + /// + /// The mapping of UIs by key to rooms by key + /// + Dictionary UiMap { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs index c1d75c3e..a5534edc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs @@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core public List PartitionStates { get; private set; } - public Dictionary EnabledRoomMap { get; set; } + public Dictionary UiMap { get; set; } private bool _isActive; @@ -39,7 +39,7 @@ namespace PepperDash.Essentials.Core PartitionStates = config.PartitionStates; - EnabledRoomMap = config.RoomMap; + UiMap = config.UiMap; activationActions = config.ActivationActions; From 6f6ca50c373e2e3327f7ad48f30f7b188575f454 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 16 Jul 2021 15:36:59 -0600 Subject: [PATCH 261/480] Removes set from interface --- .../PartitionSensor/IPartitionStateProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs index faf84015..adb420b7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/IPartitionStateProvider.cs @@ -21,7 +21,7 @@ namespace PepperDash.Essentials.Core /// public interface IPartitionController : IPartitionStateProvider { - List AdjacentRoomKeys { get; set; } + List AdjacentRoomKeys { get; } void SetPartitionStatePresent(); From 9795637d755a80a16ee6b0ce55029d84e88b6b9a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 16 Jul 2021 16:09:38 -0600 Subject: [PATCH 262/480] #742 EssentialsRoomCombiner substantially complete. Adds debounce timer when changing scenarios --- .../Room/Combining/EssentialsRoomCombiner.cs | 97 +++++++++++++++++-- .../EssentialsRoomCombinerPropertiesConfig.cs | 3 + 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index bb3040ff..cbbb58d1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + namespace PepperDash.Essentials.Core { public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner @@ -16,11 +18,20 @@ namespace PepperDash.Essentials.Core private bool isInAutoMode; + private CTimer _scenarioChangeDebounceTimer; + + private int _scenarioChangeDebounceTimeSeconds = 10; // default to 10s + public EssentialsRoomCombiner(string key, EssentialsRoomCombinerPropertiesConfig props) : base(key) { _propertiesConfig = props; + if (_propertiesConfig.ScenarioChangeDebounceTimeSeconds > 0) + { + _scenarioChangeDebounceTimeSeconds = _propertiesConfig.ScenarioChangeDebounceTimeSeconds; + } + IsInAutoModeFeedback = new BoolFeedback(() => isInAutoMode); // default to auto mode @@ -81,22 +92,61 @@ namespace PepperDash.Essentials.Core void PartitionPresentFeedback_OutputChange(object sender, FeedbackEventArgs e) { - DetermineRoomCombinationScenario(); + StartDebounceTimer(); } + void StartDebounceTimer() + { + var time = _scenarioChangeDebounceTimeSeconds * 1000; + + if (_scenarioChangeDebounceTimer == null) + { + _scenarioChangeDebounceTimer = new CTimer((o) => DetermineRoomCombinationScenario(), time); + } + else + { + _scenarioChangeDebounceTimer.Reset(time); + } + } /// /// Determines the current room combination scenario based on the state of the partition sensors /// void DetermineRoomCombinationScenario() { - //RoomCombinationScenarios.FirstOrDefault((s) => - //{ - // foreach (var partitionState in s.PartitionStates) - // { - // var partition = Partitions.FirstOrDefault( - // } - //}); + if (_scenarioChangeDebounceTimer != null) + { + _scenarioChangeDebounceTimer.Dispose(); + _scenarioChangeDebounceTimer = null; + } + + var currentScenario = RoomCombinationScenarios.FirstOrDefault((s) => + { + // iterate the partition states + foreach (var partitionState in s.PartitionStates) + { + // get the partition by key + var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey)); + + if (partition != null && partitionState.PartitionPresent != partition.PartitionPresentFeedback.BoolValue) + { + // the partition can't be found or the state doesn't match + return false; + } + else + { + // check the next partition state + continue; + } + } + // if it hasn't returned false by now we have the matching scenario + return true; + }); + + if (currentScenario != null) + { + CurrentScenario = currentScenario; + } } #region IEssentialsRoomCombiner Members @@ -114,6 +164,7 @@ namespace PepperDash.Essentials.Core if (value != _currentScenario) { _currentScenario = value; + Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name); var handler = RoomCombinationScenarioChanged; if (handler != null) { @@ -145,7 +196,7 @@ namespace PepperDash.Essentials.Core public List RoomCombinationScenarios { get; private set; } - public List Partitions { get; private set; } + public List Partitions { get; private set; } public void TogglePartitionState(string partitionKey) { @@ -159,7 +210,35 @@ namespace PepperDash.Essentials.Core public void SetRoomCombinationScenario(string scenarioKey) { + if (isInAutoMode) + { + Debug.Console(0, this, "Cannot set room combination scenario when in auto mode. Set to auto mode first."); + return; + } + // Get the scenario + var scenario = RoomCombinationScenarios.FirstOrDefault((s) => s.Key.Equals(scenarioKey)); + + // Set the parition states from the scenario manually + if (scenario != null) + { + foreach (var partitionState in scenario.PartitionStates) + { + var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey)); + + if (partition != null) + { + if (partitionState.PartitionPresent) + { + partition.SetPartitionStatePresent(); + } + else + { + partition.SetPartitionStateNotPresent(); + } + } + } + } } #endregion diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 7fa215d5..05295f42 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -44,6 +44,9 @@ namespace PepperDash.Essentials.Core /// [JsonProperty("defaultScenarioKey")] public string defaultScenarioKey { get; set; } + + [JsonProperty("scenarioChangeDebounceTimeSeconds")] + public int ScenarioChangeDebounceTimeSeconds { get; set; } } /// From 377cccf912e9dd963545df32e1a02afcbe0bd8af Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 16 Jul 2021 16:10:06 -0600 Subject: [PATCH 263/480] Updates type for Partitions on IEssentialsRoomController --- .../Room/Combining/IEssentialsRoomCombiner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs index c5fa0c50..c0c8101b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs @@ -51,7 +51,7 @@ namespace PepperDash.Essentials.Core /// /// The partition /// - List Partitions { get; } + List Partitions { get; } /// /// Toggles the state of a manual partition sensor From 990090e1dec396f22fc10bc23f5d30d26f1d4c2a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 10:29:30 -0600 Subject: [PATCH 264/480] feat: Add support for C2N-IO --- .../Crestron IO/C2nIo/C2nIoController.cs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nIo/C2nIoController.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nIo/C2nIoController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nIo/C2nIoController.cs new file mode 100644 index 00000000..0b70288f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/C2nIo/C2nIoController.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.GeneralIO; +using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core.CrestronIO +{ + public class C2NIoController:CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IRelayPorts + { + private C2nIo _device; + + public C2NIoController(string key, Func preActivationFunc, DeviceConfig config):base(key, config.Name) + { + AddPreActivationAction(() => + { + _device = preActivationFunc(config); + + RegisterCrestronGenericBase(_device); + }); + } + + #region Implementation of IComPorts + + public CrestronCollection ComPorts + { + get { return _device.ComPorts; } + } + + public int NumberOfComPorts + { + get { return _device.NumberOfComPorts; } + } + + #endregion + + #region Implementation of IIROutputPorts + + public CrestronCollection IROutputPorts + { + get { return _device.IROutputPorts; } + } + + public int NumberOfIROutputPorts + { + get { return _device.NumberOfIROutputPorts; } + } + + #endregion + + #region Implementation of IRelayPorts + + public CrestronCollection RelayPorts + { + get { return _device.RelayPorts; } + } + + public int NumberOfRelayPorts + { + get { return _device.NumberOfRelayPorts; } + } + + #endregion + } + + public class C2NIoControllerFactory : EssentialsDeviceFactory + { + public C2NIoControllerFactory() + { + TypeNames = new List() { "c2nio" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new C2N-IO Device"); + + return new C2NIoController(dc.Key, GetC2NIoDevice, dc); + } + + static C2nIo GetC2NIoDevice(DeviceConfig dc) + { + var control = CommFactory.GetControlPropertiesConfig(dc); + var cresnetId = control.CresnetIdInt; + var branchId = control.ControlPortNumber; + var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey; + + if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase)) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey); + return new C2nIo(cresnetId, Global.ControlSystem); + } + var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches; + + if (cresnetBridge != null) + { + Debug.Console(0, "Device {0} is a valid cresnet master - creating new C2nIo", parentKey); + return new C2nIo(cresnetId, cresnetBridge.CresnetBranches[branchId]); + } + Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey); + return null; + } + } +} \ No newline at end of file From 6946946c12e3b23710b85996fd267b54c7171481 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 13:47:17 -0600 Subject: [PATCH 265/480] chore: Add c2nIoController to csproj --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 6e48fd66..3919d331 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -162,6 +162,7 @@ + From 760ec8be924285a39398fef908bd8b681b7495bb Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 14:08:23 -0600 Subject: [PATCH 266/480] feat: Add occupancy aggregator factory and config --- .../IOccupancyStatusProviderAggregator.cs | 44 ++++++++++++++++--- .../Occupancy/OccupancyAggregatorConfig.cs | 15 +++++++ .../PepperDash_Essentials_Core.csproj | 1 + 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs index c321dcad..601edf67 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs @@ -2,17 +2,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Crestron.SimplSharp; - +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.GeneralIO; using PepperDash.Core; using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.Core { /// /// Aggregates the RoomIsOccupied feedbacks of one or more IOccupancyStatusProvider objects /// - public class IOccupancyStatusProviderAggregator : Device, IOccupancyStatusProvider + public class IOccupancyStatusProviderAggregator : EssentialsDevice, IOccupancyStatusProvider { /// /// Aggregated feedback of all linked IOccupancyStatusProvider devices @@ -21,16 +22,22 @@ namespace PepperDash.Essentials.Core { get { - return AggregatedOccupancyStatus.Output; + return _aggregatedOccupancyStatus.Output; } } - private BoolFeedbackOr AggregatedOccupancyStatus; + private readonly BoolFeedbackOr _aggregatedOccupancyStatus; public IOccupancyStatusProviderAggregator(string key, string name) : base(key, name) { - AggregatedOccupancyStatus = new BoolFeedbackOr(); + _aggregatedOccupancyStatus = new BoolFeedbackOr(); + } + + public IOccupancyStatusProviderAggregator(string key, string name, OccupancyAggregatorConfig config) + : this(dc.Key, dc.Name) + { + } /// @@ -39,7 +46,30 @@ namespace PepperDash.Essentials.Core /// public void AddOccupancyStatusProvider(IOccupancyStatusProvider statusProvider) { - AggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback); + _aggregatedOccupancyStatus.AddOutputIn(statusProvider.RoomIsOccupiedFeedback); + } + + public void RemoveOccupancyStatusProvider(IOccupancyStatusProvider statusProvider) + { + _aggregatedOccupancyStatus.RemoveOutputIn(statusProvider.RoomIsOccupiedFeedback); } + } + + public class OccupancyAggregatorFactory : EssentialsDeviceFactory + { + public OccupancyAggregatorFactory() + { + TypeNames = new List { "glsodtccn" }; + } + + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device"); + + var config = dc.Properties.ToObject(); + + return new IOccupancyStatusProviderAggregator(dc.Key, dc.Name, config); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs new file mode 100644 index 00000000..7909de04 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Core +{ + public class OccupancyAggregatorConfig + { + [JsonProperty("deviceKeys")] public List DeviceKeys { get; set; } + + OccupancyAggregatorConfig() + { + DeviceKeys = new List(); + } + } +} \ 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 3919d331..36992629 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -234,6 +234,7 @@ + From 9128e108f78eb671756228108e2b67fb3449744d Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 15:09:03 -0600 Subject: [PATCH 267/480] feat: Add clear method to BoolOutputLogical and do a bit of refactoring --- .../Feedbacks/BoolOutputLogicals.cs | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolOutputLogicals.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolOutputLogicals.cs index 3074254e..a8dae7b8 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolOutputLogicals.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolOutputLogicals.cs @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core protected bool ComputedValue; - public BoolFeedbackLogic() + protected BoolFeedbackLogic() { Output = new BoolFeedback(() => ComputedValue); } @@ -40,21 +40,18 @@ namespace PepperDash.Essentials.Core public void AddOutputsIn(List outputs) { - foreach (var o in outputs) - { - // skip existing - if (OutputsIn.Contains(o)) continue; - - OutputsIn.Add(o); - o.OutputChange += AnyInput_OutputChange; - } - Evaluate(); + foreach (var o in outputs.Where(o => !OutputsIn.Contains(o))) + { + OutputsIn.Add(o); + o.OutputChange += AnyInput_OutputChange; + } + Evaluate(); } - public void RemoveOutputIn(BoolFeedback output) + public void RemoveOutputIn(BoolFeedback output) { // Don't double up outputs - if (OutputsIn.Contains(output)) return; + if (!OutputsIn.Contains(output)) return; OutputsIn.Remove(output); output.OutputChange -= AnyInput_OutputChange; @@ -71,6 +68,12 @@ namespace PepperDash.Essentials.Core Evaluate(); } + public void ClearOutputs() + { + OutputsIn.Clear(); + Evaluate(); + } + void AnyInput_OutputChange(object sender, EventArgs e) { Evaluate(); @@ -85,11 +88,12 @@ namespace PepperDash.Essentials.Core { var prevValue = ComputedValue; var newValue = OutputsIn.All(o => o.BoolValue); - if (newValue != prevValue) - { - ComputedValue = newValue; - Output.FireUpdate(); - } + if (newValue == prevValue) + { + return; + } + ComputedValue = newValue; + Output.FireUpdate(); } } @@ -99,33 +103,35 @@ namespace PepperDash.Essentials.Core { var prevValue = ComputedValue; var newValue = OutputsIn.Any(o => o.BoolValue); - if (newValue != prevValue) - { - ComputedValue = newValue; - Output.FireUpdate(); - } + if (newValue == prevValue) + { + return; + } + ComputedValue = newValue; + Output.FireUpdate(); } } public class BoolFeedbackLinq : BoolFeedbackLogic { - Func, bool> Predicate; + readonly Func, bool> _predicate; public BoolFeedbackLinq(Func, bool> predicate) : base() { - Predicate = predicate; + _predicate = predicate; } protected override void Evaluate() { var prevValue = ComputedValue; - var newValue = Predicate(OutputsIn); - if (newValue != prevValue) - { - ComputedValue = newValue; - Output.FireUpdate(); - } + var newValue = _predicate(OutputsIn); + if (newValue == prevValue) + { + return; + } + ComputedValue = newValue; + Output.FireUpdate(); } } } \ No newline at end of file From 10129b81782513de98f5cd8ab271c01affc4b25c Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 15:09:37 -0600 Subject: [PATCH 268/480] feat: Add post activation action for aggregator --- .../IOccupancyStatusProviderAggregator.cs | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs index 601edf67..3da9c0dc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/IOccupancyStatusProviderAggregator.cs @@ -35,9 +35,38 @@ namespace PepperDash.Essentials.Core } public IOccupancyStatusProviderAggregator(string key, string name, OccupancyAggregatorConfig config) - : this(dc.Key, dc.Name) + : this(key, name) { - + AddPostActivationAction(() => + { + if (config.DeviceKeys.Count == 0) + { + return; + } + + foreach (var deviceKey in config.DeviceKeys) + { + var device = DeviceManager.GetDeviceForKey(deviceKey); + + if (device == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, + "Unable to retrieve Occupancy provider with key {0}", deviceKey); + continue; + } + + var provider = device as IOccupancyStatusProvider; + + if (provider == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, + "Device with key {0} does NOT implement IOccupancyStatusProvider. Please check configuration."); + continue; + } + + AddOccupancyStatusProvider(provider); + } + }); } /// @@ -52,6 +81,11 @@ namespace PepperDash.Essentials.Core public void RemoveOccupancyStatusProvider(IOccupancyStatusProvider statusProvider) { _aggregatedOccupancyStatus.RemoveOutputIn(statusProvider.RoomIsOccupiedFeedback); + } + + public void ClearOccupancyStatusProviders() + { + _aggregatedOccupancyStatus.ClearOutputs(); } } @@ -59,7 +93,7 @@ namespace PepperDash.Essentials.Core { public OccupancyAggregatorFactory() { - TypeNames = new List { "glsodtccn" }; + TypeNames = new List { "occupancyAggregator", "occAggregate" }; } From 45e6dff26d71e1b560845d3ba58e62b631bd52ee Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 19 Jul 2021 15:10:03 -0600 Subject: [PATCH 269/480] fix: update access level for config constructor --- .../Occupancy/OccupancyAggregatorConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs index 7909de04..ef237e72 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/OccupancyAggregatorConfig.cs @@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Core { [JsonProperty("deviceKeys")] public List DeviceKeys { get; set; } - OccupancyAggregatorConfig() + public OccupancyAggregatorConfig() { DeviceKeys = new List(); } From dfaaa3f6bc68b89b6e7711b68ca8149b74546123 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 19 Jul 2021 15:41:10 -0600 Subject: [PATCH 270/480] #742 Adds factory for EssentialsRoomCombiner --- .../PepperDashEssentials.csproj | 3 +- .../Room/Types/IEssentialsHuddleSpaceRoom.cs | 48 -- .../Interfaces/IEssentialsHuddleSpaceRoom.cs | 24 + .../Interfaces/IEssentialsHuddleVtc1Room.cs | 25 + .../EssentialsHuddleTechPageDriver.cs | 648 +++++++++--------- .../GlsPartitionSensorController.cs | 2 +- .../Room/Combining/EssentialsRoomCombiner.cs | 24 +- 7 files changed, 398 insertions(+), 376 deletions(-) delete mode 100644 PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs create mode 100644 PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs create mode 100644 PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 14bd450a..d172076a 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -149,7 +149,8 @@ - + + diff --git a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs deleted file mode 100644 index efc126f6..00000000 --- a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Room.Config; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Devices.Common.Codec; -using PepperDash.Essentials.Devices.Common.VideoCodec; -using PepperDash.Essentials.Devices.Common.AudioCodec; - - -using PepperDash.Core; - -namespace PepperDash.Essentials -{ - public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay - { - bool ExcludeFromGlobalFunctions { get; } - - void RunRouteAction(string routeKey); - - EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; } - - IBasicVolumeControls CurrentVolumeControls { get; } - - event EventHandler CurrentVolumeDeviceChange; - } - - public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, - IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback - { - EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } - - void RunRouteAction(string routeKey); - - IHasScheduleAwareness ScheduleSource { get; } - - BoolFeedback InCallFeedback { get; } - - BoolFeedback PrivacyModeIsOnFeedback { get; } - - string DefaultCodecRouteString { get; } - } -} \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs new file mode 100644 index 00000000..c7f68e8b --- /dev/null +++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs @@ -0,0 +1,24 @@ +using System; + +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Room.Config; + + + +namespace PepperDash.Essentials +{ + public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay + { + bool ExcludeFromGlobalFunctions { get; } + + void RunRouteAction(string routeKey); + + EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; } + + IBasicVolumeControls CurrentVolumeControls { get; } + + event EventHandler CurrentVolumeDeviceChange; + } + + +} \ No newline at end of file diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs new file mode 100644 index 00000000..662988a1 --- /dev/null +++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs @@ -0,0 +1,25 @@ + +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Room.Config; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.AudioCodec; + +namespace PepperDash.Essentials +{ + public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, + IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback + { + EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } + + void RunRouteAction(string routeKey); + + IHasScheduleAwareness ScheduleSource { get; } + + BoolFeedback InCallFeedback { get; } + + BoolFeedback PrivacyModeIsOnFeedback { get; } + + string DefaultCodecRouteString { get; } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs index b8e1dfd6..776e1034 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs @@ -1,326 +1,326 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; + +using PepperDash.Core; +using PepperDash.Essentials; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.SmartObjects; -using PepperDash.Essentials.Core.Touchpanels.Keyboards; -using PepperDash.Essentials.Devices.Displays; -using PepperDash.Essentials.Room.Config; - -namespace PepperDash.Essentials.UIDrivers -{ - public class EssentialsHuddleTechPageDriver : PanelDriverBase - { - /// - /// - /// - SmartObjectDynamicList MenuList; - /// - /// - /// - SubpageReferenceList StatusList; - /// - /// The list of display controls - /// - SubpageReferenceList DisplayList; - /// - /// References lines in the list against device instances - /// - Dictionary StatusListDeviceIndexes; - /// - /// - /// - JoinedSigInterlock PagesInterlock; - - /// - /// 1 - /// - public const uint JoinText = 1; - - CTimer PinAuthorizedTimer; - - EssentialsRoomTechConfig Config; - - StringBuilder PinEntryBuilder = new StringBuilder(4); - - bool IsAuthorized; - - SmartObjectNumeric PinKeypad; - - /// - /// - /// - /// - /// - public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config) - : base(trilist) - { - Config = config; - - PagesInterlock = new JoinedSigInterlock(trilist); - PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible); - - trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide); - - MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList], - true, 3100); - - MenuList.SetFeedback(1, true); // initial fb - ushort count = 0; - - MenuList.SetItemMainText(1, "System Status"); - MenuList.SetItemButtonAction(1, b => { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible); - MenuList.SetFeedback(1, true); - }); - - MenuList.SetItemMainText(2, "Display Controls"); - MenuList.SetItemButtonAction(2, b => { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible); - MenuList.SetFeedback(2, true); - }); - - count = 2; - - // Don't show panel setup on iPad or xpanel - if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button) - { - count++; - MenuList.SetItemMainText(count, "Panel Setup"); - MenuList.SetItemButtonAction(count, b => - { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible); - MenuList.SetFeedback(count, true); - }); - } - - MenuList.Count = count; - BuildStatusList(); - BuildDisplayList(); - SetupPinModal(); - } - - /// - /// - /// - public override void Show() - { - // divert to PIN if we need auth - if (IsAuthorized) - { - // Cancel the auth timer so we don't deauth after coming back in - if (PinAuthorizedTimer != null) - PinAuthorizedTimer.Stop(); - - TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true); - PagesInterlock.Show(); - base.Show(); - } - else - { - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true); - } - } - - /// - /// - /// - public override void Hide() - { - // Leave it authorized for 60 seconds. - if (IsAuthorized) - PinAuthorizedTimer = new CTimer(o => { - IsAuthorized = false; - PinAuthorizedTimer = null; - }, 60000); - TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false); - PagesInterlock.Hide(); - base.Hide(); - } - - /// - /// Wire up the keypad and buttons - /// - void SetupPinModal() - { - TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog); - PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true); - PinKeypad.Digit0.UserObject = new Action(b => { if (b)DialPinDigit('0'); }); - PinKeypad.Digit1.UserObject = new Action(b => { if (b)DialPinDigit('1'); }); - PinKeypad.Digit2.UserObject = new Action(b => { if (b)DialPinDigit('2'); }); - PinKeypad.Digit3.UserObject = new Action(b => { if (b)DialPinDigit('3'); }); - PinKeypad.Digit4.UserObject = new Action(b => { if (b)DialPinDigit('4'); }); - PinKeypad.Digit5.UserObject = new Action(b => { if (b)DialPinDigit('5'); }); - PinKeypad.Digit6.UserObject = new Action(b => { if (b)DialPinDigit('6'); }); - PinKeypad.Digit7.UserObject = new Action(b => { if (b)DialPinDigit('7'); }); - PinKeypad.Digit8.UserObject = new Action(b => { if (b)DialPinDigit('8'); }); - PinKeypad.Digit9.UserObject = new Action(b => { if (b)DialPinDigit('9'); }); - } - - /// - /// - /// - /// - void DialPinDigit(char d) - { - PinEntryBuilder.Append(d); - var len = PinEntryBuilder.Length; - SetPinDotsFeedback(len); - - // check it! - if (len == 4) - { - if (Config.Password == PinEntryBuilder.ToString()) - { - IsAuthorized = true; - SetPinDotsFeedback(0); - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); - Show(); - } - else - { - SetPinDotsFeedback(0); - TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true); - new CTimer(o => - { - TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false); - }, 1500); - } - - PinEntryBuilder.Remove(0, len); // clear it either way - } - } - - /// - /// Draws the dots as pin is entered - /// - /// - void SetPinDotsFeedback(int len) - { - TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1); - TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2); - TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3); - TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4); - - } - - /// - /// Does what it says - /// - void CancelPinDialog() - { - PinEntryBuilder.Remove(0, PinEntryBuilder.Length); - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); - } - - - /// - /// - /// - void BuildStatusList() - { - StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3); - StatusListDeviceIndexes = new Dictionary(); - uint i = 0; - foreach (var d in DeviceManager.AllDevices) - { - // make sure it is both ICommunicationMonitor and a Device - var sd = d as ICommunicationMonitor; - if (sd == null) - continue; - var dd = sd as Device; - if(dd == null) - continue; - i++; - StatusList.StringInputSig(i, 1).StringValue = dd.Name; - StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status; - StatusListDeviceIndexes.Add(sd, i); - sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ; - } - StatusList.Count = (ushort)i; - } - - /// - /// Builds the list of display controls - /// - void BuildDisplayList() - { - DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3); - - var devKeys = ConfigReader.ConfigObject.Devices.Where(d => - d.Group.Equals("display", StringComparison.OrdinalIgnoreCase) - || d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase)) - .Select(dd => dd.Key); - var disps = DeviceManager.AllDevices.Where(d => - devKeys.Contains(d.Key)); - ushort i = 0; - foreach (var disp in disps) - { - var display = disp as DisplayBase; - if (display != null) - { - i++; - DisplayList.StringInputSig(i, 1).StringValue = display.Name; - DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn); - DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff); - if (display is TwoWayDisplayBase) - { - var powerOnSig = DisplayList.BoolInputSig(i, 1); - (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig); - - var powerOffSig = DisplayList.BoolInputSig(1, 2); - (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig); - } - DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() => - { if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); }); - DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() => - { if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); }); - DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() => - { if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); }); - //DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => - //{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); }); - DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => - { if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); }); - - - // Figure out some way to provide current input feedback - if (display is TwoWayDisplayBase) - { - (display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange; - } - } - - - } - - DisplayList.Count = i; - } - - - void CurrentInputFeedback_OutputChange(object sender, EventArgs e) - { - - } - - /// - /// - /// - void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e) - { - var c = sender as ICommunicationMonitor; - if (StatusListDeviceIndexes.ContainsKey(c)) - { - var i = StatusListDeviceIndexes[c]; - StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status; - } - } - } +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.SmartObjects; +using PepperDash.Essentials.Core.Touchpanels.Keyboards; +using PepperDash.Essentials.Devices.Displays; +using PepperDash.Essentials.Room.Config; + +namespace PepperDash.Essentials.UIDrivers +{ + public class EssentialsHuddleTechPageDriver : PanelDriverBase + { + /// + /// + /// + SmartObjectDynamicList MenuList; + /// + /// + /// + SubpageReferenceList StatusList; + /// + /// The list of display controls + /// + SubpageReferenceList DisplayList; + /// + /// References lines in the list against device instances + /// + Dictionary StatusListDeviceIndexes; + /// + /// + /// + JoinedSigInterlock PagesInterlock; + + /// + /// 1 + /// + public const uint JoinText = 1; + + CTimer PinAuthorizedTimer; + + EssentialsRoomTechConfig Config; + + StringBuilder PinEntryBuilder = new StringBuilder(4); + + bool IsAuthorized; + + SmartObjectNumeric PinKeypad; + + /// + /// + /// + /// + /// + public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config) + : base(trilist) + { + Config = config; + + PagesInterlock = new JoinedSigInterlock(trilist); + PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible); + + trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide); + + MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList], + true, 3100); + + MenuList.SetFeedback(1, true); // initial fb + ushort count = 0; + + MenuList.SetItemMainText(1, "System Status"); + MenuList.SetItemButtonAction(1, b => { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible); + MenuList.SetFeedback(1, true); + }); + + MenuList.SetItemMainText(2, "Display Controls"); + MenuList.SetItemButtonAction(2, b => { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible); + MenuList.SetFeedback(2, true); + }); + + count = 2; + + // Don't show panel setup on iPad or xpanel + if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button) + { + count++; + MenuList.SetItemMainText(count, "Panel Setup"); + MenuList.SetItemButtonAction(count, b => + { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible); + MenuList.SetFeedback(count, true); + }); + } + + MenuList.Count = count; + BuildStatusList(); + BuildDisplayList(); + SetupPinModal(); + } + + /// + /// + /// + public override void Show() + { + // divert to PIN if we need auth + if (IsAuthorized) + { + // Cancel the auth timer so we don't deauth after coming back in + if (PinAuthorizedTimer != null) + PinAuthorizedTimer.Stop(); + + TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true); + PagesInterlock.Show(); + base.Show(); + } + else + { + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true); + } + } + + /// + /// + /// + public override void Hide() + { + // Leave it authorized for 60 seconds. + if (IsAuthorized) + PinAuthorizedTimer = new CTimer(o => { + IsAuthorized = false; + PinAuthorizedTimer = null; + }, 60000); + TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false); + PagesInterlock.Hide(); + base.Hide(); + } + + /// + /// Wire up the keypad and buttons + /// + void SetupPinModal() + { + TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog); + PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true); + PinKeypad.Digit0.UserObject = new Action(b => { if (b)DialPinDigit('0'); }); + PinKeypad.Digit1.UserObject = new Action(b => { if (b)DialPinDigit('1'); }); + PinKeypad.Digit2.UserObject = new Action(b => { if (b)DialPinDigit('2'); }); + PinKeypad.Digit3.UserObject = new Action(b => { if (b)DialPinDigit('3'); }); + PinKeypad.Digit4.UserObject = new Action(b => { if (b)DialPinDigit('4'); }); + PinKeypad.Digit5.UserObject = new Action(b => { if (b)DialPinDigit('5'); }); + PinKeypad.Digit6.UserObject = new Action(b => { if (b)DialPinDigit('6'); }); + PinKeypad.Digit7.UserObject = new Action(b => { if (b)DialPinDigit('7'); }); + PinKeypad.Digit8.UserObject = new Action(b => { if (b)DialPinDigit('8'); }); + PinKeypad.Digit9.UserObject = new Action(b => { if (b)DialPinDigit('9'); }); + } + + /// + /// + /// + /// + void DialPinDigit(char d) + { + PinEntryBuilder.Append(d); + var len = PinEntryBuilder.Length; + SetPinDotsFeedback(len); + + // check it! + if (len == 4) + { + if (Config.Password == PinEntryBuilder.ToString()) + { + IsAuthorized = true; + SetPinDotsFeedback(0); + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); + Show(); + } + else + { + SetPinDotsFeedback(0); + TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true); + new CTimer(o => + { + TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false); + }, 1500); + } + + PinEntryBuilder.Remove(0, len); // clear it either way + } + } + + /// + /// Draws the dots as pin is entered + /// + /// + void SetPinDotsFeedback(int len) + { + TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1); + TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2); + TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3); + TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4); + + } + + /// + /// Does what it says + /// + void CancelPinDialog() + { + PinEntryBuilder.Remove(0, PinEntryBuilder.Length); + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); + } + + + /// + /// + /// + void BuildStatusList() + { + StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3); + StatusListDeviceIndexes = new Dictionary(); + uint i = 0; + foreach (var d in DeviceManager.AllDevices) + { + // make sure it is both ICommunicationMonitor and a Device + var sd = d as ICommunicationMonitor; + if (sd == null) + continue; + var dd = sd as Device; + if(dd == null) + continue; + i++; + StatusList.StringInputSig(i, 1).StringValue = dd.Name; + StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status; + StatusListDeviceIndexes.Add(sd, i); + sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ; + } + StatusList.Count = (ushort)i; + } + + /// + /// Builds the list of display controls + /// + void BuildDisplayList() + { + DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3); + + var devKeys = ConfigReader.ConfigObject.Devices.Where(d => + d.Group.Equals("display", StringComparison.OrdinalIgnoreCase) + || d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase)) + .Select(dd => dd.Key); + var disps = DeviceManager.AllDevices.Where(d => + devKeys.Contains(d.Key)); + ushort i = 0; + foreach (var disp in disps) + { + var display = disp as DisplayBase; + if (display != null) + { + i++; + DisplayList.StringInputSig(i, 1).StringValue = display.Name; + DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn); + DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff); + if (display is TwoWayDisplayBase) + { + var powerOnSig = DisplayList.BoolInputSig(i, 1); + (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig); + + var powerOffSig = DisplayList.BoolInputSig(1, 2); + (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig); + } + DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() => + { if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); }); + DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() => + { if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); }); + DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() => + { if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); }); + //DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => + //{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); }); + DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => + { if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); }); + + + // Figure out some way to provide current input feedback + if (display is TwoWayDisplayBase) + { + (display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange; + } + } + + + } + + DisplayList.Count = i; + } + + + void CurrentInputFeedback_OutputChange(object sender, EventArgs e) + { + + } + + /// + /// + /// + void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e) + { + var c = sender as ICommunicationMonitor; + if (StatusListDeviceIndexes.ContainsKey(c)) + { + var i = StatusListDeviceIndexes[c]; + StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status; + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 752a7107..114909c4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -257,7 +257,7 @@ namespace PepperDash.Essentials.Core public override EssentialsDevice BuildDevice(DeviceConfig dc) { - Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device"); + Debug.Console(1, "Factory Attempting to create new GlsPartitionSensorController Device"); return new GlsPartitionSensorController(dc.Key, GetGlsPartCnDevice, dc); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index cbbb58d1..b68a4c04 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -46,9 +46,12 @@ namespace PepperDash.Essentials.Core CreateScenarios(); - SetupPartitionStateProviders(); + AddPostActivationAction(() => + { + SetupPartitionStateProviders(); - SetRooms(); + SetRooms(); + }); } void CreateScenarios() @@ -243,4 +246,21 @@ namespace PepperDash.Essentials.Core #endregion } + + public class EssentialsRoomCombinerFactory : EssentialsDeviceFactory + { + public EssentialsRoomCombinerFactory() + { + TypeNames = new List { "essentialsroomcombiner" }; + } + + public override EssentialsDevice BuildDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new EssentialsRoomCombiner Device"); + + var props = dc.Properties.ToObject(); + + return new EssentialsRoomCombiner(dc.Key, props); + } + } } \ No newline at end of file From 5a4f7b6a2864e650ba343a7f7d71dc0d9bf935a4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 19 Jul 2021 15:44:28 -0600 Subject: [PATCH 271/480] Adds new keyword to intentionally hide properties --- .../Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs index 662988a1..5a6e9f59 100644 --- a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs @@ -16,9 +16,9 @@ namespace PepperDash.Essentials IHasScheduleAwareness ScheduleSource { get; } - BoolFeedback InCallFeedback { get; } + new BoolFeedback InCallFeedback { get; } - BoolFeedback PrivacyModeIsOnFeedback { get; } + new BoolFeedback PrivacyModeIsOnFeedback { get; } string DefaultCodecRouteString { get; } } From 94c0e92f6bc912c172e79b5430d4f0347cb36b78 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 08:28:25 -0600 Subject: [PATCH 272/480] fix: Initialize lists for partitions and scenarios also removed unnecessary else --- .../Room/Combining/EssentialsRoomCombiner.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index b68a4c04..6d80913f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -27,6 +27,9 @@ namespace PepperDash.Essentials.Core { _propertiesConfig = props; + Partitions = new List(); + RoomCombinationScenarios = new List(); + if (_propertiesConfig.ScenarioChangeDebounceTimeSeconds > 0) { _scenarioChangeDebounceTimeSeconds = _propertiesConfig.ScenarioChangeDebounceTimeSeconds; @@ -136,11 +139,6 @@ namespace PepperDash.Essentials.Core // the partition can't be found or the state doesn't match return false; } - else - { - // check the next partition state - continue; - } } // if it hasn't returned false by now we have the matching scenario return true; From 5f6b650dba081b5eb0bfd860bb0402d1e09a99c7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 11:15:37 -0600 Subject: [PATCH 273/480] fix: Update fusion IP-ID for multiple rooms --- PepperDashEssentials/ControlSystem.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 033d82fe..8c3399ae 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -450,14 +450,13 @@ namespace PepperDash.Essentials return; } + uint fusionIpId = 0xf1; + foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) { var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom; if (room != null) { - // default IPID - uint fusionIpId = 0xf1; - // default to no join map key string fusionJoinMapKey = string.Empty; @@ -515,9 +514,13 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); } + fusionIpId += 1; } else + { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key); + + } } Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded."); From db5aa319ec35d48a5bf8300a0117a372ce454c52 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 20 Jul 2021 16:49:03 -0600 Subject: [PATCH 274/480] Adds a prompt to capture affected version --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index c969d2a1..a1757593 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,6 +7,9 @@ assignees: '' --- +**Was this bug identified in a specific build version?** +Please note the build version where this bug was identified + **Describe the bug** A clear and concise description of what the bug is. From c8b0c7dd01277ed0df238ba3ffd4239216d1eaca Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 20 Jul 2021 17:12:42 -0600 Subject: [PATCH 275/480] #753 Adds new type and starts updating as needed --- .../PepperDashEssentials.csproj | 1 + .../Types/EssentialsCombinedHuddleVtc1Room.cs | 813 ++++++++++++++++++ .../Room/Combining/EssentialsRoomCombiner.cs | 2 - .../EssentialsRoomCombinerPropertiesConfig.cs | 3 + 4 files changed, 817 insertions(+), 2 deletions(-) create mode 100644 PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index d172076a..e4a0cff6 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -144,6 +144,7 @@ + diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs new file mode 100644 index 00000000..1be38cb0 --- /dev/null +++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs @@ -0,0 +1,813 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using Newtonsoft.Json; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Room.Config; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.AudioCodec; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; + +namespace PepperDash.Essentials +{ + public class EssentialsCombinedHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room + { + private bool _codecExternalSourceChange; + public event EventHandler CurrentVolumeDeviceChange; + public event SourceInfoChangeHandler CurrentSourceChange; + + + //************************ + // Call-related stuff + + public BoolFeedback InCallFeedback { get; private set; } + + ///// + ///// Make this more specific + ///// + //public List ActiveCalls { get; private set; } + + /// + /// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis + /// + public IntFeedback CallTypeFeedback { get; private set; } + + /// + /// + /// + public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } + + /// + /// When something in the room is sharing with the far end or through other means + /// + public BoolFeedback IsSharingFeedback { get; private set; } + + //************************ + + protected override Func OnFeedbackFunc + { + get + { + return () => + { + var disp = DefaultDisplay as DisplayBase; + var val = CurrentSourceInfo != null + && CurrentSourceInfo.Type == eSourceListItemType.Route + && disp != null; + //&& disp.PowerIsOnFeedback.BoolValue; + return val; + }; + } + } + /// + /// + /// + protected override Func IsWarmingFeedbackFunc + { + get + { + return () => + { + var disp = DefaultDisplay as DisplayBase; + if (disp != null) + return disp.IsWarmingUpFeedback.BoolValue; + else + return false; + }; + } + } + /// + /// + /// + protected override Func IsCoolingFeedbackFunc + { + get + { + return () => + { + var disp = DefaultDisplay as DisplayBase; + if (disp != null) + return disp.IsCoolingDownFeedback.BoolValue; + else + return false; + }; + } + } + + public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; } + + private List Displays; + + public IRoutingSinkWithSwitching DefaultDisplay { get; private set; } + + public IBasicVolumeControls DefaultAudioDevice { get; private set; } + public IBasicVolumeControls DefaultVolumeControls { get; private set; } + + public VideoCodecBase VideoCodec { get; private set; } + + public AudioCodecBase AudioCodec { get; private set; } + + public bool ExcludeFromGlobalFunctions { get; set; } + + public string DefaultSourceItem { get; set; } + + public ushort DefaultVolume { get; set; } + + /// + /// If room is off, enables power on to last source. Default true + /// + public bool EnablePowerOnToLastSource { get; set; } + string LastSourceKey; + + /// + /// Sets the volume control device, and attaches/removes InUseTrackers with "audio" + /// tag to device. + /// + public IBasicVolumeControls CurrentVolumeControls + { + get { return _CurrentAudioDevice; } + set + { + if (value == _CurrentAudioDevice) return; + + var oldDev = _CurrentAudioDevice; + // derigister this room from the device, if it can + if (oldDev is IInUseTracking) + (oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio"); + var handler = CurrentVolumeDeviceChange; + if (handler != null) + CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange)); + _CurrentAudioDevice = value; + if (handler != null) + CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange)); + // register this room with new device, if it can + if (_CurrentAudioDevice is IInUseTracking) + (_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio"); + } + } + IBasicVolumeControls _CurrentAudioDevice; + + /// + /// The SourceListItem last run - containing names and icons + /// + public SourceListItem CurrentSourceInfo + { + get { return _CurrentSourceInfo; } + set + { + if (value == _CurrentSourceInfo) return; + + var handler = CurrentSourceChange; + // remove from in-use tracker, if so equipped + if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) + (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control"); + + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.WillChange); + + _CurrentSourceInfo = value; + + // add to in-use tracking + if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking) + (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control"); + if (handler != null) + handler(_CurrentSourceInfo, ChangeType.DidChange); + + var vc = VideoCodec as IHasExternalSourceSwitching; + if (vc != null && !_codecExternalSourceChange) + { + vc.SetSelectedSource(CurrentSourceInfoKey); + } + + _codecExternalSourceChange = false; + } + } + SourceListItem _CurrentSourceInfo; + + public string CurrentSourceInfoKey { get; set; } + + /// + /// "codecOsd" + /// + public string DefaultCodecRouteString { get { return "codecOsd"; } } + + /// + /// Temporary implementation. Returns the schedule-ready object or null if none. Fow now, + /// always returns the VideoCodec if it is capable + /// + public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } } + + CCriticalSection SourceSelectLock = new CCriticalSection(); + + public EssentialsCombinedHuddleVtc1Room(DeviceConfig config) + : base(config) + { + try + { + PropertiesConfig = JsonConvert.DeserializeObject + (config.Properties.ToString()); + DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching; + + VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as + PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase; + + + if (VideoCodec == null) + throw new ArgumentNullException("codec cannot be null"); + + AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as + PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase; + if (AudioCodec == null) + Debug.Console(0, this, "No Audio Codec Found"); + + DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; + + Initialize(); + } + catch (Exception e) + { + Debug.Console(1, this, "Error building room: \n{0}", e); + } + } + + void Initialize() + { + try + { + if (DefaultAudioDevice is IBasicVolumeControls) + DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls; + else if (DefaultAudioDevice is IHasVolumeDevice) + DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice; + CurrentVolumeControls = DefaultVolumeControls; + + + // Combines call feedback from both codecs if available + InCallFeedback = new BoolFeedback(() => + { + bool inAudioCall = false; + bool inVideoCall = false; + + if (AudioCodec != null) + inAudioCall = AudioCodec.IsInCall; + + if (VideoCodec != null) + inVideoCall = VideoCodec.IsInCall; + + if (inAudioCall || inVideoCall) + return true; + else + return false; + }); + + var disp = DefaultDisplay as DisplayBase; + if (disp != null) + { + // Link power, warming, cooling to display + var dispTwoWay = disp as IHasPowerControlWithFeedback; + if (dispTwoWay != null) + { + dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) => + { + if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) + { + if (!dispTwoWay.PowerIsOnFeedback.BoolValue) + CurrentSourceInfo = null; + OnFeedback.FireUpdate(); + } + if (dispTwoWay.PowerIsOnFeedback.BoolValue) + { + SetDefaultLevels(); + } + }; + } + + disp.IsWarmingUpFeedback.OutputChange += (o, a) => + { + IsWarmingUpFeedback.FireUpdate(); + if (!IsWarmingUpFeedback.BoolValue) + (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume); + }; + disp.IsCoolingDownFeedback.OutputChange += (o, a) => + { + IsCoolingDownFeedback.FireUpdate(); + }; + + } + + + + // Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback + this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this); + + Debug.Console(2, this, "Microphone Privacy Config evaluated."); + + // Get emergency object, if any + this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this); + + Debug.Console(2, this, "Emergency Config evaluated."); + + + VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate(); + VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); }; + + if (AudioCodec != null) + AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate(); + + IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue); + VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate(); + + // link privacy to VC (for now?) + PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue); + VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate(); + + CallTypeFeedback = new IntFeedback(() => 0); + + SetSourceListKey(); + + EnablePowerOnToLastSource = true; + } + catch (Exception e) + { + Debug.Console(0, this, "Error Initializing Room: {0}", e); + } + } + + private void SetSourceListKey() + { + if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) + { + SetSourceListKey(PropertiesConfig.SourceListKey); + } + else + { + SetSourceListKey(Key); + } + + SetCodecExternalSources(); + } + + protected override void CustomSetConfig(DeviceConfig config) + { + var newPropertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString()); + + if (newPropertiesConfig != null) + PropertiesConfig = newPropertiesConfig; + + ConfigWriter.UpdateRoomConfig(config); + } + + public override bool CustomActivate() + { + // Add Occupancy object from config + if (PropertiesConfig.Occupancy != null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room"); + this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as + IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes); + } + + this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight(); + this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark(); + + this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem; + this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100); + + return base.CustomActivate(); + } + + /// + /// + /// + protected override void EndShutdown() + { + VideoCodec.EndAllCalls(); + + SetDefaultLevels(); + + RunDefaultPresentRoute(); + + CrestronEnvironment.Sleep(1000); + + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room"); + + RunRouteAction("roomOff"); + VideoCodec.StopSharing(); + VideoCodec.StandbyActivate(); + } + + /// + /// Routes the default source item, if any. Returns true when default route exists + /// + public override bool RunDefaultPresentRoute() + { + if (DefaultSourceItem != null) + RunRouteAction(DefaultSourceItem); + + return DefaultSourceItem != null; + } + + /// + /// Sets up the room when started into call mode without presenting a source + /// + /// + public bool RunDefaultCallRoute() + { + RunRouteAction(DefaultCodecRouteString); + return true; + } + + public void RunRouteActionCodec(string routeKey, string sourceListKey) + { + _codecExternalSourceChange = true; + RunRouteAction(routeKey, sourceListKey); + } + + /// + /// + /// + /// + public void RunRouteAction(string routeKey) + { + RunRouteAction(routeKey, new Action(() => { })); + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string sourceListKey) + { + if (string.IsNullOrEmpty(sourceListKey)) + { + Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list."); + RunRouteAction(routeKey, new Action(() => { })); + } + else + { + Debug.Console(1, this, "sourceListKey present but not yet implemented"); + throw new NotImplementedException(); + } + } + + /// + /// + /// + /// + /// + /// + public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback) + { + if (string.IsNullOrEmpty(sourceListKey)) + { + RunRouteAction(routeKey, successCallback); + } + else + throw new NotImplementedException(); + } + + + /// + /// Gets a source from config list SourceListKey and dynamically build and executes the + /// route or commands + /// + /// + public void RunRouteAction(string routeKey, Action successCallback) + { + // Run this on a separate thread + new CTimer(o => + { + // try to prevent multiple simultaneous selections + SourceSelectLock.TryEnter(); + + try + { + + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey); + var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey); + if (dict == null) + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey); + return; + } + + // Try to get the list item by it's string key + if (!dict.ContainsKey(routeKey)) + { + Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'", + routeKey, SourceListKey); + return; + } + + // End usage timer on last source + if (!string.IsNullOrEmpty(LastSourceKey)) + { + var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking; + if (usageLastSource != null && usageLastSource.UsageTracker != null) + { + try + { + // There MAY have been failures in here. Protect + usageLastSource.UsageTracker.EndDeviceUsage(); + } + catch (Exception e) + { + Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e); + } + } + } + + // Let's run it + var item = dict[routeKey]; + if (routeKey.ToLower() != "roomoff") + { + + LastSourceKey = routeKey; + } + else + CurrentSourceInfoKey = null; + + // hand off the individual routes to this helper + foreach (var route in item.RouteList) + DoRouteItem(route); + + // Start usage timer on routed source + var usageNewSource = item.SourceDevice as IUsageTracking; + if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker! + { + (item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage(); + } + + // See if this can be moved into common, base-class method ------------- + + + // Set volume control, using default if non provided + IBasicVolumeControls volDev = null; + // Handle special cases for volume control + if (string.IsNullOrEmpty(item.VolumeControlKey) + || item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase)) + volDev = DefaultVolumeControls; + else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) + volDev = DefaultDisplay as IBasicVolumeControls; + // Or a specific device, probably rarely used. + else + { + var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey); + if (dev is IBasicVolumeControls) + volDev = dev as IBasicVolumeControls; + else if (dev is IHasVolumeDevice) + volDev = (dev as IHasVolumeDevice).VolumeDevice; + } + + if (volDev != CurrentVolumeControls) + { + // zero the volume on the device we are leaving. + // Set the volume to default on device we are entering + if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback) + { + var vd = CurrentVolumeControls as IBasicVolumeWithFeedback; + SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue; + vd.SetVolume(0); + } + + CurrentVolumeControls = volDev; + if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback) + { + var vd = CurrentVolumeControls as IBasicVolumeWithFeedback; + ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume); + vd.SetVolume(vol); + } + } + // ----------------------------------------------------------------------- + + + + // store the name and UI info for routes + if (item.SourceKey == "$off") + { + CurrentSourceInfoKey = routeKey; + CurrentSourceInfo = null; + } + else if (item.SourceKey != null) + { + CurrentSourceInfoKey = routeKey; + CurrentSourceInfo = item; + } + + OnFeedback.FireUpdate(); + + if (OnFeedback.BoolValue) + { + if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue) + { + Debug.Console(1, this, "Video Codec in use, deactivating standby on codec"); + VideoCodec.StandbyDeactivate(); + } + + if (VideoCodec.StandbyIsOnFeedback.BoolValue) + { + VideoCodec.StandbyDeactivate(); + } + else + { + Debug.Console(1, this, "Video codec not in standby. No need to wake."); + } + } + else + { + Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue); + } + + // report back when done + if (successCallback != null) + successCallback(); + } + catch (Exception e) + { + Debug.Console(1, this, "ERROR in routing: {0}", e); + } + + SourceSelectLock.Leave(); + }, 0); // end of CTimer + } + + /// + /// + /// + /// + void DoRouteItem(SourceRouteListItem route) + { + // if there is a $defaultAll on route, run two separate + if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase)) + { + // Going to assume a single-path route for now + var tempVideo = new SourceRouteListItem + { + DestinationKey = "$defaultDisplay", + SourceKey = route.SourceKey, + Type = eRoutingSignalType.Video + }; + DoRoute(tempVideo); + } + else + DoRoute(route); + } + + /// + /// + /// + /// + /// + bool DoRoute(SourceRouteListItem route) + { + IRoutingSink dest = null; + + if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase)) + dest = DefaultAudioDevice as IRoutingSinkNoSwitching; + else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) + dest = DefaultDisplay; + else + dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; + + if (dest == null) + { + Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey); + return false; + } + + if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) + { + dest.ReleaseRoute(); + if (dest is IHasPowerControl) + (dest as IHasPowerControl).PowerOff(); + + } + else + { + var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs; + if (source == null) + { + Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey); + return false; + } + dest.ReleaseAndMakeRoute(source, route.Type); + } + return true; + } + + public override void RoomVacatedForTimeoutPeriod(object o) + { + //Implement this + } + + /// + /// Does what it says + /// + public override void SetDefaultLevels() + { + Debug.Console(1, this, "Restoring default levels"); + var vc = CurrentVolumeControls as IBasicVolumeWithFeedback; + if (vc != null) + vc.SetVolume(DefaultVolume); + } + /// + /// Will power the room on with the last-used source + /// + public override void PowerOnToDefaultOrLastSource() + { + if (!EnablePowerOnToLastSource || LastSourceKey == null) + return; + RunRouteAction(LastSourceKey); + } + + /// + /// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions + /// + public static void AllRoomsOff() + { + var allRooms = DeviceManager.AllDevices.Where(d => + d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions); + foreach (var room in allRooms) + (room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); + } + + + /// + /// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch + /// + private void SetCodecExternalSources() + { + var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching; + + if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled) + { + return; + } + + try + { + // Get the tie line that the external switcher is connected to + string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault( + x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort; + + videoCodecWithExternalSwitching.ClearExternalSources(); + videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec; + var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ; + + foreach (var kvp in srcList) + { + var srcConfig = kvp.Value; + + if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff") + { + videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); + videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); + } + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error setting codec external sources: {0}", e); + } + } + + private void SetCodecBranding() + { + var vcWithBranding = VideoCodec as IHasBranding; + + if (vcWithBranding == null) return; + + Debug.Console(1, this, "Setting Codec Branding"); + vcWithBranding.InitializeBranding(Key); + } + + #region IPrivacy Members + + + public void PrivacyModeOff() + { + VideoCodec.PrivacyModeOff(); + } + + public void PrivacyModeOn() + { + VideoCodec.PrivacyModeOn(); + } + + public void PrivacyModeToggle() + { + VideoCodec.PrivacyModeToggle(); + } + + #endregion + + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index 6d80913f..00c55d1c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -59,8 +59,6 @@ namespace PepperDash.Essentials.Core void CreateScenarios() { - RoomCombinationScenarios = new List(); - foreach (var scenarioConfig in _propertiesConfig.Scenarios) { var scenario = new RoomCombinationScenario(scenarioConfig); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 05295f42..9d721584 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -87,6 +87,9 @@ namespace PepperDash.Essentials.Core [JsonProperty("partitionStates")] public List PartitionStates { get; set; } + /// + /// Determines which UI devices get mapped to which room in this scenario. The Key should be the key of the UI device and the Value should be the key of the room to map to + /// [JsonProperty("uiMap")] public Dictionary UiMap { get; set; } From 61d8370329ef74c90c0862d9f3f93f382baa78fd Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 20 Jul 2021 17:27:30 -0600 Subject: [PATCH 276/480] Updates to config type in IEssentialsHuddleVtc1Room --- .../Types/EssentialsCombinedHuddleVtc1Room.cs | 78 ++++++++++--------- .../Room/Types/EssentialsHuddleVtc1Room.cs | 4 +- .../Interfaces/IEssentialsHuddleVtc1Room.cs | 2 +- 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs index 1be38cb0..7f140ff3 100644 --- a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs @@ -213,7 +213,6 @@ namespace PepperDash.Essentials { PropertiesConfig = JsonConvert.DeserializeObject (config.Properties.ToString()); - DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching; VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase; @@ -266,42 +265,7 @@ namespace PepperDash.Essentials return false; }); - var disp = DefaultDisplay as DisplayBase; - if (disp != null) - { - // Link power, warming, cooling to display - var dispTwoWay = disp as IHasPowerControlWithFeedback; - if (dispTwoWay != null) - { - dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) => - { - if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) - { - if (!dispTwoWay.PowerIsOnFeedback.BoolValue) - CurrentSourceInfo = null; - OnFeedback.FireUpdate(); - } - if (dispTwoWay.PowerIsOnFeedback.BoolValue) - { - SetDefaultLevels(); - } - }; - } - - disp.IsWarmingUpFeedback.OutputChange += (o, a) => - { - IsWarmingUpFeedback.FireUpdate(); - if (!IsWarmingUpFeedback.BoolValue) - (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume); - }; - disp.IsCoolingDownFeedback.OutputChange += (o, a) => - { - IsCoolingDownFeedback.FireUpdate(); - }; - - } - - + SetupDisplays(); // Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this); @@ -339,6 +303,46 @@ namespace PepperDash.Essentials } } + private void SetupDisplays() + { + //DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching; + + var disp = DefaultDisplay as DisplayBase; + if (disp != null) + { + // Link power, warming, cooling to display + var dispTwoWay = disp as IHasPowerControlWithFeedback; + if (dispTwoWay != null) + { + dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) => + { + if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) + { + if (!dispTwoWay.PowerIsOnFeedback.BoolValue) + CurrentSourceInfo = null; + OnFeedback.FireUpdate(); + } + if (dispTwoWay.PowerIsOnFeedback.BoolValue) + { + SetDefaultLevels(); + } + }; + } + + disp.IsWarmingUpFeedback.OutputChange += (o, a) => + { + IsWarmingUpFeedback.FireUpdate(); + if (!IsWarmingUpFeedback.BoolValue) + (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume); + }; + disp.IsCoolingDownFeedback.OutputChange += (o, a) => + { + IsCoolingDownFeedback.FireUpdate(); + }; + + } + } + private void SetSourceListKey() { if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 5e7b5c37..14fa93e1 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -101,7 +101,7 @@ namespace PepperDash.Essentials } } - public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; } + public EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; private set; } public IRoutingSinkWithSwitching DefaultDisplay { get; private set; } public IBasicVolumeControls DefaultAudioDevice { get; private set; } @@ -210,7 +210,7 @@ namespace PepperDash.Essentials { PropertiesConfig = JsonConvert.DeserializeObject (config.Properties.ToString()); - DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching; + DefaultDisplay = DeviceManager.GetDeviceForKey((PropertiesConfig as EssentialsHuddleVtc1PropertiesConfig).DefaultDisplayKey) as IRoutingSinkWithSwitching; VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase; diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs index 5a6e9f59..f3988cb2 100644 --- a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs @@ -10,7 +10,7 @@ namespace PepperDash.Essentials public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback { - EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } + EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; } void RunRouteAction(string routeKey); From 1415999d8653fbb1760908b3fc1ef0ad1cb5e30b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 17:28:40 -0600 Subject: [PATCH 277/480] refactor: Update a debug message with IP-ID info --- .../Fusion/EssentialsHuddleVtc1FusionController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 54d936f0..c3877706 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -150,7 +150,7 @@ namespace PepperDash.Essentials.Fusion protected override void CreateSymbolAndBasicSigs(uint ipId) { - Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); + Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId); FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); From 88e5c49663f7b0b9db35faec8480cec00ab0f627 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 17:29:02 -0600 Subject: [PATCH 278/480] refactor: Add Fusion IP-ID info to debug messages --- PepperDashEssentials/ControlSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 8c3399ae..ba5529d9 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -477,7 +477,7 @@ namespace PepperDash.Essentials { DeviceManager.AddDevice(room); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); @@ -489,7 +489,7 @@ namespace PepperDash.Essentials { DeviceManager.AddDevice(room); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -501,7 +501,7 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); Debug.Console(0, Debug.ErrorLogLevel.Notice, - "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion"); + "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); From de7a74eaffa5946f0330985d4de6ec979faefe37 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 17:30:45 -0600 Subject: [PATCH 279/480] feat: Update Fusion to create a GUID file per room This allows for multiple rooms to be designated and created without any issues. Also moved post Activation action to it's own method rather than a lambda. In the interest of backwards compatibility, the Fusion class will look for a GUID file with the old file name and migrate it to the new file name. --- ...lsHuddleSpaceFusionSystemControllerBase.cs | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index a172ab49..1bf925d6 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -119,9 +119,21 @@ namespace PepperDash.Essentials.Core.Fusion var slot = Global.ControlSystem.ProgramNumber; var guidFilePath = Global.FilePathPrefix + - string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag); + string.Format(@"{0}-FusionGuids-{1:X2}.json", InitialParametersClass.ProgramIDTag, _ipId); - _guidFileExists = File.Exists(guidFilePath); + var oldGuidFilePath = Global.FilePathPrefix + + string.Format(@"{0}-FusionGuids.json", InitialParametersClass.ProgramIDTag); + + if (File.Exists(oldGuidFilePath)) + { + Debug.Console(0, this, "Migrating from old Fusion GUID file to new Fusion GUID File"); + + File.Copy(oldGuidFilePath, guidFilePath); + + File.Delete(oldGuidFilePath); + } + + _guidFileExists = File.Exists(guidFilePath); // Check if file exists if (!_guidFileExists) @@ -149,19 +161,7 @@ namespace PepperDash.Essentials.Core.Fusion } - AddPostActivationAction(() => - { - CreateSymbolAndBasicSigs(_ipId); - SetUpSources(); - SetUpCommunitcationMonitors(); - SetUpDisplay(); - SetUpError(); - ExecuteCustomSteps(); - - FusionRVI.GenerateFileForAllFusionDevices(); - - GenerateGuidFile(guidFilePath); - }); + AddPostActivationAction(() => PostActivate(guidFilePath)); } catch (Exception e) { @@ -169,6 +169,20 @@ namespace PepperDash.Essentials.Core.Fusion } } + private void PostActivate(string guidFilePath) + { + CreateSymbolAndBasicSigs(_ipId); + SetUpSources(); + SetUpCommunitcationMonitors(); + SetUpDisplay(); + SetUpError(); + ExecuteCustomSteps(); + + FusionRVI.GenerateFileForAllFusionDevices(); + + GenerateGuidFile(guidFilePath); + } + protected string RoomGuid { get { return _guiDs.RoomGuid; } @@ -314,7 +328,7 @@ namespace PepperDash.Essentials.Core.Fusion protected virtual void CreateSymbolAndBasicSigs(uint ipId) { - Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId); FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); From 290e887903d2d0f3ac84eede97aeda695680c5fd Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 20 Jul 2021 17:32:00 -0600 Subject: [PATCH 280/480] refactor: Modify debug messages Exceptions now print the device key and the error message. To see stack traces, use `appdebug:XX 1`. There are also now debug messages indicating when the different activation cycles are complete. --- .../Devices/DeviceManager.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index aac38dfa..df864550 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -60,6 +60,7 @@ namespace PepperDash.Essentials.Core DeviceCriticalSection.Enter(); AddDeviceEnabled = false; // PreActivate all devices + Debug.Console(0,"****PreActivation starting...****"); foreach (var d in Devices.Values) { try @@ -69,9 +70,12 @@ namespace PepperDash.Essentials.Core } catch (Exception e) { - Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e); + Debug.Console(0, d, "ERROR: Device {1} PreActivation failure: {0}", e.Message, d.Key); + Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace); } } + Debug.Console(0, "****PreActivation complete****"); + Debug.Console(0, "****Activation starting...****"); // Activate all devices foreach (var d in Devices.Values) @@ -83,10 +87,14 @@ namespace PepperDash.Essentials.Core } catch (Exception e) { - Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e); + Debug.Console(0, d, "ERROR: Device {1} Activation failure: {0}", e.Message, d.Key); + Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace); } } + Debug.Console(0, "****Activation complete****"); + Debug.Console(0, "****PostActivation starting...****"); + // PostActivate all devices foreach (var d in Devices.Values) { @@ -97,10 +105,13 @@ namespace PepperDash.Essentials.Core } catch (Exception e) { - Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e); + Debug.Console(0, d, "ERROR: Device {1} PostActivation failure: {0}", e.Message, d.Key); + Debug.Console(1, d, "Stack Trace: {0}", e.StackTrace); } } + Debug.Console(0, "****PostActivation complete****"); + OnAllDevicesActivated(); } finally From 56f9a29c612b66a080b4921bc9f6970c423f0de0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 21 Jul 2021 14:19:57 -0600 Subject: [PATCH 281/480] #753 Updates some of the Funcs --- .../Types/EssentialsCombinedHuddleVtc1Room.cs | 77 +++++++++++++++++-- .../Interfaces/IEssentialsHuddleVtc1Room.cs | 2 + 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs index 7f140ff3..de4b26ec 100644 --- a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs @@ -75,9 +75,18 @@ namespace PepperDash.Essentials { return () => { - var disp = DefaultDisplay as DisplayBase; - if (disp != null) - return disp.IsWarmingUpFeedback.BoolValue; + var displays = Displays.Where((d) => d is TwoWayDisplayBase) as List; + if (displays != null) + { + var warmingDisplays = displays.Where((d) => d.IsWarmingUpFeedback.BoolValue); + + if (warmingDisplays.Count() > 0) + { + return true; + } + else + return false; + } else return false; }; @@ -92,9 +101,18 @@ namespace PepperDash.Essentials { return () => { - var disp = DefaultDisplay as DisplayBase; - if (disp != null) - return disp.IsCoolingDownFeedback.BoolValue; + var displays = Displays.Where((d) => d is TwoWayDisplayBase) as List; + if (displays != null) + { + var coolingDisplays = displays.Where((d) => d.IsCoolingDownFeedback.BoolValue); + + if (coolingDisplays.Count() > 0) + { + return true; + } + else + return false; + } else return false; }; @@ -307,6 +325,53 @@ namespace PepperDash.Essentials { //DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching; + var destinationList = ConfigReader.ConfigObject.DestinationLists[PropertiesConfig.DestinationListKey]; + + foreach (var destination in destinationList) + { + var dest = destination.Value.SinkDevice as IRoutingSinkWithSwitching; + + if (dest != null) + { + Displays.Add(dest); + } + + var display = dest as DisplayBase; + if (display != null) + { + // Link power, warming, cooling to display + var dispTwoWay = display as IHasPowerControlWithFeedback; + if (dispTwoWay != null) + { + dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) => + { + if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) + { + if (!dispTwoWay.PowerIsOnFeedback.BoolValue) + CurrentSourceInfo = null; + OnFeedback.FireUpdate(); + } + if (dispTwoWay.PowerIsOnFeedback.BoolValue) + { + SetDefaultLevels(); + } + }; + } + + display.IsWarmingUpFeedback.OutputChange += (o, a) => + { + IsWarmingUpFeedback.FireUpdate(); + if (!IsWarmingUpFeedback.BoolValue) + (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume); + }; + display.IsCoolingDownFeedback.OutputChange += (o, a) => + { + IsCoolingDownFeedback.FireUpdate(); + }; + + } + } + var disp = DefaultDisplay as DisplayBase; if (disp != null) { diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs index f3988cb2..4b13145c 100644 --- a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs @@ -12,6 +12,8 @@ namespace PepperDash.Essentials { EssentialsConferenceRoomPropertiesConfig PropertiesConfig { get; } + bool ExcludeFromGlobalFunctions { get; } + void RunRouteAction(string routeKey); IHasScheduleAwareness ScheduleSource { get; } From c4752b2ac26c83c8efe34a19cb0a4dc5fa142497 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 21 Jul 2021 21:33:57 -0600 Subject: [PATCH 282/480] #753 EssentialsCombinedHuddleVtc1Room should be ready for testing --- .../Types/EssentialsCombinedHuddleVtc1Room.cs | 74 ++++++------------- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 2 +- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 2 +- 3 files changed, 24 insertions(+), 54 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs index de4b26ec..79f28aae 100644 --- a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs @@ -57,10 +57,11 @@ namespace PepperDash.Essentials { return () => { - var disp = DefaultDisplay as DisplayBase; + var displays = Displays.Where((d) => d is DisplayBase) as List; + var val = CurrentSourceInfo != null && CurrentSourceInfo.Type == eSourceListItemType.Route - && disp != null; + && displays.Count() > 0; //&& disp.PowerIsOnFeedback.BoolValue; return val; }; @@ -246,6 +247,8 @@ namespace PepperDash.Essentials DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; + Displays = new List(); + Initialize(); } catch (Exception e) @@ -347,8 +350,8 @@ namespace PepperDash.Essentials { if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) { - if (!dispTwoWay.PowerIsOnFeedback.BoolValue) - CurrentSourceInfo = null; + //if (!dispTwoWay.PowerIsOnFeedback.BoolValue) + // CurrentSourceInfo = null; OnFeedback.FireUpdate(); } if (dispTwoWay.PowerIsOnFeedback.BoolValue) @@ -371,41 +374,6 @@ namespace PepperDash.Essentials } } - - var disp = DefaultDisplay as DisplayBase; - if (disp != null) - { - // Link power, warming, cooling to display - var dispTwoWay = disp as IHasPowerControlWithFeedback; - if (dispTwoWay != null) - { - dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) => - { - if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) - { - if (!dispTwoWay.PowerIsOnFeedback.BoolValue) - CurrentSourceInfo = null; - OnFeedback.FireUpdate(); - } - if (dispTwoWay.PowerIsOnFeedback.BoolValue) - { - SetDefaultLevels(); - } - }; - } - - disp.IsWarmingUpFeedback.OutputChange += (o, a) => - { - IsWarmingUpFeedback.FireUpdate(); - if (!IsWarmingUpFeedback.BoolValue) - (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume); - }; - disp.IsCoolingDownFeedback.OutputChange += (o, a) => - { - IsCoolingDownFeedback.FireUpdate(); - }; - - } } private void SetSourceListKey() @@ -624,8 +592,8 @@ namespace PepperDash.Essentials if (string.IsNullOrEmpty(item.VolumeControlKey) || item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase)) volDev = DefaultVolumeControls; - else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) - volDev = DefaultDisplay as IBasicVolumeControls; + //else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) + // volDev = DefaultDisplay as IBasicVolumeControls; // Or a specific device, probably rarely used. else { @@ -717,14 +685,16 @@ namespace PepperDash.Essentials // if there is a $defaultAll on route, run two separate if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase)) { - // Going to assume a single-path route for now - var tempVideo = new SourceRouteListItem + foreach (var display in Displays) { - DestinationKey = "$defaultDisplay", - SourceKey = route.SourceKey, - Type = eRoutingSignalType.Video - }; - DoRoute(tempVideo); + var tempVideo = new SourceRouteListItem + { + DestinationKey = display.Key, + SourceKey = route.SourceKey, + Type = eRoutingSignalType.Video + }; + DoRoute(tempVideo); + } } else DoRoute(route); @@ -740,11 +710,11 @@ namespace PepperDash.Essentials IRoutingSink dest = null; if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase)) - dest = DefaultAudioDevice as IRoutingSinkNoSwitching; - else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) - dest = DefaultDisplay; + dest = DefaultAudioDevice as IRoutingSink; + //else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase)) + // dest = DefaultDisplay; else - dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; + dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink; if (dest == null) { diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index a0d5947c..1141b5fa 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -306,7 +306,7 @@ namespace PepperDash.Essentials TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () => { - if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl) + if (CurrentRoom != null && CurrentRoom.DefaultDisplay != null && CurrentRoom.DefaultDisplay is IHasPowerControl) (CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle(); }); diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 6280f54e..6fb7a047 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -319,7 +319,7 @@ namespace PepperDash.Essentials TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () => { - if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl) + if (CurrentRoom != null && CurrentRoom.DefaultDisplay != null && CurrentRoom.DefaultDisplay is IHasPowerControl) (CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle(); }); From bfa48091d95584220383d209efe68430b70e7a52 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 22 Jul 2021 12:44:13 -0600 Subject: [PATCH 283/480] #753 Adds methods to build new room type --- PepperDashEssentials/ControlSystem.cs | 7 +++++-- PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index ba5529d9..aafb5b1e 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -489,8 +489,11 @@ namespace PepperDash.Essentials { DeviceManager.AddDevice(room); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); - DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); + if (!(room is EssentialsCombinedHuddleVtc1Room)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); + } Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 5ec0565d..c5a6e949 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -39,6 +39,10 @@ namespace PepperDash.Essentials.Room.Config { return new EssentialsDualDisplayRoom(roomConfig); } + if (typeName == "combinedhuddlevtc1") + { + return new EssentialsCombinedHuddleVtc1Room(roomConfig); + } return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig); } From 2db397b474ea1eaf48d0b1d2aecba7e4b789261e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 22 Jul 2021 12:46:27 -0600 Subject: [PATCH 284/480] #742 Adds step to post activation action to determine initial room combination scenario --- .../Room/Combining/EssentialsRoomCombiner.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index 00c55d1c..a0284dc1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -54,6 +54,15 @@ namespace PepperDash.Essentials.Core SetupPartitionStateProviders(); SetRooms(); + + if (isInAutoMode) + { + DetermineRoomCombinationScenario(); + } + else + { + SetRoomCombinationScenario(_propertiesConfig.defaultScenarioKey); + } }); } From 085a64c87b14ce76ad0e955fc255c94cb1da9601 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 13:41:21 -0600 Subject: [PATCH 285/480] fix: Correct functioning while in test mode --- .../GlsPartitionSensorController.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 114909c4..26cade95 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -39,10 +39,10 @@ namespace PepperDash.Essentials.Core RegisterCrestronGenericBase(_partitionSensor); NameFeedback = new StringFeedback(() => Name); - EnableFeedback = new BoolFeedback(() => _partitionSensor.EnableFeedback.BoolValue); - PartitionPresentFeedback = new BoolFeedback(() => _partitionSensor.PartitionSensedFeedback.BoolValue); - PartitionNotSensedFeedback = new BoolFeedback(() => _partitionSensor.PartitionNotSensedFeedback.BoolValue); - SensitivityFeedback = new IntFeedback(() => _partitionSensor.SensitivityFeedback.UShortValue); + EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue); + PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue); + PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue); + SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue); if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent; }); @@ -93,6 +93,9 @@ namespace PepperDash.Essentials.Core if (InTestMode) { TestEnableFeedback = state; + + EnableFeedback.FireUpdate(); + Debug.Console(1, this, "TestEnableFeedback: {0}", TestEnableFeedback.ToString()); return; } @@ -105,6 +108,10 @@ namespace PepperDash.Essentials.Core if (InTestMode) { TestPartitionSensedFeedback = state; + + PartitionPresentFeedback.FireUpdate(); + PartitionNotSensedFeedback.FireUpdate(); + Debug.Console(1, this, "TestPartitionSensedFeedback: {0}", TestPartitionSensedFeedback.ToString()); return; } @@ -117,6 +124,8 @@ namespace PepperDash.Essentials.Core if (InTestMode) { TestSensitivityFeedback = value; + + SensitivityFeedback.FireUpdate(); Debug.Console(1, this, "TestSensitivityFeedback: {0}", TestSensitivityFeedback); return; } From f607394ee724d9192d83d88db5f9c6ccb97748b3 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 16:53:11 -0600 Subject: [PATCH 286/480] chore: Update PD Core to 1.0.48 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 3876040a..3494f2eb 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 4bd777f6b942b2da27ada6a163788ecff8bd1e33 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 16:53:36 -0600 Subject: [PATCH 287/480] feat: Update `Essentials Device` to call `Initialize` method --- .../Devices/EssentialsDevice.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 781101d4..00624007 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -27,6 +27,27 @@ namespace PepperDash.Essentials.Core { } + + private void SubscribeToActivateComplete() + { + DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated; + } + + private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs) + { + CrestronInvoke.BeginInvoke((o) => + { + try + { + Initialize(); + } + catch (Exception ex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message); + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace); + } + }); + } } [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] From 6542c062b9777b5de8ffe157cd0c74c4d7422019 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 23 Jul 2021 17:35:12 -0600 Subject: [PATCH 288/480] Working towards getting EssentialsTouchpanelController to switch rooms --- .../Room/Config/EssentialsRoomConfig.cs | 6 ++++ .../UI/EssentialsTouchpanelController.cs | 33 +++++++++++++++++++ ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 2 +- .../EssentialsRoomCombinerPropertiesConfig.cs | 2 +- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index c5a6e949..078f9bd5 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -187,6 +187,12 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")] public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; } + /// + /// Indicates if this room represents a combination of other rooms + /// + [JsonProperty("isRoomCombinationScenario")] + public bool IsRoomCombinationScenario { get; set; } + public EssentialsRoomPropertiesConfig() { LogoLight = new EssentialsLogoPropertiesConfig(); diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 7873bf42..b295cf95 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -16,6 +16,8 @@ namespace PepperDash.Essentials { public class EssentialsTouchpanelController : EssentialsDevice, IHasBasicTriListWithSmartObject { + private CrestronTouchpanelPropertiesConfig _propertiesConfig; + public BasicTriListWithSmartObject Panel { get; private set; } public PanelDriverBase PanelDriver { get; private set; } @@ -50,6 +52,7 @@ namespace PepperDash.Essentials public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id) : base(key, name) { + _propertiesConfig = props; Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating touchpanel hardware..."); type = type.ToLower(); @@ -124,8 +127,38 @@ namespace PepperDash.Essentials Panel.LoadSmartObjects(sgdName); Panel.SigChange += Panel_SigChange; + AddPostActivationAction(() => + { + // Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event + + var roomCombiner = DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) as IEssentialsRoomCombiner; + + if (roomCombiner != null) + { + roomCombiner.RoomCombinationScenarioChanged += new EventHandler(roomCombiner_RoomCombinationScenarioChanged); + } + }); + } + void roomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e) + { + var roomCombiner = sender as IEssentialsRoomCombiner; + + string newRoomKey = null; + + if (roomCombiner.CurrentScenario.UiMap.ContainsKey(Key)) + { + newRoomKey = roomCombiner.CurrentScenario.UiMap[Key]; + } + else if (roomCombiner.CurrentScenario.UiMap.ContainsKey(_propertiesConfig.DefaultRoomKey)) + { + newRoomKey = roomCombiner.CurrentScenario.UiMap[_propertiesConfig.DefaultRoomKey]; + } + + // TODO: + } + public void LoadAndShowDriver(PanelDriverBase driver) { PanelDriver = driver; diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 6fb7a047..ffc6fec1 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -448,7 +448,7 @@ namespace PepperDash.Essentials // and the LastMeetingDismissed != this meeting var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId); - Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", + Debug.Console(1, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", CurrentRoom.OnFeedback.BoolValue, LastMeetingDismissedId, lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : ""); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs index 9d721584..6fb15042 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombinerPropertiesConfig.cs @@ -30,7 +30,7 @@ namespace PepperDash.Essentials.Core /// /// The list of rooms keys that can be combined /// - [JsonProperty("roomMap")] + [JsonProperty("roomKeys")] public List RoomKeys {get; set;} /// From 76e4d4a82d9994ec2e0c1b3c7dd76810cd29f724 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 19:44:41 -0600 Subject: [PATCH 289/480] feat: Add method call to constructor for EssentialsDevice --- .../PepperDashEssentialsBase/Devices/EssentialsDevice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 00624007..46fa819b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -19,13 +19,13 @@ namespace PepperDash.Essentials.Core protected EssentialsDevice(string key) : base(key) { - + SubscribeToActivateComplete(); } protected EssentialsDevice(string key, string name) : base(key, name) { - + SubscribeToActivateComplete(); } private void SubscribeToActivateComplete() From ea254ef98333f754e12f411891613a2691f05d8a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 19:56:29 -0600 Subject: [PATCH 290/480] feat: Update some internal Essentials devices to use Initialize method --- .../MicrophonePrivacyController.cs | 14 +++++++++----- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 19 +++++++++++++------ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 17 +++++++++++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs index 0f15a02d..55b458a7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs @@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy else Debug.Console(0, this, "Unable to add Red LED device"); - DeviceManager.AllDevicesActivated += (o, a) => - { - CheckPrivacyMode(); - }; - AddPostActivationAction(() => { PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange; PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange; @@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy return base.CustomActivate(); } + #region Overrides of Device + + public override void Initialize() + { + CheckPrivacyMode(); + } + + #endregion + public void SetPrivacyDevice(IPrivacy privacyDevice) { PrivacyDevice = privacyDevice; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index a7be2443..7cfe82c0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -550,6 +550,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); + return base.CustomActivate(); + } + + #region Overrides of Device + + public override void Initialize() + { var socket = Communication as ISocketStatus; if (socket != null) { @@ -558,9 +565,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco Communication.Connect(); - CommunicationMonitor.Start(); + CommunicationMonitor.Start(); - string prefix = "xFeedback register "; + const string prefix = "xFeedback register "; CliFeedbackRegistrationExpression = prefix + "/Configuration" + Delimiter + @@ -575,14 +582,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Status/Video/Layout" + Delimiter + prefix + "/Status/Video/Input/MainVideoMute" + Delimiter + prefix + "/Bookings" + Delimiter + - prefix + "/Event/CallDisconnect" + Delimiter + + prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/Bookings" + Delimiter + prefix + "/Event/CameraPresetListUpdated" + Delimiter + - prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; - - return base.CustomActivate(); + prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; } + #endregion + /// /// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc. /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index fc3f14a9..e838ceed 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -717,7 +717,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); - var socket = Communication as ISocketStatus; + + + return base.CustomActivate(); + } + + #region Overrides of Device + + public override void Initialize() + { + var socket = Communication as ISocketStatus; if (socket != null) { socket.ConnectionChange += socket_ConnectionChange; @@ -728,11 +737,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Communication.Connect(); CommunicationMonitor.Start(); + } - return base.CustomActivate(); - } + #endregion - public void SetCommDebug(string s) + public void SetCommDebug(string s) { if (s == "1") { From 7b57ce439ecf46e0ffbabbdeb0c408f4e9439b9a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 28 Jul 2021 14:47:17 -0600 Subject: [PATCH 291/480] #761 Adds support for x70 series touchpanels --- .../UI/EssentialsTouchpanelController.cs | 12 +++++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 65039872..92552841 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -79,6 +79,16 @@ namespace PepperDash.Essentials Panel = new Tsw1052(id, Global.ControlSystem); else if (type == "tsw1060") Panel = new Tsw1060(id, Global.ControlSystem); + else if (type == "tsw570") + Panel = new Tsw570(id, Global.ControlSystem); + else if (type == "tsw770") + Panel = new Tsw770(id, Global.ControlSystem); + else if (type == "ts770") + Panel = new Ts770(id, Global.ControlSystem); + else if (type == "tsw1070") + Panel = new Tsw1070(id, Global.ControlSystem); + else if (type == "ts1070") + Panel = new Ts1070(id, Global.ControlSystem); else { Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type); @@ -203,7 +213,7 @@ namespace PepperDash.Essentials { public EssentialsTouchpanelControllerFactory() { - TypeNames = new List() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" }; + TypeNames = new List() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index fc3f14a9..394ef0c7 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -667,6 +667,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { DirectoryRoot = new CodecDirectory(); + _currentDirectoryResult = DirectoryRoot; + DirectoryBrowseHistory = new List(); DirectoryBrowseHistoryStack = new Stack(); From eec86fde487c6e46f842a6bbadd0ec3ea42d6d38 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 28 Jul 2021 15:23:57 -0600 Subject: [PATCH 292/480] Updates incorrect path for ZoomRoom feedback exclusions and adds toll_free_callinList --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 394ef0c7..a1aca4dd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -972,10 +972,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("echo off"); Thread.Sleep(100); // set feedback exclusions - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callin_country_list"); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); Thread.Sleep(100); - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/info/callout_country_list"); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list"); Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); + Thread.Sleep(100); if (!_props.DisablePhonebookAutoDownload) { From e7bbfbd40aa8bdb09ba5f646c498270c2ea57a18 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 28 Jul 2021 15:27:47 -0600 Subject: [PATCH 293/480] Update to add populate call Id and Name properties to allow proper removal of inactive calls --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a1aca4dd..60f663ab 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1589,7 +1589,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; } - var newCall = new CodecActiveCallItem { Status = newStatus }; + var newCall = new CodecActiveCallItem + { + Name = Status.Call.Info.meeting_list_item.meetingName, + Id = Status.Call.Info.meeting_id, + Status = newStatus + }; ActiveCalls.Add(newCall); From 66ff6b2e07c0bac62c6c1b4289b18b2d9b0afac1 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 28 Jul 2021 15:33:04 -0600 Subject: [PATCH 294/480] Brings in another small zoom update from @jkdevito --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 60f663ab..f08b2d6c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1650,7 +1650,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //clear participants list after call cleanup if (ActiveCalls.Count == 0) { - Participants.CurrentParticipants = new List(); + var emptyList = new List(); + Participants.CurrentParticipants = emptyList; } } From f4ac4e6319d2a38f1b7e588ca71f204be0013c91 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 28 Jul 2021 16:38:20 -0600 Subject: [PATCH 295/480] Minor updates to resolve oddities with ZoomRoom and TSW UI drivers (call status) --- .../UIDrivers/Essentials/EssentialsHeaderDriver.cs | 1 + .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 2 +- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index ccaedd9c..f9092958 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -207,6 +207,7 @@ namespace PepperDash.Essentials //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1); // Set the call status text + Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count); if (codec.ActiveCalls.Count > 0) { if (codec.ActiveCalls.Count == 1) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index a4e88e7e..fd39d4bc 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -1035,7 +1035,7 @@ namespace PepperDash.Essentials if (CurrentRoom.CurrentSourceInfo != null && CurrentRoom.CurrentSourceInfo.DisableCodecSharing) { Debug.Console(1, CurrentRoom, "Transitioning to in-call, cancelling non-sharable source"); - CurrentRoom.RunRouteAction("codecOsd", CurrentRoom.SourceListKey); + CurrentRoom.RunRouteAction("codecOsd"); } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index f08b2d6c..f8d4bf47 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1569,6 +1569,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "Creating new Status.Call object"); Status.Call = new zStatus.Call { Status = callStatus }; + OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected }); + SetUpCallFeedbackActions(); } @@ -1603,6 +1605,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom OnCallStatusChange(newCall); } + + } else { From 0cd3c1bdc509d5ec58ccfc42561b789d6077b728 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 29 Jul 2021 13:01:02 -0600 Subject: [PATCH 296/480] fix(ZoomRoom): #767 #768 Adds Output2 on ZoomRoom and updates to UI for VTC Updates EssentialsVideoCodecUiDriver and codec classes to better deal with dynamic use of IHasCallHistory and --- .../UI/JoinConstants/UIBoolJoin.cs | 7 ++++- .../VC/EssentialsVideoCodecUiDriver.cs | 26 ++++++++++++++----- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 3 ++- .../VideoCodec/CiscoCodec/xStatus.cs | 20 ++++++++++++-- .../VideoCodec/VideoCodecBase.cs | 4 +-- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 6 +++++ 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index 293fddd5..f8685671 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -103,7 +103,7 @@ namespace PepperDash.Essentials /// /// 1202 /// - public const uint VCStagingInactivePopoverVisible = 1202; + public const uint VCStagingInactivePopoverWithRecentsVisible = 1202; /// /// /// @@ -121,6 +121,11 @@ namespace PepperDash.Essentials /// public const uint VCRecentsVisible = 1206; + /// + /// 1202 + /// + public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207; + /// /// 1208 /// diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 5642d757..6d5521a8 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -142,7 +142,10 @@ namespace PepperDash.Essentials.UIDrivers.VC VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); StagingBarsInterlock = new JoinedSigInterlock(triList); - StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible); + if(Codec is IHasCallHistory) + StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible); + else + StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible); StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); @@ -351,10 +354,15 @@ namespace PepperDash.Essentials.UIDrivers.VC TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0); uint stageJoin; - if (Codec.IsInCall) - stageJoin = UIBoolJoin.VCStagingActivePopoverVisible; - else - stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible; + if (Codec.IsInCall) + stageJoin = UIBoolJoin.VCStagingActivePopoverVisible; + else + { + if (Codec is IHasCallHistory) + stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible; + else + stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible; + } if (IsVisible) StagingBarsInterlock.ShowInterlocked(stageJoin); else @@ -513,9 +521,13 @@ namespace PepperDash.Essentials.UIDrivers.VC var codecOffCameras = Codec as IHasCameraOff; + var supportsCameraOffMode = Codec.SupportsCameraOff; + var codecAutoCameras = Codec as IHasCameraAutoMode; - if (codecAutoCameras != null) + var supportsAutoCameraMode = Codec.SupportsCameraAutoMode; + + if (codecAutoCameras != null && supportsAutoCameraMode) { CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn()); TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true; @@ -554,7 +566,7 @@ namespace PepperDash.Essentials.UIDrivers.VC //TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction( // () => ShowCameraManualMode()); - if (codecOffCameras != null) + if (codecOffCameras != null && supportsCameraOffMode) { TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true; codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index a7be2443..d31fbda1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -314,7 +314,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco FarEndIsSharingContentFeedback = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); CameraIsOffFeedback = new BoolFeedback(() => CodecStatus.Status.Video.Input.MainVideoMute.BoolValue); CameraIsMutedFeedback = CameraIsOffFeedback; - + SupportsCameraOff = true; PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); @@ -417,6 +417,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate; + CodecStatus.Status.Cameras.SpeakerTrack.Availability.ValueChangedAction = () => { SupportsCameraAutoMode = CodecStatus.Status.Cameras.SpeakerTrack.Availability.BoolValue; }; CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate; CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 676737c4..8184289e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -277,9 +277,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public SoftwareID SoftwareID { get; set; } } - public class Availability + public class Availability : ValueProperty { - public string Value { get; set; } + string _Value; + public bool BoolValue { get; private set; } + + public string Value + { + get + { + return _Value; + } + set + { + // If the incoming value is "Available" it sets the BoolValue true, otherwise sets it false + _Value = value; + BoolValue = value == "Available"; + OnValueChanged(); + } + } } public class Status2 : ValueProperty 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 fc38a647..c5cff74e 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 @@ -65,8 +65,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public bool ShowSelfViewByDefault { get; protected set; } - protected bool SupportsCameraOff; - protected bool SupportsCameraAutoMode; + public bool SupportsCameraOff { get; protected set; } + public bool SupportsCameraAutoMode { get; protected set; } public bool IsReady { get; protected set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index f8d4bf47..9ac80c33 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -95,6 +95,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this); + Output2 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, + eRoutingSignalType.Video, + eRoutingPortConnectionType.DisplayPort, null, this); + SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc); CameraIsOffFeedback = new BoolFeedback(CameraIsOffFeedbackFunc); @@ -252,6 +256,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public RoutingInputPort CodecOsdIn { get; private set; } public RoutingOutputPort Output1 { get; private set; } + public RoutingOutputPort Output2 { get; private set; } #region ICommunicationMonitor Members @@ -685,6 +690,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // Set up output ports OutputPorts.Add(Output1); + OutputPorts.Add(Output2); } /// From 49c1c61a8830269ef3a1624a8336c24ecebf0679 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 29 Jul 2021 14:51:16 -0600 Subject: [PATCH 297/480] updates ZoomRoom to use GenericQueue --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 45 +++---------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 9ac80c33..c2ec5c38 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -15,6 +15,7 @@ using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Core.Queues; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; @@ -30,10 +31,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; private const string Delimiter = "\x0D\x0A"; - private readonly CrestronQueue _receiveQueue; + + private readonly GenericQueue _receiveQueue; + //private readonly CrestronQueue _receiveQueue; - private readonly Thread _receiveThread; + //private readonly Thread _receiveThread; private readonly ZoomRoomSyncState _syncState; public bool CommDebuggingIsOn; @@ -51,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { _props = JsonConvert.DeserializeObject(config.Properties.ToString()); - // The queue that will collect the repsonses in the order they are received - _receiveQueue = new CrestronQueue(1024); - - // The thread responsible for dequeuing and processing the messages - _receiveThread = new Thread(o => ProcessQueue(), null) { Priority = Thread.eThreadPriority.MediumPriority }; + _receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512); Communication = comm; @@ -787,37 +786,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //if (CommDebuggingIsOn) // Debug.Console(1, this, "Gathered: '{0}'", args.Text); - _receiveQueue.Enqueue(args.Text); - - // If the receive thread has for some reason stopped, this will restart it - if (_receiveThread.ThreadState != Thread.eThreadStates.ThreadRunning) - { - _receiveThread.Start(); - } - } - - - /// - /// Runs in it's own thread to dequeue messages in the order they were received to be processed - /// - /// - private object ProcessQueue() - { - try - { - while (true) - { - var message = _receiveQueue.Dequeue(); - - ProcessMessage(message); - } - } - catch (Exception e) - { - Debug.Console(1, this, "Error Processing Queue: {0}", e); - } - - return null; + _receiveQueue.Enqueue(new ProcessStringMessage(args.Text, ProcessMessage)); } From 19cbe480a64cfa2d31d16254d58f3e3bda02311c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 29 Jul 2021 16:39:34 -0600 Subject: [PATCH 298/480] reverts IMobileControl back to using EssentialsRoomBase instead of IEssentialsRoom for now --- PepperDashEssentials/ControlSystem.cs | 8 +- .../DeviceTypeInterfaces/IMobileControl.cs | 2 +- .../Factory/DeviceFactory.cs | 255 +++++++++--------- 3 files changed, 137 insertions(+), 128 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 033d82fe..2495340c 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -484,7 +484,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room); + CreateMobileControlBridge(room as EssentialsRoomBase); } else if (room is IEssentialsHuddleVtc1Room) { @@ -495,7 +495,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room); + CreateMobileControlBridge(room as EssentialsRoomBase); } else if (room is EssentialsTechRoom) { @@ -507,7 +507,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); - CreateMobileControlBridge(room); + CreateMobileControlBridge(room as EssentialsRoomBase); } else { @@ -524,7 +524,7 @@ namespace PepperDash.Essentials } - private static void CreateMobileControlBridge(IEssentialsRoom room) + private static void CreateMobileControlBridge(EssentialsRoomBase room) { var mobileControl = GetMobileControlDevice(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index a2dda43a..c87e7865 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// public interface IMobileControl : IKeyed { - void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent); + void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent); void LinkSystemMonitorToAppServer(); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index ec041853..a17e0d91 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -1,90 +1,90 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.GeneralIO; -using Crestron.SimplSharp.Reflection; -using PepperDash.Core; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.CrestronIO; -using PepperDash.Essentials.Core.Touchpanels; - -namespace PepperDash.Essentials.Core -{ - public class DeviceFactoryWrapper - { - public CType CType { get; set; } - public string Description { get; set; } - public Func FactoryMethod { get; set; } - - public DeviceFactoryWrapper() - { - CType = null; - Description = "Not Available"; - } - } - - public class DeviceFactory - { - public DeviceFactory() - { - var assy = Assembly.GetExecutingAssembly(); - PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); - - var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); - - if (types != null) - { - foreach (var type in types) - { - try - { - var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); - factory.LoadTypeFactories(); - } - catch (Exception e) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); - } - } - } - } - - /// - /// A dictionary of factory methods, keyed by config types, added by plugins. - /// These methods are looked up and called by GetDevice in this class. - /// - static Dictionary FactoryMethods = - new Dictionary(StringComparer.OrdinalIgnoreCase); - - /// - /// Adds a plugin factory method - /// - /// - /// - public static void AddFactoryForType(string typeName, Func method) - { - Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); - DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); - } - - public static void AddFactoryForType(string typeName, string description, CType cType, Func method) - { - Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); - - if(FactoryMethods.ContainsKey(typeName)) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName); - return; - } - - var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; - DeviceFactory.FactoryMethods.Add(typeName, wrapper); +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.GeneralIO; +using Crestron.SimplSharp.Reflection; +using PepperDash.Core; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.CrestronIO; +using PepperDash.Essentials.Core.Touchpanels; + +namespace PepperDash.Essentials.Core +{ + public class DeviceFactoryWrapper + { + public CType CType { get; set; } + public string Description { get; set; } + public Func FactoryMethod { get; set; } + + public DeviceFactoryWrapper() + { + CType = null; + Description = "Not Available"; + } + } + + public class DeviceFactory + { + public DeviceFactory() + { + var assy = Assembly.GetExecutingAssembly(); + PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy); + + var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract); + + if (types != null) + { + foreach (var type in types) + { + try + { + var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type); + factory.LoadTypeFactories(); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name); + } + } + } + } + + /// + /// A dictionary of factory methods, keyed by config types, added by plugins. + /// These methods are looked up and called by GetDevice in this class. + /// + static Dictionary FactoryMethods = + new Dictionary(StringComparer.OrdinalIgnoreCase); + + /// + /// Adds a plugin factory method + /// + /// + /// + public static void AddFactoryForType(string typeName, Func method) + { + Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); + } + + public static void AddFactoryForType(string typeName, string description, CType cType, Func method) + { + Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + + if(FactoryMethods.ContainsKey(typeName)) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in DeviceFactory", typeName); + return; + } + + var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method }; + DeviceFactory.FactoryMethods.Add(typeName, wrapper); } private static void CheckForSecrets(IEnumerable obj) @@ -156,44 +156,53 @@ namespace PepperDash.Essentials.Core Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message); Debug.Console(2, "{0}", ex.StackTrace); + + if (ex.InnerException == null) + { + return null; + } + + Debug.Console(0, Debug.ErrorLogLevel.Error, "Inner exception while creating device {0}: {1}", dc.Key, + ex.InnerException.Message); + Debug.Console(2, "{0}", ex.InnerException.StackTrace); return null; } } - /// - /// Prints the type names and associated metadata from the FactoryMethods collection. - /// - /// - public static void GetDeviceFactoryTypes(string filter) - { - Dictionary types = new Dictionary(); - - if (!string.IsNullOrEmpty(filter)) - { - types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value); - } - else - { - types = FactoryMethods; - } - - Debug.Console(0, "Device Types:"); - - foreach (var type in types.OrderBy(t => t.Key)) - { - var description = type.Value.Description; - var cType = "Not Specified by Plugin"; - - if(type.Value.CType != null) - { - cType = type.Value.CType.FullName; - } - - Debug.Console(0, - @"Type: '{0}' - CType: '{1}' - Description: {2}", type.Key, cType, description); - } - } - } + /// + /// Prints the type names and associated metadata from the FactoryMethods collection. + /// + /// + public static void GetDeviceFactoryTypes(string filter) + { + Dictionary types = new Dictionary(); + + if (!string.IsNullOrEmpty(filter)) + { + types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value); + } + else + { + types = FactoryMethods; + } + + Debug.Console(0, "Device Types:"); + + foreach (var type in types.OrderBy(t => t.Key)) + { + var description = type.Value.Description; + var cType = "Not Specified by Plugin"; + + if(type.Value.CType != null) + { + cType = type.Value.CType.FullName; + } + + Debug.Console(0, + @"Type: '{0}' + CType: '{1}' + Description: {2}", type.Key, cType, description); + } + } + } } \ No newline at end of file From 7114e60c046f99f056abc306c4aaecf1d6d21234 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 30 Jul 2021 16:59:32 -0600 Subject: [PATCH 299/480] feat(RoomCombining): #742 Updates EssentialsTouchpanelController Will now switch room the TP is linked to based on room combination scenario --- .../UI/EssentialsTouchpanelController.cs | 293 ++++++++++-------- .../EssentialsPanelMainInterfaceDriver.cs | 33 +- .../UIDrivers/ScreenSaverController.cs | 17 +- .../Room/Combining/EssentialsRoomCombiner.cs | 14 +- .../Touchpanels/TriListExtensions.cs | 21 ++ 5 files changed, 248 insertions(+), 130 deletions(-) diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index b295cf95..6d13614c 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -29,7 +29,14 @@ namespace PepperDash.Essentials : base(key, name) { Panel = tsw; - tsw.LoadSmartObjects(sgdPath); + + if (!string.IsNullOrEmpty(sgdPath)) + Panel.LoadSmartObjects(sgdPath); + else + Debug.Console(1, this, "No SGD file path defined"); + + + tsw.SigChange += Panel_SigChange; } @@ -39,7 +46,7 @@ namespace PepperDash.Essentials Panel = dge; if (!string.IsNullOrEmpty(sgdPath)) - dge.LoadSmartObjects(sgdPath); + Panel.LoadSmartObjects(sgdPath); else Debug.Console(1, this, "No SGD file path defined"); @@ -130,37 +137,191 @@ namespace PepperDash.Essentials AddPostActivationAction(() => { // Check for IEssentialsRoomCombiner in DeviceManager and if found, subscribe to its event - var roomCombiner = DeviceManager.AllDevices.FirstOrDefault((d) => d is IEssentialsRoomCombiner) as IEssentialsRoomCombiner; if (roomCombiner != null) { + // Subscribe to the even roomCombiner.RoomCombinationScenarioChanged += new EventHandler(roomCombiner_RoomCombinationScenarioChanged); + + // Connect to the initial roomKey + if (roomCombiner.CurrentScenario != null) + { + // Use the current scenario + DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario); + } + else + { + // Current Scenario not yet set. Use default + SetupPanelDrivers(_propertiesConfig.DefaultRoomKey); + } + } + else + { + // No room combiner, use the default key + SetupPanelDrivers(_propertiesConfig.DefaultRoomKey); } }); - } void roomCombiner_RoomCombinationScenarioChanged(object sender, EventArgs e) { var roomCombiner = sender as IEssentialsRoomCombiner; + DetermineRoomKeyFromScenario(roomCombiner.CurrentScenario); + } + + /// + /// Determines the room key to use based on the scenario + /// + /// + void DetermineRoomKeyFromScenario(IRoomCombinationScenario scenario) + { string newRoomKey = null; - if (roomCombiner.CurrentScenario.UiMap.ContainsKey(Key)) + if (scenario.UiMap.ContainsKey(Key)) { - newRoomKey = roomCombiner.CurrentScenario.UiMap[Key]; + newRoomKey = scenario.UiMap[Key]; } - else if (roomCombiner.CurrentScenario.UiMap.ContainsKey(_propertiesConfig.DefaultRoomKey)) + else if (scenario.UiMap.ContainsKey(_propertiesConfig.DefaultRoomKey)) { - newRoomKey = roomCombiner.CurrentScenario.UiMap[_propertiesConfig.DefaultRoomKey]; + newRoomKey = scenario.UiMap[_propertiesConfig.DefaultRoomKey]; + } + + SetupPanelDrivers(newRoomKey); + } + + + /// + /// Sets up drivers and links them to the room specified + /// + /// key of room to link the drivers to + void SetupPanelDrivers(string roomKey) + { + // Clear out any existing actions + Panel.ClearAllSigActions(); + + Debug.Console(0, this, "Linking TP '{0}' to Room '{1}'", Key, roomKey); + + var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, _propertiesConfig); + // Then the sub drivers + + // spin up different room drivers depending on room type + var room = DeviceManager.GetDeviceForKey(roomKey); + if (room is IEssentialsHuddleSpaceRoom) + { + // Screen Saver Driver + + mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _propertiesConfig); + + // Header Driver + Debug.Console(0, this, "Adding header driver"); + mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _propertiesConfig); + + // AV Driver + Debug.Console(0, this, "Adding huddle space AV driver"); + var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, _propertiesConfig); + avDriver.DefaultRoomKey = roomKey; + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom; + + // Environment Driver + if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) + { + Debug.Console(0, this, "Adding environment driver"); + mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _propertiesConfig); + + mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); + } + + mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); + + if (Panel is TswFt5ButtonSystem) + { + var tsw = Panel as TswFt5ButtonSystem; + // Wire up hard keys + tsw.Power.UserObject = new Action(b => { if (!b) avDriver.PowerButtonPressed(); }); + if (mainDriver.EnvironmentDriver != null) + tsw.Lights.UserObject = new Action(b => + { + if (!b) + { + mainDriver.EnvironmentDriver.Toggle(); + } + }); + tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); + tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); + } + } + else if (room is IEssentialsHuddleVtc1Room) + { + Debug.Console(0, this, "Adding huddle space VTC AV driver"); + + // Screen Saver Driver + mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _propertiesConfig); + + // Header Driver + mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _propertiesConfig); + + // AV Driver + var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, _propertiesConfig); + + var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(Panel, avDriver, + (room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); + avDriver.SetVideoCodecDriver(codecDriver); + avDriver.DefaultRoomKey = roomKey; + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room; + + // Environment Driver + if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) + { + Debug.Console(0, this, "Adding environment driver"); + mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _propertiesConfig); + + mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); + } + + mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); + + + if (Panel is TswFt5ButtonSystem) + { + var tsw = Panel as TswFt5ButtonSystem; + // Wire up hard keys + tsw.Power.UserObject = new Action(b => { if (!b) avDriver.EndMeetingPress(); }); + if (mainDriver.EnvironmentDriver != null) + tsw.Lights.UserObject = new Action(b => + { + if (!b) + { + mainDriver.EnvironmentDriver.Toggle(); + } + }); + tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); + tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); + } + + LoadAndShowDriver(mainDriver); + } + else + { + Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", roomKey); } - // TODO: } public void LoadAndShowDriver(PanelDriverBase driver) { + if (PanelDriver != null) + { + var mainDriver = PanelDriver as EssentialsPanelMainInterfaceDriver; + if (mainDriver != null) + { + mainDriver.Dispose(); + } + } + PanelDriver = driver; driver.Show(); } @@ -171,7 +332,6 @@ namespace PepperDash.Essentials PanelDriver.BackButtonPressed(); } - void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) { // If the sig is transitioning on, mark it in case it was home button that transitioned it @@ -248,119 +408,6 @@ namespace PepperDash.Essentials var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, dc.Type, props, comm.IpIdInt); - panelController.AddPostActivationAction(() => - { - var mainDriver = new EssentialsPanelMainInterfaceDriver(panelController.Panel, props); - // Then the sub drivers - - // spin up different room drivers depending on room type - var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey); - if (room is IEssentialsHuddleSpaceRoom) - { - // Screen Saver Driver - mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); - - // Header Driver - Debug.Console(0, panelController, "Adding header driver"); - mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); - - // AV Driver - Debug.Console(0, panelController, "Adding huddle space AV driver"); - var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); - avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom; - - // Environment Driver - if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) - { - Debug.Console(0, panelController, "Adding environment driver"); - mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); - - mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); - } - - mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); - - panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. - - if (panelController.Panel is TswFt5ButtonSystem) - { - var tsw = panelController.Panel as TswFt5ButtonSystem; - // Wire up hard keys - tsw.Power.UserObject = new Action(b => { if (!b) avDriver.PowerButtonPressed(); }); - //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); - if (mainDriver.EnvironmentDriver != null) - tsw.Lights.UserObject = new Action(b => - { - if (!b) - { - //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); - mainDriver.EnvironmentDriver.Toggle(); - } - }); - tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); - tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); - } - } - else if (room is IEssentialsHuddleVtc1Room) - { - Debug.Console(0, panelController, "Adding huddle space VTC AV driver"); - - // Screen Saver Driver - mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props); - - // Header Driver - mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props); - - // AV Driver - var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props); - - var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, - (room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); - avDriver.SetVideoCodecDriver(codecDriver); - avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; - avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room; - - // Environment Driver - if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0) - { - Debug.Console(0, panelController, "Adding environment driver"); - mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props); - - mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment); - } - - mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom); - - panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted. - - if (panelController.Panel is TswFt5ButtonSystem) - { - var tsw = panelController.Panel as TswFt5ButtonSystem; - // Wire up hard keys - tsw.Power.UserObject = new Action(b => { if (!b) avDriver.EndMeetingPress(); }); - //tsw.Home.UserObject = new Action(b => { if (!b) HomePressed(); }); - if (mainDriver.EnvironmentDriver != null) - tsw.Lights.UserObject = new Action(b => - { - if (!b) - { - //mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin); - mainDriver.EnvironmentDriver.Toggle(); - } - }); - tsw.Up.UserObject = new Action(avDriver.VolumeUpPress); - tsw.Down.UserObject = new Action(avDriver.VolumeDownPress); - } - } - else - { - Debug.Console(0, panelController, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey); - } - }); - return panelController; } } diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs index 9b92fc41..2b787063 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsPanelMainInterfaceDriver.cs @@ -11,7 +11,7 @@ namespace PepperDash.Essentials /// /// /// - public class EssentialsPanelMainInterfaceDriver : PanelDriverBase, IHasScreenSaverController + public class EssentialsPanelMainInterfaceDriver : PanelDriverBase, IHasScreenSaverController, IDisposable { CTimer InactivityTimer; @@ -69,6 +69,35 @@ namespace PepperDash.Essentials } } + #region IDisposable Members + + public void Dispose() + { + var avDriver = AvDriver as PanelDriverBase; + if (avDriver != null) + { + avDriver.Hide(); + } + if (ScreenSaverController != null) + { + ScreenSaverController.Dispose(); + } + if (HeaderDriver != null) + { + HeaderDriver.Hide(); + } + if (EnvironmentDriver != null) + { + EnvironmentDriver.Hide(); + } + if (CurrentChildDriver != null) + { + CurrentChildDriver.Hide(); + } + } + + #endregion + void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args) { @@ -130,7 +159,7 @@ namespace PepperDash.Essentials if(CurrentChildDriver != null) CurrentChildDriver.BackButtonPressed(); } - } + } public interface IHasScreenSaverController { diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs index e6d60d5b..afced26e 100644 --- a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -12,7 +12,7 @@ namespace PepperDash.Essentials /// /// Driver responsible for controlling the screenshaver showing the client logo, MC connection information and QR Code. Moves the elements around to prevent screen burn in /// - public class ScreenSaverController : PanelDriverBase + public class ScreenSaverController : PanelDriverBase, IDisposable { /// @@ -65,7 +65,7 @@ namespace PepperDash.Essentials public override void Hide() { - Debug.Console(1, "Hiding ScreenSaverController"); + Debug.Console(2, "Hiding ScreenSaverController"); if (PositionTimer != null) { @@ -117,7 +117,7 @@ namespace PepperDash.Essentials CurrentPositionIndex = 0; } - Debug.Console(1, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); + //Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); } // @@ -129,9 +129,18 @@ namespace PepperDash.Essentials void ClearAllPositions() { - Debug.Console(1, "Hiding all screensaver positions"); + Debug.Console(2, "Hiding all screensaver positions"); PositionInterlock.HideAndClear(); } + + #region IDisposable Members + + public void Dispose() + { + Hide(); + } + + #endregion } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index a0284dc1..d9886e70 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -167,7 +167,7 @@ namespace PepperDash.Essentials.Core { return _currentScenario; } - set + private set { if (value != _currentScenario) { @@ -227,9 +227,11 @@ namespace PepperDash.Essentials.Core // Get the scenario var scenario = RoomCombinationScenarios.FirstOrDefault((s) => s.Key.Equals(scenarioKey)); + // Set the parition states from the scenario manually if (scenario != null) { + Debug.Console(0, this, "Manually setting scenario to '{0}'", scenario.Key); foreach (var partitionState in scenario.PartitionStates) { var partition = Partitions.FirstOrDefault((p) => p.Key.Equals(partitionState.PartitionKey)); @@ -238,15 +240,25 @@ namespace PepperDash.Essentials.Core { if (partitionState.PartitionPresent) { + Debug.Console(0, this, "Manually setting state to Present for: '{0}'", partition.Key); partition.SetPartitionStatePresent(); } else { + Debug.Console(0, this, "Manually setting state to Not Present for: '{0}'", partition.Key); partition.SetPartitionStateNotPresent(); } } + else + { + Debug.Console(1, this, "Unable to find partition with key: '{0}'", partitionState.PartitionKey); + } } } + else + { + Debug.Console(1, this, "Unable to find scenario with key: '{0}'", scenarioKey); + } } #endregion diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/TriListExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/TriListExtensions.cs index d9cadb24..bfbb73f0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/TriListExtensions.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/TriListExtensions.cs @@ -206,6 +206,27 @@ namespace PepperDash.Essentials.Core return ClearSigAction(tl.StringOutput[sigNum]) as StringOutputSig; } + /// + /// Clears all actions on all sigs + /// + public static void ClearAllSigActions(this BasicTriList t1) + { + foreach (var sig in t1.BooleanOutput) + { + ClearSigAction(sig); + } + + foreach (var sig in t1.UShortOutput) + { + ClearSigAction(sig); + } + + foreach (var sig in t1.StringOutput) + { + ClearSigAction(sig); + } + } + /// /// Helper method to set the value of a bool Sig on TriList /// From 77672237e63b325b13e0ded78ef6c84733bcc664 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 30 Jul 2021 17:27:38 -0600 Subject: [PATCH 300/480] Adds some debug comments to assist in debugging --- PepperDashEssentials/UIDrivers/ScreenSaverController.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs index afced26e..49357868 100644 --- a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -51,6 +51,8 @@ namespace PepperDash.Essentials public override void Show() { + Debug.Console(2, "Showing ScreenSaverController"); + if (_parent.AvDriver != null) { _parent.AvDriver.PopupInterlock.ShowInterlocked(UIBoolJoin.MCScreenSaverVisible); @@ -86,6 +88,8 @@ namespace PepperDash.Essentials void StartPositionTimer() { + Debug.Console(2, "Starting Position Timer"); + if (PositionTimer == null) { PositionTimer = new CTimer((o) => PositionTimerExpired(), PositionTimeoutMs); @@ -117,7 +121,7 @@ namespace PepperDash.Essentials CurrentPositionIndex = 0; } - //Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); + Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); } // From 864e0675ea589b0d70db4aade804ebfdf674a430 Mon Sep 17 00:00:00 2001 From: Trevor Payne <44117050+TrevorPayne@users.noreply.github.com> Date: Mon, 2 Aug 2021 10:34:41 -0500 Subject: [PATCH 301/480] Resolves #769 Fix issues with large dm frame instantiation --- .../Chassis/DmBladeChassisController.cs | 380 +++++++++++------- 1 file changed, 238 insertions(+), 142 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index 3a4f55c0..96cc8097 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -16,7 +16,8 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.DM.Config; -namespace PepperDash.Essentials.DM { +namespace PepperDash.Essentials.DM +{ /// /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// @@ -75,8 +76,10 @@ namespace PepperDash.Essentials.DM { /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now /// public static DmBladeChassisController GetDmChassisController(string key, string name, - string type, DMChassisPropertiesConfig properties) { - try { + string type, DMChassisPropertiesConfig properties) + { + try + { type = type.ToLower(); uint ipid = properties.Control.IpIdInt; @@ -85,7 +88,8 @@ namespace PepperDash.Essentials.DM { else if (type == "dmmd128x128") { chassis = new DmMd128x128(ipid, Global.ControlSystem); } - if (chassis == null) { + if (chassis == null) + { return null; } @@ -93,11 +97,13 @@ namespace PepperDash.Essentials.DM { // add the cards and port names foreach (var kvp in properties.InputSlots) controller.AddInputBlade(kvp.Value, kvp.Key); - foreach (var kvp in properties.OutputSlots) { + foreach (var kvp in properties.OutputSlots) + { controller.AddOutputBlade(kvp.Value, kvp.Key); } - foreach (var kvp in properties.VolumeControls) { + foreach (var kvp in properties.VolumeControls) + { // get the card // check it for an audio-compatible type // make a something-something that will make it work @@ -123,7 +129,8 @@ namespace PepperDash.Essentials.DM { controller.PropertiesConfig = properties; return controller; } - catch (System.Exception e) { + catch (System.Exception e) + { Debug.Console(0, "Error creating DM chassis:\r{0}", e); } return null; @@ -137,7 +144,8 @@ namespace PepperDash.Essentials.DM { /// /// public DmBladeChassisController(string key, string name, BladeSwitch chassis) - : base(key, name, chassis) { + : base(key, name, chassis) + { Chassis = chassis; InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); @@ -161,68 +169,87 @@ namespace PepperDash.Essentials.DM { InputCardHdcpCapabilityFeedbacks = new Dictionary(); InputCardHdcpCapabilityTypes = new Dictionary(); - for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) { + for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) + { var tempX = x; - if (Chassis.Outputs[tempX] != null) { - VideoOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX] != null) + { + VideoOutputFeedbacks[tempX] = new IntFeedback(() => + { if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; } else { return 0; }; }); - OutputNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Outputs[tempX].NameFeedback != null) { + OutputNameFeedbacks[tempX] = new StringFeedback(() => + { + if (Chassis.Outputs[tempX].NameFeedback != null) + { return Chassis.Outputs[tempX].NameFeedback.StringValue; } - else { + else + { return ""; } }); - OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Outputs[tempX].VideoOutFeedback != null) { + OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => + { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + { return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; } - else { + else + { return ""; } }); - OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { + OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => + { //if (Chassis.Outputs[tempX].Endpoint != null) // return Chassis.Outputs[tempX].Endpoint.IsOnline; //else - return Chassis.Outputs[tempX].EndpointOnlineFeedback; + return Chassis.Outputs[tempX].EndpointOnlineFeedback; }); } - if (Chassis.Inputs[tempX] != null) { - UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Inputs[tempX] != null) + { + UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => + { if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; } else { return 0; }; }); - VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { + VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => + { if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; else return false; }); - InputNameFeedbacks[tempX] = new StringFeedback(() => { - if (Chassis.Inputs[tempX].NameFeedback != null) { + InputNameFeedbacks[tempX] = new StringFeedback(() => + { + if (Chassis.Inputs[tempX].NameFeedback != null) + { return Chassis.Inputs[tempX].NameFeedback.StringValue; } - else { + else + { return ""; } }); - InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { + InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => + { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); - InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => { + InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => + { var inputCard = Chassis.Inputs[tempX]; - if (inputCard.Card is DmHdmi4kInputBladeCard) { + if (inputCard.Card is DmHdmi4kInputBladeCard) + { InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; if ((inputCard.Card as DmHdmi4kInputBladeCard).Hdmi4kInput.HdcpSupportOnFeedback.BoolValue) @@ -231,7 +258,8 @@ namespace PepperDash.Essentials.DM { return 0; } - if (inputCard.Card is DmC4kInputBladeCard) { + if (inputCard.Card is DmC4kInputBladeCard) + { InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; if ((inputCard.Card as DmC4kInputBladeCard).DmInput.HdcpCapabilityFeedback.Equals(eHdcpCapabilityType.HdcpSupportOff)) @@ -252,45 +280,56 @@ namespace PepperDash.Essentials.DM { /// /// /// - public void AddInputBlade(string type, uint number) { + public void AddInputBlade(string type, uint number) + { Debug.Console(2, this, "Adding input blade '{0}', slot {1}", type, number); type = type.ToLower(); - if (type == "dmb4kihd") { + if (type == "dmb4kihd") + { var inputBlade = new Dmb4kIHd(number, this.Chassis); - foreach (var item in inputBlade.Inputs) { + foreach (var item in inputBlade.Inputs) + { var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput; var cecPort = card as ICec; AddHdmiInBladePorts(item.Number, cecPort); } } - else if (type == "dmb4kihddnt") { + else if (type == "dmb4kihddnt") + { var inputBlade = new Dmb4kIHd(number, this.Chassis); - foreach (var item in inputBlade.Inputs) { + foreach (var item in inputBlade.Inputs) + { var card = (item.Card as DmHdmi4kInputBladeCard).Hdmi4kInput; var cecPort = card as ICec; AddHdmiInBladePorts(item.Number, cecPort); } } - else if (type == "dmb4kic") { + else if (type == "dmb4kic") + { var inputBlade = new Dmb4kIC(number, this.Chassis); - foreach (var item in inputBlade.Inputs) { + foreach (var item in inputBlade.Inputs) + { AddDmInBladePorts(item.Number); } } - else if (type == "dmbis") { + else if (type == "dmbis") + { var inputBlade = new DmbIS(number, this.Chassis); - foreach (var item in inputBlade.Inputs) { + foreach (var item in inputBlade.Inputs) + { AddDmInMmFiberPorts(item.Number); } } - else if (type == "dmbis2") { + else if (type == "dmbis2") + { var inputBlade = new DmbIS2(number, this.Chassis); - foreach (var item in inputBlade.Inputs) { + foreach (var item in inputBlade.Inputs) + { AddDmInSmFiberPorts(item.Number); } } @@ -304,22 +343,26 @@ namespace PepperDash.Essentials.DM { { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } + } - void AddHdmiInBladePorts(uint number, ICec cecPort) { + void AddHdmiInBladePorts(uint number, ICec cecPort) + { AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); } - void AddDmInBladePorts(uint number) { + void AddDmInBladePorts(uint number) + { AddInputPortWithDebug(number, "dmCIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); } - void AddDmInMmFiberPorts(uint number) { + void AddDmInMmFiberPorts(uint number) + { AddInputPortWithDebug(number, "dmMmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); } - void AddDmInSmFiberPorts(uint number) { + void AddDmInSmFiberPorts(uint number) + { AddInputPortWithDebug(number, "dmSmIn", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); } @@ -328,64 +371,81 @@ namespace PepperDash.Essentials.DM { /// /// /// - public void AddOutputBlade(string type, uint number) { + public void AddOutputBlade(string type, uint number) + { type = type.ToLower(); Debug.Console(2, this, "Adding output blade '{0}', slot {1}", type, number); - if (type == "dmb4kohd") { + if (type == "dmb4kohd") + { var outputBlade = new Dmb4KOHD(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddHdmiOutBladePorts(item.Number); } } - else if (type == "dmb4kohddnt") { + else if (type == "dmb4kohddnt") + { var outputBlade = new Dmb4KOHD(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddHdmiOutBladePorts(item.Number); } } - else if (type == "dmb4koc") { + else if (type == "dmb4koc") + { var outputBlade = new Dmb4KOC(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddDmOutBladePorts(item.Number); } } - else if (type == "dmb4koc") { + else if (type == "dmb4koc") + { var outputBlade = new Dmb4KOC(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddDmOutBladePorts(item.Number); } } - else if (type == "dmbos") { + else if (type == "dmbos") + { var outputBlade = new DmbOS(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddDmOutMmFiberBladePorts(item.Number); } } - else if (type == "dmbos2") { + else if (type == "dmbos2") + { var outputBlade = new DmbOS2(number, Chassis); - foreach (var item in outputBlade.Outputs) { + foreach (var item in outputBlade.Outputs) + { AddDmOutSmFiberBladePorts(item.Number); } } } - void AddHdmiOutBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]); + void AddHdmiOutBladePorts(uint number) + { + AddOutputPortWithDebug(number, "hdmiOut", eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]); } - void AddDmOutBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]); + void AddDmOutBladePorts(uint number) + { + AddOutputPortWithDebug(number, "dmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]); } - void AddDmOutMmFiberBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]); + void AddDmOutMmFiberBladePorts(uint number) + { + AddOutputPortWithDebug(number, "dmMmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]); } - void AddDmOutSmFiberBladePorts(uint number) { - AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]); + void AddDmOutSmFiberBladePorts(uint number) + { + AddOutputPortWithDebug(number, "dmSmOut", eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]); } @@ -417,23 +477,44 @@ namespace PepperDash.Essentials.DM { } - /// - /// Adds OutputPort - /// - void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { + + /*void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { var portKey = string.Format("{0}--{1}", cardName, portName); Debug.Console(2, this, "Adding output port '{0}'", portKey); OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this) { FeedbackMatchObject = Chassis.Outputs[(uint)selector] }); + }*/ + + /// + /// Adds OutputPort + /// + void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) + { + try + { + var portKey = string.Format("outputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding output port '{0}'", portKey); + var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this) + { + FeedbackMatchObject = Chassis.Outputs[cardNum] + }; + OutputPorts.Add(outputPort); + } + catch (Exception ex) + { + Debug.Console(0, this, "Exception : {0}", ex); + } + } /// /// /// - void AddVolumeControl(uint number, Audio.Output audio) { + void AddVolumeControl(uint number, Audio.Output audio) + { VolumeControls.Add(number, new DmCardAudioOutputController(audio)); } @@ -443,35 +524,43 @@ namespace PepperDash.Essentials.DM { //} - void Chassis_DMInputChange(Switch device, DMInputEventArgs args) { + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { - switch (args.EventId) { - case DMInputEventIds.EndpointOnlineEventId: { + switch (args.EventId) + { + case DMInputEventIds.EndpointOnlineEventId: + { Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); break; } - case DMInputEventIds.OnlineFeedbackEventId: { + case DMInputEventIds.OnlineFeedbackEventId: + { Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); break; } - case DMInputEventIds.VideoDetectedEventId: { + case DMInputEventIds.VideoDetectedEventId: + { Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); VideoInputSyncFeedbacks[args.Number].FireUpdate(); break; } - case DMInputEventIds.InputNameEventId: { + case DMInputEventIds.InputNameEventId: + { Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); InputNameFeedbacks[args.Number].FireUpdate(); break; } - case DMInputEventIds.HdcpCapabilityFeedbackEventId: { + case DMInputEventIds.HdcpCapabilityFeedbackEventId: + { Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate(); break; } - default: { + default: + { Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); break; } @@ -487,74 +576,74 @@ namespace PepperDash.Essentials.DM { switch (args.EventId) { case DMOutputEventIds.VolumeEventId: - { - if (VolumeControls.ContainsKey(output)) { - VolumeControls[args.Number].VolumeEventFromChassis(); + if (VolumeControls.ContainsKey(output)) + { + VolumeControls[args.Number].VolumeEventFromChassis(); + } + break; } - break; - } case DMOutputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, - "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}", - args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); - if (Chassis.Outputs[output].Endpoint != null) + { Debug.Console(2, this, - "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}", - args.Number, Chassis.Outputs[output].Endpoint.IsOnline); + "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}", + args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); + if (Chassis.Outputs[output].Endpoint != null) + Debug.Console(2, this, + "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}", + args.Number, Chassis.Outputs[output].Endpoint.IsOnline); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } case DMOutputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", - args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } + { + Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", + args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } case DMOutputEventIds.VideoOutEventId: - { - - var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number; - - Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name, - inputNumber, output); - - if (VideoOutputFeedbacks.ContainsKey(output)) { - var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback); - var localOutputPort = - OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]); + + var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number; + + Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name, + inputNumber, output); + + if (VideoOutputFeedbacks.ContainsKey(output)) + { + var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback); + var localOutputPort = + OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]); - VideoOutputFeedbacks[output].FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs(output, - inputNumber, - localOutputPort, - localInputPort, - eRoutingSignalType.AudioVideo)); + VideoOutputFeedbacks[output].FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs(output, + inputNumber, + localOutputPort, + localInputPort, + eRoutingSignalType.AudioVideo)); + } + if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) + { + OutputVideoRouteNameFeedbacks[output].FireUpdate(); + } + break; } - if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) - { - OutputVideoRouteNameFeedbacks[output].FireUpdate(); - } - break; - } case DMOutputEventIds.OutputNameEventId: - { - Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); - OutputNameFeedbacks[output].FireUpdate(); - break; - } + { + Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); + OutputNameFeedbacks[output].FireUpdate(); + break; + } default: - { - Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", - args.Number, args.EventId); - break; - } + { + Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", + args.Number, args.EventId); + break; + } } } @@ -564,7 +653,8 @@ namespace PepperDash.Essentials.DM { /// /// /// - void StartOffTimer(PortNumberType pnt) { + void StartOffTimer(PortNumberType pnt) + { if (RouteOffTimers.ContainsKey(pnt)) return; RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime); @@ -572,8 +662,10 @@ namespace PepperDash.Essentials.DM { // Send out sigs when coming online - void IsOnline_OutputChange(object sender, EventArgs e) { - if (IsOnline.BoolValue) { + void IsOnline_OutputChange(object sender, EventArgs e) + { + if (IsOnline.BoolValue) + { Chassis.EnableUSBBreakaway.BoolValue = true; if (InputNames != null) @@ -587,12 +679,13 @@ namespace PepperDash.Essentials.DM { #region IRouting Members - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) { + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) + { Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); var input = inputSelector as DMInput; // Cast can sometimes fail var output = outputSelector as DMOutput; - + if (output == null) { @@ -605,11 +698,14 @@ namespace PepperDash.Essentials.DM { // Check to see if there's an off timer waiting on this and if so, cancel var key = new PortNumberType(output, sigType); - if (input == null) { + if (input == null) + { StartOffTimer(key); } - else { - if (RouteOffTimers.ContainsKey(key)) { + else + { + if (RouteOffTimers.ContainsKey(key)) + { Debug.Console(2, this, "{0} cancelling route off due to new source", output); RouteOffTimers[key].Stop(); RouteOffTimers.Remove(key); @@ -671,7 +767,7 @@ namespace PepperDash.Essentials.DM { var ioSlotJoin = ioSlot - 1; // Control - trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort) ioSlot, eRoutingSignalType.Video)); + trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, o => ExecuteNumericSwitch(o, (ushort)ioSlot, eRoutingSignalType.Video)); if (TxDictionary.ContainsKey(ioSlot)) { From 0e41cafdadef2826ec49069aa2c151810744f689 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 2 Aug 2021 14:22:31 -0600 Subject: [PATCH 302/480] Adds some debug comments to assist in debugging --- .../UI/EssentialsTouchpanelController.cs | 2 ++ .../UIDrivers/ScreenSaverController.cs | 14 ++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 0c4e3b88..becba34c 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -71,6 +71,8 @@ namespace PepperDash.Essentials app.ParameterProjectName.Value = props.ProjectName; Panel = app; } + else if (type == "xpanel") + Panel = new XpanelForSmartGraphics(id, Global.ControlSystem); else if (type == "tsw550") Panel = new Tsw550(id, Global.ControlSystem); else if (type == "tsw552") diff --git a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs index 49357868..0f75e2a2 100644 --- a/PepperDashEssentials/UIDrivers/ScreenSaverController.cs +++ b/PepperDashEssentials/UIDrivers/ScreenSaverController.cs @@ -42,7 +42,7 @@ namespace PepperDash.Essentials PositionInterlock = new JoinedSigInterlock(parent.TriList); - var cmdName = String.Format("shwscrsvr-{0}", parent.TriList.ID); + var cmdName = String.Format("shwscrsvr-{0:X2}", parent.TriList.ID); CrestronConsole.AddNewConsoleCommand((o) => Show(), cmdName, "Shows Panel Screensaver", ConsoleAccessLevelEnum.AccessOperator); @@ -51,7 +51,7 @@ namespace PepperDash.Essentials public override void Show() { - Debug.Console(2, "Showing ScreenSaverController"); + Debug.Console(2, "Showing ScreenSaverController: {0:X2}", TriList.ID); if (_parent.AvDriver != null) { @@ -67,10 +67,11 @@ namespace PepperDash.Essentials public override void Hide() { - Debug.Console(2, "Hiding ScreenSaverController"); + Debug.Console(2, "Hiding ScreenSaverController: {0:X2}", TriList.ID); if (PositionTimer != null) { + Debug.Console(2, "Stopping PositionTimer: {0:X2}", TriList.ID); PositionTimer.Stop(); PositionTimer.Dispose(); PositionTimer = null; @@ -88,7 +89,7 @@ namespace PepperDash.Essentials void StartPositionTimer() { - Debug.Console(2, "Starting Position Timer"); + Debug.Console(2, "Starting Position Timer: {0:X2}", TriList.ID); if (PositionTimer == null) { @@ -121,7 +122,7 @@ namespace PepperDash.Essentials CurrentPositionIndex = 0; } - Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex); + Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0} ID: {1:X2}", CurrentPositionIndex, TriList.ID); } // @@ -133,7 +134,8 @@ namespace PepperDash.Essentials void ClearAllPositions() { - Debug.Console(2, "Hiding all screensaver positions"); + Debug.Console(2, "Hiding all screensaver positions: {0:X2}", TriList.ID); + PositionInterlock.HideAndClear(); } From 1696ef3ac11fea37202e6ab0d0f89e2a4d7f7608 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 2 Aug 2021 16:58:32 -0600 Subject: [PATCH 303/480] Adds LocalLayoutToggle() implementation and minor updates to UI Driver --- .../UI/JoinConstants/UIBoolJoin.cs | 4 ++ .../VC/EssentialsVideoCodecUiDriver.cs | 28 ++++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 46 ++++++++++++++++++- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index f8685671..aaecb81a 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -248,6 +248,10 @@ namespace PepperDash.Essentials /// public const uint VCCameraSelectBarWithoutModeVisible = 1261; + /// + /// 1262 + /// + public const uint VCCameraAutoModeIsOnFb = 1262; /// /// 1271 diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 6d5521a8..e95ab5e5 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -532,6 +532,7 @@ namespace PepperDash.Essentials.UIDrivers.VC CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn()); TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true; codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]); + codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCCameraAutoModeIsOnFb]); //TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction( //() => codecAutoCameras.CameraAutoModeOn()); @@ -857,19 +858,32 @@ namespace PepperDash.Essentials.UIDrivers.VC // Determines if codec is in manual camera control mode and shows feedback void ShowCameraManualMode() { + Debug.Console(2, "ShowCameraManualMode"); + var inManualMode = true; var codecOffCameras = Codec as IHasCameraOff; var codecAutoCameras = Codec as IHasCameraAutoMode; + var supportsAutoCameras = codecAutoCameras != null && Codec.SupportsCameraAutoMode; + if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue) { inManualMode = false; + + var codecCameraMute = Codec as IHasCameraMute; + + if (codecCameraMute != null) + { + codecCameraMute.CameraMuteOff(); + inManualMode = true; + + } } // Clear auto mode - if (codecAutoCameras != null ) + if (supportsAutoCameras) { if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue) { @@ -1213,7 +1227,7 @@ namespace PepperDash.Essentials.UIDrivers.VC var lc = Codec as IHasCodecLayouts; if (lc != null) { - TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent); + lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]); lc.LocalLayoutFeedback.OutputChange += (o,a) => { @@ -1226,14 +1240,24 @@ namespace PepperDash.Essentials.UIDrivers.VC var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec; if (cisco != null) { + TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent); // Cisco has min/max buttons that need special sauce cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges; //cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges; TriList.SetSigFalseAction(UIBoolJoin.VCMinMaxPress, cisco.MinMaxLayoutToggle); } + + var zoomRoom = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom; + if (zoomRoom != null) + { + TriList.BooleanInput[UIBoolJoin.VCLayoutToggleEnable].BoolValue = true; + TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggle); + } } + + } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index c2ec5c38..eb55db9f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants = new CodecParticipants(); - SupportsCameraOff = _props.SupportsCameraOff; + SupportsCameraOff = true; // Always allow turning off the camera for zoom calls? SupportsCameraAutoMode = _props.SupportsCameraAutoMode; PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc); @@ -2446,9 +2446,51 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void LocalLayoutToggle() { - throw new NotImplementedException(); + var currentLayout = LocalLayoutFeedback.StringValue; + + var eCurrentLayout = (int)Enum.Parse(typeof(zConfiguration.eLayoutStyle), currentLayout, true); + + var nextLayout = GetNextLayout(eCurrentLayout); + + if (nextLayout != zConfiguration.eLayoutStyle.None) + { + SetLayout(nextLayout); + } } + /// + /// Tries to get the next available layout + /// + /// + /// + private zConfiguration.eLayoutStyle GetNextLayout(int currentLayout) + { + if (AvailableLayouts == zConfiguration.eLayoutStyle.None) + { + return zConfiguration.eLayoutStyle.None; + } + + zConfiguration.eLayoutStyle nextLayout; + + if (((zConfiguration.eLayoutStyle)currentLayout & zConfiguration.eLayoutStyle.ShareAll) == zConfiguration.eLayoutStyle.ShareAll) + { + nextLayout = zConfiguration.eLayoutStyle.Gallery; + } + else + { + nextLayout = (zConfiguration.eLayoutStyle)(currentLayout << 1); + } + + if ((AvailableLayouts & nextLayout) == nextLayout) + { + return nextLayout; + } + else + { + return GetNextLayout((int)nextLayout); + } + } + public void LocalLayoutToggleSingleProminent() { throw new NotImplementedException(); From 5c3e1ca9151d23592ea65ba2d18c4e34c9c44874 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 3 Aug 2021 14:52:26 -0600 Subject: [PATCH 304/480] Updates IMobileControl to use IEssentialsRoom instead of EssentialsRoomBase again --- PepperDashEssentials/ControlSystem.cs | 8 ++++---- .../DeviceTypeInterfaces/IMobileControl.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index f3fcafab..aafb5b1e 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -483,7 +483,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else if (room is IEssentialsHuddleVtc1Room) { @@ -497,7 +497,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else if (room is EssentialsTechRoom) { @@ -509,7 +509,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else { @@ -530,7 +530,7 @@ namespace PepperDash.Essentials } - private static void CreateMobileControlBridge(EssentialsRoomBase room) + private static void CreateMobileControlBridge(IEssentialsRoom room) { var mobileControl = GetMobileControlDevice(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index c87e7865..a2dda43a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces /// public interface IMobileControl : IKeyed { - void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent); + void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent); void LinkSystemMonitorToAppServer(); } From 0867d08c5aa1058b4030caa2e6a4627303cbc72c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 4 Aug 2021 15:13:35 -0600 Subject: [PATCH 305/480] fix(MockVC): various fixes for local testing update MockVC and EssentialsVideoCodecUiDriver updates to Cisco classes to address some exceptions at startup with EssentialsVideoCodecUiDriver --- .../Properties/ControlSystem.cfg | 4 +-- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 8 ++--- .../VC/EssentialsVideoCodecUiDriver.cs | 19 ++++++---- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 35 +++++++++++-------- .../VideoCodec/CiscoCodec/xStatus.cs | 1 + .../VideoCodec/MockVC/MockVC.cs | 19 ++++++++-- .../MockVC/MockVcPropertiesConfig.cs | 6 ++++ 7 files changed, 62 insertions(+), 30 deletions(-) diff --git a/PepperDashEssentials/Properties/ControlSystem.cfg b/PepperDashEssentials/Properties/ControlSystem.cfg index d2c3b2c7..384bf949 100644 --- a/PepperDashEssentials/Properties/ControlSystem.cfg +++ b/PepperDashEssentials/Properties/ControlSystem.cfg @@ -1,7 +1,7 @@  - 192.168.10.1 -
auto 192.168.10.1
+ Test RMC3 +
auto 192.168.1.40;username crestron
Program01 Internal Flash
\ No newline at end of file diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index e9dc824b..d2978c44 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -448,10 +448,10 @@ namespace PepperDash.Essentials // and the LastMeetingDismissed != this meeting var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId); - Debug.Console(1, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", - CurrentRoom.OnFeedback.BoolValue, - LastMeetingDismissedId, - lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : ""); + //Debug.Console(1, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", + // CurrentRoom.OnFeedback.BoolValue, + // LastMeetingDismissedId, + // lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : ""); var meeting = meetings.LastOrDefault(m => m.Joinable); if (CurrentRoom.OnFeedback.BoolValue diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index e95ab5e5..9159381e 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -123,12 +123,6 @@ namespace PepperDash.Essentials.UIDrivers.VC codec.CallStatusChange += new EventHandler(Codec_CallStatusChange); - // If the codec is ready, then get the values we want, otherwise wait - if (Codec.IsReady) - Codec_IsReady(); - else - codec.IsReadyChange += (o, a) => Codec_IsReady(); - //InCall = new BoolFeedback(() => false); LocalPrivacyIsMuted = new BoolFeedback(() => false); @@ -199,6 +193,14 @@ namespace PepperDash.Essentials.UIDrivers.VC triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500, StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress); + // If the codec is ready, then get the values we want, otherwise wait + if (Codec.IsReady) + Codec_IsReady(); + else + codec.IsReadyChange += (o, a) => Codec_IsReady(); + + + } catch (Exception e) { @@ -518,7 +520,6 @@ namespace PepperDash.Essentials.UIDrivers.VC VCControlsInterlock.StatusChanged += new EventHandler(VCControlsInterlock_StatusChanged); - var codecOffCameras = Codec as IHasCameraOff; var supportsCameraOffMode = Codec.SupportsCameraOff; @@ -529,6 +530,7 @@ namespace PepperDash.Essentials.UIDrivers.VC if (codecAutoCameras != null && supportsAutoCameraMode) { + CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn()); TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true; codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]); @@ -558,6 +560,7 @@ namespace PepperDash.Essentials.UIDrivers.VC } }; + } // Manual button always visible @@ -569,6 +572,7 @@ namespace PepperDash.Essentials.UIDrivers.VC if (codecOffCameras != null && supportsCameraOffMode) { + TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true; codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]); CameraModeList.SetItemButtonAction(3, (b) => codecOffCameras.CameraOff()); @@ -596,6 +600,7 @@ namespace PepperDash.Essentials.UIDrivers.VC } }; + } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index bce321b9..660ec0f1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -352,8 +352,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CallHistory = new CodecCallHistory(); - - if (props.Favorites != null) + if (props.Favorites != null) { CallFavorites = new CodecCallFavorites(); CallFavorites.Favorites = props.Favorites; @@ -369,9 +368,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecSchedule = new CodecScheduleAwareness(); - //Set Feedback Actions - SetFeedbackActions(); - CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this); HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video, @@ -406,6 +402,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco BrandingEnabled = props.UiBranding.Enable; _brandingUrl = props.UiBranding.BrandingUrl; + + //Set Feedback Actions + SetFeedbackActions(); } private void SetFeedbackActions() @@ -429,11 +428,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } catch (Exception ex) { - Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex); + Debug.Console(0, this, "Error setting MainVideoMute Action: {0}", ex); if (ex.InnerException != null) { - Debug.Console(0, this, "Error setting MainVideuMute Action: {0}", ex); + Debug.Console(0, this, "Error setting MainVideoMute Action: {0}", ex); } } } @@ -1879,17 +1878,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { get { - if (CodecStatus.Status.SIP != null && CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value != null) + try { - return CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value; + if (CodecStatus.Status.SIP != null && CodecStatus.Status.SIP.AlternateURI != null) + { + return CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value; + } + else if (CodecStatus.Status.UserInterface != null && + CodecStatus.Status.UserInterface.ContactInfo != null && CodecStatus.Status.UserInterface.ContactInfo != null) + { + return CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value; + } + else + return string.Empty; } - else if (CodecStatus.Status.UserInterface != null && - CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value != null) + catch (Exception e) { - return CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value; - } - else + Debug.Console(2, "Error getting SipUri: {0}", e); return string.Empty; + } } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 8184289e..c1cd92cf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -327,6 +327,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public SpeakerTrack() { Status = new Status2(); + Availability = new Availability(); } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index ca199957..5d701f7b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -416,8 +416,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec m.MinutesBeforeMeeting = 5; m.Id = i.ToString(); m.Organizer = "Employee " + 1; - m.StartTime = DateTime.Now.AddMinutes(6).AddHours(i); - m.EndTime = DateTime.Now.AddHours(i).AddMinutes(16); + m.StartTime = DateTime.Now.AddMinutes(5).AddHours(i); + m.EndTime = DateTime.Now.AddHours(i).AddMinutes(50); m.Title = "Meeting " + i; m.Calls.Add(new Call() { Number = i + "meeting@fake.com"}); _CodecSchedule.Meetings.Add(m); @@ -583,6 +583,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec CameraAutoModeIsOnFeedback = new BoolFeedback(() => _CameraAutoModeIsOn); + SupportsCameraAutoMode = true; + CameraAutoModeIsOnFeedback.FireUpdate(); DeviceManager.AddDevice(internalCamera); @@ -590,7 +592,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec NearEndPresets = new List(15); // Fix the capacity to emulate Cisco - NearEndPresets = PropertiesConfig.Presets; + if (PropertiesConfig.Presets != null && PropertiesConfig.Presets.Count > 0) + { + NearEndPresets = PropertiesConfig.Presets; + } + else + { + for (int i = 1; i <= NearEndPresets.Capacity; i++) + { + var label = string.Format("Near End Preset {0}", i); + NearEndPresets.Add(new CodecRoomPreset(i, label, true, false)); + } + } FarEndRoomPresets = new List(15); // Fix the capacity to emulate Cisco diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs index 6a790af6..d294aff1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVcPropertiesConfig.cs @@ -18,5 +18,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec [JsonProperty("presets")] public List Presets { get; set; } + + public MockVcPropertiesConfig() + { + Favorites = new List(); + Presets = new List(); + } } } \ No newline at end of file From 397a5b1794e68c00f25e4902f65ae3413ea46382 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 5 Aug 2021 17:28:49 -0600 Subject: [PATCH 306/480] fix(CiscoSparkCodec): Solves exception when in SipUri getter --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 660ec0f1..ae740dbf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -1880,17 +1880,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { try { - if (CodecStatus.Status.SIP != null && CodecStatus.Status.SIP.AlternateURI != null) + if (CodecStatus.Status.SIP != null && !string.IsNullOrEmpty(CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value)) { return CodecStatus.Status.SIP.AlternateURI.Primary.URI.Value; } else if (CodecStatus.Status.UserInterface != null && - CodecStatus.Status.UserInterface.ContactInfo != null && CodecStatus.Status.UserInterface.ContactInfo != null) + CodecStatus.Status.UserInterface.ContactInfo != null && CodecStatus.Status.UserInterface.ContactInfo.ContactMethod != null) { return CodecStatus.Status.UserInterface.ContactInfo.ContactMethod[0].Number.Value; } else + { return string.Empty; + } } catch (Exception e) { From 22aea3089dec7528ec58a2757938c824d503c124 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 9 Aug 2021 14:41:31 -0600 Subject: [PATCH 307/480] #773 Adds some debug and sets the Capabilities value on ZoomRoomCamera Also updates RunRouteAction in EssentialsHuddleVtc1Room to still call down in to main RunRouteAction method if called with a sourceListKey --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 9 ++++-- .../VC/EssentialsVideoCodecUiDriver.cs | 12 +++++++- .../Display/InputInterfaces.cs | 28 +++++++++---------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 12 +++++++- .../VideoCodec/ZoomRoom/ZoomRoomCamera.cs | 2 ++ 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 5e7b5c37..b2450abe 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -454,7 +454,8 @@ namespace PepperDash.Essentials else { Debug.Console(1, this, "sourceListKey present but not yet implemented"); - throw new NotImplementedException(); + + RunRouteAction(routeKey, new Action(() => { })); } } @@ -471,7 +472,11 @@ namespace PepperDash.Essentials RunRouteAction(routeKey, successCallback); } else - throw new NotImplementedException(); + { + Debug.Console(1, this, "sourceListKey present but not yet implemented"); + + RunRouteAction(routeKey, successCallback); + } } /// diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index e95ab5e5..53efb69f 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -782,12 +782,14 @@ namespace PepperDash.Essentials.UIDrivers.VC if (camerasCodec != null && camerasCodec.SelectedCamera != null) { - + Debug.Console(2, "Attempting to map camera actions to selected camera: '{0}'", camerasCodec.SelectedCamera.Key); var dpad = CameraPtzPad; var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl; if (camera != null) { + + Debug.Console(2, "Selected camera is IHasCameraPtzControl"); if (camerasCodec.SelectedCamera.CanTilt) { dpad.SigUp.SetBoolSigAction((b) => @@ -852,6 +854,14 @@ namespace PepperDash.Essentials.UIDrivers.VC } } + else + { + Debug.Console(2, "Selected Camera is not IHasCameraPtzControl. No controls to map"); + } + } + else + { + Debug.Console(2, "Codec does not have cameras of selected camera is null"); } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/InputInterfaces.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/InputInterfaces.cs index d984f523..95070e1b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/InputInterfaces.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/InputInterfaces.cs @@ -1,17 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -namespace PepperDash.Essentials.Devices.Displays -{ - public interface IInputHdmi1 { void InputHdmi1(); } - public interface IInputHdmi2 { void InputHdmi2(); } - public interface IInputHdmi3 { void InputHdmi3(); } - public interface IInputHdmi4 { void InputHdmi4(); } - public interface IInputDisplayPort1 { void InputDisplayPort1(); } - public interface IInputDisplayPort2 { void InputDisplayPort2(); } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Displays +{ + public interface IInputHdmi1 { void InputHdmi1(); } + public interface IInputHdmi2 { void InputHdmi2(); } + public interface IInputHdmi3 { void InputHdmi3(); } + public interface IInputHdmi4 { void InputHdmi4(); } + public interface IInputDisplayPort1 { void InputDisplayPort1(); } + public interface IInputDisplayPort2 { void InputDisplayPort2(); } public interface IInputVga1 { void InputVga1(); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index eb55db9f..e2f5aaf4 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -281,7 +281,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var handler = CameraSelected; if (handler != null) { - handler(this, new CameraSelectedEventArgs(SelectedCamera)); + handler(this, new CameraSelectedEventArgs(_selectedCamera)); } } } @@ -2015,6 +2015,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom foreach (var cam in Status.Cameras) { + // Known Issue: + // Crestron UC engine systems seem to report an item in the cameras list that represnts the USB bridge device. + // If we know the name and it's reliably consistent, we could ignore it here... + + if (cam.Name.IndexOf("HD-CONV-USB") > -1) + { + // Skip this as it's the Crestron USB box, not a real camera + continue; + } + var camera = new ZoomRoomCamera(cam.id, cam.Name, this); Cameras.Add(camera); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs index 7a3abdaa..b0fc52fe 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomCamera.cs @@ -63,6 +63,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom : base(key, name) { ParentCodec = codec; + + Capabilities = eCameraCapabilities.Pan | eCameraCapabilities.Tilt | eCameraCapabilities.Zoom; } /// From cea1d2fcdd60f0d5d654fb6280291453204abae7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 9 Aug 2021 16:20:55 -0600 Subject: [PATCH 308/480] Updates to mute toggle for ZoomRoom --- .../EssentialsHuddleTechPageDriver.cs | 648 +++++++++--------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 15 +- 2 files changed, 337 insertions(+), 326 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs index b8e1dfd6..32d8ebe4 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddleTechPageDriver.cs @@ -1,326 +1,326 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; + +using PepperDash.Core; +using PepperDash.Essentials; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.SmartObjects; -using PepperDash.Essentials.Core.Touchpanels.Keyboards; -using PepperDash.Essentials.Devices.Displays; -using PepperDash.Essentials.Room.Config; - -namespace PepperDash.Essentials.UIDrivers -{ - public class EssentialsHuddleTechPageDriver : PanelDriverBase - { - /// - /// - /// - SmartObjectDynamicList MenuList; - /// - /// - /// - SubpageReferenceList StatusList; - /// - /// The list of display controls - /// - SubpageReferenceList DisplayList; - /// - /// References lines in the list against device instances - /// - Dictionary StatusListDeviceIndexes; - /// - /// - /// - JoinedSigInterlock PagesInterlock; - - /// - /// 1 - /// - public const uint JoinText = 1; - - CTimer PinAuthorizedTimer; - - EssentialsRoomTechConfig Config; - - StringBuilder PinEntryBuilder = new StringBuilder(4); - - bool IsAuthorized; - - SmartObjectNumeric PinKeypad; - - /// - /// - /// - /// - /// - public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config) - : base(trilist) - { - Config = config; - - PagesInterlock = new JoinedSigInterlock(trilist); - PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible); - - trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide); - - MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList], - true, 3100); - - MenuList.SetFeedback(1, true); // initial fb - ushort count = 0; - - MenuList.SetItemMainText(1, "System Status"); - MenuList.SetItemButtonAction(1, b => { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible); - MenuList.SetFeedback(1, true); - }); - - MenuList.SetItemMainText(2, "Display Controls"); - MenuList.SetItemButtonAction(2, b => { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible); - MenuList.SetFeedback(2, true); - }); - - count = 2; - - // Don't show panel setup on iPad or xpanel - if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button) - { - count++; - MenuList.SetItemMainText(count, "Panel Setup"); - MenuList.SetItemButtonAction(count, b => - { - if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible); - MenuList.SetFeedback(count, true); - }); - } - - MenuList.Count = count; - BuildStatusList(); - BuildDisplayList(); - SetupPinModal(); - } - - /// - /// - /// - public override void Show() - { - // divert to PIN if we need auth - if (IsAuthorized) - { - // Cancel the auth timer so we don't deauth after coming back in - if (PinAuthorizedTimer != null) - PinAuthorizedTimer.Stop(); - - TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true); - PagesInterlock.Show(); - base.Show(); - } - else - { - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true); - } - } - - /// - /// - /// - public override void Hide() - { - // Leave it authorized for 60 seconds. - if (IsAuthorized) - PinAuthorizedTimer = new CTimer(o => { - IsAuthorized = false; - PinAuthorizedTimer = null; - }, 60000); - TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false); - PagesInterlock.Hide(); - base.Hide(); - } - - /// - /// Wire up the keypad and buttons - /// - void SetupPinModal() - { - TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog); - PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true); - PinKeypad.Digit0.UserObject = new Action(b => { if (b)DialPinDigit('0'); }); - PinKeypad.Digit1.UserObject = new Action(b => { if (b)DialPinDigit('1'); }); - PinKeypad.Digit2.UserObject = new Action(b => { if (b)DialPinDigit('2'); }); - PinKeypad.Digit3.UserObject = new Action(b => { if (b)DialPinDigit('3'); }); - PinKeypad.Digit4.UserObject = new Action(b => { if (b)DialPinDigit('4'); }); - PinKeypad.Digit5.UserObject = new Action(b => { if (b)DialPinDigit('5'); }); - PinKeypad.Digit6.UserObject = new Action(b => { if (b)DialPinDigit('6'); }); - PinKeypad.Digit7.UserObject = new Action(b => { if (b)DialPinDigit('7'); }); - PinKeypad.Digit8.UserObject = new Action(b => { if (b)DialPinDigit('8'); }); - PinKeypad.Digit9.UserObject = new Action(b => { if (b)DialPinDigit('9'); }); - } - - /// - /// - /// - /// - void DialPinDigit(char d) - { - PinEntryBuilder.Append(d); - var len = PinEntryBuilder.Length; - SetPinDotsFeedback(len); - - // check it! - if (len == 4) - { - if (Config.Password == PinEntryBuilder.ToString()) - { - IsAuthorized = true; - SetPinDotsFeedback(0); - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); - Show(); - } - else - { - SetPinDotsFeedback(0); - TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true); - new CTimer(o => - { - TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false); - }, 1500); - } - - PinEntryBuilder.Remove(0, len); // clear it either way - } - } - - /// - /// Draws the dots as pin is entered - /// - /// - void SetPinDotsFeedback(int len) - { - TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1); - TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2); - TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3); - TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4); - - } - - /// - /// Does what it says - /// - void CancelPinDialog() - { - PinEntryBuilder.Remove(0, PinEntryBuilder.Length); - TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); - } - - - /// - /// - /// - void BuildStatusList() - { - StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3); - StatusListDeviceIndexes = new Dictionary(); - uint i = 0; - foreach (var d in DeviceManager.AllDevices) - { - // make sure it is both ICommunicationMonitor and a Device - var sd = d as ICommunicationMonitor; - if (sd == null) - continue; - var dd = sd as Device; - if(dd == null) - continue; - i++; - StatusList.StringInputSig(i, 1).StringValue = dd.Name; - StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status; - StatusListDeviceIndexes.Add(sd, i); - sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ; - } - StatusList.Count = (ushort)i; - } - - /// - /// Builds the list of display controls - /// - void BuildDisplayList() - { - DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3); - - var devKeys = ConfigReader.ConfigObject.Devices.Where(d => - d.Group.Equals("display", StringComparison.OrdinalIgnoreCase) - || d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase)) - .Select(dd => dd.Key); - var disps = DeviceManager.AllDevices.Where(d => - devKeys.Contains(d.Key)); - ushort i = 0; - foreach (var disp in disps) - { - var display = disp as DisplayBase; - if (display != null) - { - i++; - DisplayList.StringInputSig(i, 1).StringValue = display.Name; - DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn); - DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff); - if (display is TwoWayDisplayBase) - { - var powerOnSig = DisplayList.BoolInputSig(i, 1); - (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig); - - var powerOffSig = DisplayList.BoolInputSig(1, 2); - (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig); - } - DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() => - { if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); }); - DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() => - { if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); }); - DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() => - { if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); }); - //DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => - //{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); }); - DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => - { if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); }); - - - // Figure out some way to provide current input feedback - if (display is TwoWayDisplayBase) - { - (display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange; - } - } - - - } - - DisplayList.Count = i; - } - - - void CurrentInputFeedback_OutputChange(object sender, EventArgs e) - { - - } - - /// - /// - /// - void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e) - { - var c = sender as ICommunicationMonitor; - if (StatusListDeviceIndexes.ContainsKey(c)) - { - var i = StatusListDeviceIndexes[c]; - StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status; - } - } - } +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.SmartObjects; +using PepperDash.Essentials.Core.Touchpanels.Keyboards; +using PepperDash.Essentials.Devices.Displays; +using PepperDash.Essentials.Room.Config; + +namespace PepperDash.Essentials.UIDrivers +{ + public class EssentialsHuddleTechPageDriver : PanelDriverBase + { + /// + /// + /// + SmartObjectDynamicList MenuList; + /// + /// + /// + SubpageReferenceList StatusList; + /// + /// The list of display controls + /// + SubpageReferenceList DisplayList; + /// + /// References lines in the list against device instances + /// + Dictionary StatusListDeviceIndexes; + /// + /// + /// + JoinedSigInterlock PagesInterlock; + + /// + /// 1 + /// + public const uint JoinText = 1; + + CTimer PinAuthorizedTimer; + + EssentialsRoomTechConfig Config; + + StringBuilder PinEntryBuilder = new StringBuilder(4); + + bool IsAuthorized; + + SmartObjectNumeric PinKeypad; + + /// + /// + /// + /// + /// + public EssentialsHuddleTechPageDriver(BasicTriListWithSmartObject trilist, EssentialsRoomTechConfig config) + : base(trilist) + { + Config = config; + + PagesInterlock = new JoinedSigInterlock(trilist); + PagesInterlock.SetButDontShow(UIBoolJoin.TechSystemStatusVisible); + + trilist.SetSigFalseAction(UIBoolJoin.TechExitButton, Hide); + + MenuList = new SmartObjectDynamicList(trilist.SmartObjects[UISmartObjectJoin.TechMenuList], + true, 3100); + + MenuList.SetFeedback(1, true); // initial fb + ushort count = 0; + + MenuList.SetItemMainText(1, "System Status"); + MenuList.SetItemButtonAction(1, b => { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechSystemStatusVisible); + MenuList.SetFeedback(1, true); + }); + + MenuList.SetItemMainText(2, "Display Controls"); + MenuList.SetItemButtonAction(2, b => { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechDisplayControlsVisible); + MenuList.SetFeedback(2, true); + }); + + count = 2; + + // Don't show panel setup on iPad or xpanel + if (TriList is Crestron.SimplSharpPro.DeviceSupport.TswFt5Button) + { + count++; + MenuList.SetItemMainText(count, "Panel Setup"); + MenuList.SetItemButtonAction(count, b => + { + if (b) PagesInterlock.ShowInterlocked(UIBoolJoin.TechPanelSetupVisible); + MenuList.SetFeedback(count, true); + }); + } + + MenuList.Count = count; + BuildStatusList(); + BuildDisplayList(); + SetupPinModal(); + } + + /// + /// + /// + public override void Show() + { + // divert to PIN if we need auth + if (IsAuthorized) + { + // Cancel the auth timer so we don't deauth after coming back in + if (PinAuthorizedTimer != null) + PinAuthorizedTimer.Stop(); + + TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, true); + PagesInterlock.Show(); + base.Show(); + } + else + { + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, true); + } + } + + /// + /// + /// + public override void Hide() + { + // Leave it authorized for 60 seconds. + if (IsAuthorized) + PinAuthorizedTimer = new CTimer(o => { + IsAuthorized = false; + PinAuthorizedTimer = null; + }, 60000); + TriList.SetBool(UIBoolJoin.TechCommonItemsVisbible, false); + PagesInterlock.Hide(); + base.Hide(); + } + + /// + /// Wire up the keypad and buttons + /// + void SetupPinModal() + { + TriList.SetSigFalseAction(UIBoolJoin.PinDialogCancelPress, CancelPinDialog); + PinKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.TechPinDialogKeypad], true); + PinKeypad.Digit0.UserObject = new Action(b => { if (b)DialPinDigit('0'); }); + PinKeypad.Digit1.UserObject = new Action(b => { if (b)DialPinDigit('1'); }); + PinKeypad.Digit2.UserObject = new Action(b => { if (b)DialPinDigit('2'); }); + PinKeypad.Digit3.UserObject = new Action(b => { if (b)DialPinDigit('3'); }); + PinKeypad.Digit4.UserObject = new Action(b => { if (b)DialPinDigit('4'); }); + PinKeypad.Digit5.UserObject = new Action(b => { if (b)DialPinDigit('5'); }); + PinKeypad.Digit6.UserObject = new Action(b => { if (b)DialPinDigit('6'); }); + PinKeypad.Digit7.UserObject = new Action(b => { if (b)DialPinDigit('7'); }); + PinKeypad.Digit8.UserObject = new Action(b => { if (b)DialPinDigit('8'); }); + PinKeypad.Digit9.UserObject = new Action(b => { if (b)DialPinDigit('9'); }); + } + + /// + /// + /// + /// + void DialPinDigit(char d) + { + PinEntryBuilder.Append(d); + var len = PinEntryBuilder.Length; + SetPinDotsFeedback(len); + + // check it! + if (len == 4) + { + if (Config.Password == PinEntryBuilder.ToString()) + { + IsAuthorized = true; + SetPinDotsFeedback(0); + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); + Show(); + } + else + { + SetPinDotsFeedback(0); + TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, true); + new CTimer(o => + { + TriList.SetBool(UIBoolJoin.PinDialogErrorVisible, false); + }, 1500); + } + + PinEntryBuilder.Remove(0, len); // clear it either way + } + } + + /// + /// Draws the dots as pin is entered + /// + /// + void SetPinDotsFeedback(int len) + { + TriList.SetBool(UIBoolJoin.PinDialogDot1, len >= 1); + TriList.SetBool(UIBoolJoin.PinDialogDot2, len >= 2); + TriList.SetBool(UIBoolJoin.PinDialogDot3, len >= 3); + TriList.SetBool(UIBoolJoin.PinDialogDot4, len == 4); + + } + + /// + /// Does what it says + /// + void CancelPinDialog() + { + PinEntryBuilder.Remove(0, PinEntryBuilder.Length); + TriList.SetBool(UIBoolJoin.PinDialog4DigitVisible, false); + } + + + /// + /// + /// + void BuildStatusList() + { + StatusList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechStatusList, 3, 3, 3); + StatusListDeviceIndexes = new Dictionary(); + uint i = 0; + foreach (var d in DeviceManager.AllDevices) + { + // make sure it is both ICommunicationMonitor and a Device + var sd = d as ICommunicationMonitor; + if (sd == null) + continue; + var dd = sd as Device; + if(dd == null) + continue; + i++; + StatusList.StringInputSig(i, 1).StringValue = dd.Name; + StatusList.UShortInputSig(i, 1).UShortValue = (ushort)sd.CommunicationMonitor.Status; + StatusListDeviceIndexes.Add(sd, i); + sd.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange ; + } + StatusList.Count = (ushort)i; + } + + /// + /// Builds the list of display controls + /// + void BuildDisplayList() + { + DisplayList = new SubpageReferenceList(TriList, UISmartObjectJoin.TechDisplayControlsList, 10, 3, 3); + + var devKeys = ConfigReader.ConfigObject.Devices.Where(d => + d.Group.Equals("display", StringComparison.OrdinalIgnoreCase) + || d.Group.Equals("projector", StringComparison.OrdinalIgnoreCase)) + .Select(dd => dd.Key); + var disps = DeviceManager.AllDevices.Where(d => + devKeys.Contains(d.Key)); + ushort i = 0; + foreach (var disp in disps) + { + var display = disp as DisplayBase; + if (display != null) + { + i++; + DisplayList.StringInputSig(i, 1).StringValue = display.Name; + DisplayList.GetBoolFeedbackSig(i, 1).SetSigFalseAction(display.PowerOn); + DisplayList.GetBoolFeedbackSig(i, 2).SetSigFalseAction(display.PowerOff); + if (display is TwoWayDisplayBase) + { + var powerOnSig = DisplayList.BoolInputSig(i, 1); + (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkInputSig(powerOnSig); + + var powerOffSig = DisplayList.BoolInputSig(1, 2); + (display as TwoWayDisplayBase).PowerIsOnFeedback.LinkComplementInputSig(powerOffSig); + } + DisplayList.GetBoolFeedbackSig(i, 3).SetSigFalseAction(() => + { if (display is IInputHdmi1) (display as IInputHdmi1).InputHdmi1(); }); + DisplayList.GetBoolFeedbackSig(i, 4).SetSigFalseAction(() => + { if (display is IInputHdmi2) (display as IInputHdmi2).InputHdmi2(); }); + DisplayList.GetBoolFeedbackSig(i, 5).SetSigFalseAction(() => + { if (display is IInputHdmi3) (display as IInputHdmi3).InputHdmi3(); }); + //DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => + //{ if (display is IInputHdmi4) (display as IInputHdmi4).InputHdmi4(); }); + DisplayList.GetBoolFeedbackSig(i, 6).SetSigFalseAction(() => + { if (display is IInputDisplayPort1) (display as IInputDisplayPort1).InputDisplayPort1(); }); + + + // Figure out some way to provide current input feedback + if (display is TwoWayDisplayBase) + { + (display as TwoWayDisplayBase).CurrentInputFeedback.OutputChange += CurrentInputFeedback_OutputChange; + } + } + + + } + + DisplayList.Count = i; + } + + + void CurrentInputFeedback_OutputChange(object sender, EventArgs e) + { + + } + + /// + /// + /// + void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e) + { + var c = sender as ICommunicationMonitor; + if (c != null && StatusListDeviceIndexes.ContainsKey(c)) + { + var i = StatusListDeviceIndexes[c]; + StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status; + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index e2f5aaf4..57433187 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -157,7 +157,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { get { - return () => CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); + return () => + { + var scaledVol = CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); + + if (Configuration.Audio.Output.Volume != 0) + { + Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, scaledVol); + _previousVolumeLevel = scaledVol; // Store the previous level for recall + } + + return scaledVol; + }; } } @@ -1684,12 +1695,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void MuteOff() { + Debug.Console(2, this, "Unmuting to previous level: {0}", _previousVolumeLevel); SetVolume((ushort)_previousVolumeLevel); } public override void MuteOn() { - _previousVolumeLevel = Configuration.Audio.Output.Volume; // Store the previous level for recall SetVolume(0); } From 71881addabf9cced4f0009cc4faaebaa45af73ee Mon Sep 17 00:00:00 2001 From: Jason Alborough Date: Wed, 11 Aug 2021 13:00:51 -0400 Subject: [PATCH 309/480] fix(Devices.Common.Cameras.CameraVisca): add and fire the event OnPresetsListHasChanged() after LinkToApi so that the camera presets populate to the bridge correctly --- .../Essentials Devices Common/Cameras/CameraVisca.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs index fb8ae79c..37a0487e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs @@ -170,6 +170,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); + + OnPresetsListHasChanged(); } void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) @@ -525,6 +527,15 @@ namespace PepperDash.Essentials.Devices.Common.Cameras public event EventHandler PresetsListHasChanged; + protected void OnPresetsListHasChanged() + { + var handler = PresetsListHasChanged; + if (handler == null) + return; + + handler.Invoke(this, EventArgs.Empty); + } + public List Presets { get; private set; } public void PresetSelect(int preset) @@ -537,6 +548,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras SavePreset(preset); } + #endregion #region IHasCameraFocusControl Members From 1bf828b8a9c0c658780bdc0012ac7dd8bb994e9a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 09:36:03 -0600 Subject: [PATCH 310/480] Updates feedback funcs for combined room type --- .../Types/EssentialsCombinedHuddleVtc1Room.cs | 41 +++---------------- devjson commands.json | 3 ++ 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs index 79f28aae..9dec21f2 100644 --- a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs @@ -57,11 +57,12 @@ namespace PepperDash.Essentials { return () => { - var displays = Displays.Where((d) => d is DisplayBase) as List; + + var displays = Displays.OfType().ToList(); var val = CurrentSourceInfo != null && CurrentSourceInfo.Type == eSourceListItemType.Route - && displays.Count() > 0; + && displays.Count > 0; //&& disp.PowerIsOnFeedback.BoolValue; return val; }; @@ -74,23 +75,7 @@ namespace PepperDash.Essentials { get { - return () => - { - var displays = Displays.Where((d) => d is TwoWayDisplayBase) as List; - if (displays != null) - { - var warmingDisplays = displays.Where((d) => d.IsWarmingUpFeedback.BoolValue); - - if (warmingDisplays.Count() > 0) - { - return true; - } - else - return false; - } - else - return false; - }; + return () => Displays.OfType().Any((d) => d.IsWarmingUpFeedback.BoolValue); } } /// @@ -100,23 +85,7 @@ namespace PepperDash.Essentials { get { - return () => - { - var displays = Displays.Where((d) => d is TwoWayDisplayBase) as List; - if (displays != null) - { - var coolingDisplays = displays.Where((d) => d.IsCoolingDownFeedback.BoolValue); - - if (coolingDisplays.Count() > 0) - { - return true; - } - else - return false; - } - else - return false; - }; + return () => Displays.OfType().Any((d) => d.IsCoolingDownFeedback.BoolValue); } } diff --git a/devjson commands.json b/devjson commands.json index 62e675d1..c7ed7291 100644 --- a/devjson commands.json +++ b/devjson commands.json @@ -42,3 +42,6 @@ devjson:2 {"deviceKey":"display01Comm-com", "methodName":"SendText", "params": [ devjson:10 {"deviceKey":"dmLink-ssh", "methodName":"Connect", "params": []} +devjson:2 {"deviceKey":"roomCombiner", "methodName":"SetRoomCombinationScenario", "params": ["combined"]} + +devjson:2 {"deviceKey":"roomCombiner", "methodName":"SetRoomCombinationScenario", "params": ["divided"]} \ No newline at end of file From 072411e4f60a142a749465d8a7fc214a43064a41 Mon Sep 17 00:00:00 2001 From: Louis Iacovelli Date: Thu, 12 Aug 2021 11:49:59 -0400 Subject: [PATCH 311/480] Added method to set preset for multiple situations --- .../Cameras/CameraBase.cs | 41 +++++++++++++------ .../Cameras/CameraVisca.cs | 3 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs index def22069..18a1ad36 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraBase.cs @@ -216,21 +216,11 @@ namespace PepperDash.Essentials.Devices.Common.Cameras var presetsCamera = cameraDevice as IHasCameraPresets; presetsCamera.PresetsListHasChanged += new EventHandler((o, a) => { - for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++) - { - int tempNum = i - 1; - - string label = ""; - - var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i)); - - if (preset != null) - label = preset.Description; - - trilist.SetString((ushort) (joinMap.PresetLabelStart.JoinNumber + tempNum), label); - } + SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist); }); + SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist); + for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++) { int tempNum = i; @@ -246,10 +236,35 @@ namespace PepperDash.Essentials.Devices.Common.Cameras presetsCamera.PresetStore(tempNum, label); }); } + trilist.OnlineStatusChange += (sender, args) => + { + if (!args.DeviceOnLine) + { return; } + + SendCameraPresetNamesToApi(presetsCamera, joinMap, trilist); + }; + + } + } + private void SendCameraPresetNamesToApi(IHasCameraPresets presetsCamera, CameraControllerJoinMap joinMap, BasicTriList trilist) + { + for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++) + { + int tempNum = i - 1; + + string label = ""; + + var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i)); + + if (preset != null) + label = preset.Description; + + trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label); } } } + public class CameraPreset : PresetBase { public CameraPreset(int id, string description, bool isDefined, bool isDefinable) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs index 37a0487e..71adf030 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs @@ -171,7 +171,8 @@ namespace PepperDash.Essentials.Devices.Common.Cameras { LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); - OnPresetsListHasChanged(); + //OnPresetsListHasChanged(); + } void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) From 7f6160eb4448cfce65dd4377116001e8f3d48d03 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 12:24:23 -0600 Subject: [PATCH 312/480] fix(essentials): Updates to better set feedback for current mode --- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index a1ceb50b..7e3745a2 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -173,10 +173,28 @@ namespace PepperDash.Essentials /// public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; } + + private UiDisplayMode _currentMode; + /// /// The mode showing. Presentation or call. /// - UiDisplayMode CurrentMode = UiDisplayMode.Start; + UiDisplayMode CurrentMode + { + get + { + return _currentMode; + } + set + { + if (value != _currentMode) + { + _currentMode = value; + + SetActivityFooterFeedbacks(); + } + } + } CTimer NextMeetingTimer; @@ -207,6 +225,7 @@ namespace PepperDash.Essentials MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5); + CurrentMode = UiDisplayMode.Start; // buttons are added in SetCurrentRoom //HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]); @@ -630,7 +649,6 @@ namespace PepperDash.Essentials CurrentSourcePageManager.Hide(); PowerOnFromCall(); CurrentMode = UiDisplayMode.Call; - SetActivityFooterFeedbacks(); VCDriver.Show(); } @@ -665,7 +683,6 @@ namespace PepperDash.Essentials } CurrentMode = UiDisplayMode.Presentation; SetupSourceList(); - SetActivityFooterFeedbacks(); } /// @@ -707,6 +724,8 @@ namespace PepperDash.Essentials if (CurrentRoom.CurrentSourceInfo == null) return; + CurrentMode = UiDisplayMode.Presentation; + if (CurrentRoom.CurrentSourceInfo.SourceDevice == null) { TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); @@ -1218,7 +1237,6 @@ namespace PepperDash.Essentials VCDriver.Hide(); SetupActivityFooterWhenRoomOff(); ShowLogo(); - SetActivityFooterFeedbacks(); TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; // Clear this so that the pesky meeting warning can resurface every minute when off From c26d7d73f8ae613c4f28705a9703847464827c60 Mon Sep 17 00:00:00 2001 From: Louis Iacovelli Date: Thu, 12 Aug 2021 15:14:23 -0400 Subject: [PATCH 313/480] Removed commented line. --- .../Essentials Devices Common/Cameras/CameraVisca.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs index 71adf030..6acf5850 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Cameras/CameraVisca.cs @@ -170,9 +170,6 @@ namespace PepperDash.Essentials.Devices.Common.Cameras public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { LinkCameraToApi(this, trilist, joinStart, joinMapKey, bridge); - - //OnPresetsListHasChanged(); - } void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) From 6e7bf061cfa130834f39e1907603e5ae985a4692 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 13:51:48 -0600 Subject: [PATCH 314/480] fix(essentials): Add null check for CurrentRoom --- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 7e3745a2..02f2e8e7 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -626,11 +626,14 @@ namespace PepperDash.Essentials /// void SetActivityFooterFeedbacks() { - CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call - && CurrentRoom.ShutdownType == eShutdownType.None; - ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation - && CurrentRoom.ShutdownType == eShutdownType.None; - EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; + if (CurrentRoom != null) + { + CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call + && CurrentRoom.ShutdownType == eShutdownType.None; + ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation + && CurrentRoom.ShutdownType == eShutdownType.None; + EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; + } } /// From 4b4f1f3c3d9c4ea61c7a1ece4962bd8137e6e23e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 14:48:19 -0600 Subject: [PATCH 315/480] fix(essentials): Updates to staging subpage join logic --- .../UI/JoinConstants/UIBoolJoin.cs | 8 +++--- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 25 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index aaecb81a..81be9002 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -752,10 +752,10 @@ namespace PepperDash.Essentials /// 15044 Close button for source modal overlay /// public const uint SourceBackgroundOverlayClosePress = 15044; - /// - /// 15045 - Visibility for the bar containing call navigation button list - /// - public const uint CallStagingBarVisible = 15045; + ///// + ///// 15045 - Visibility for the bar containing call navigation button list + ///// + //public const uint CallStagingBarVisible = 15045; /// /// 15046 /// diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 02f2e8e7..e12e94d9 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -626,13 +626,21 @@ namespace PepperDash.Essentials /// void SetActivityFooterFeedbacks() { + var startMode = CurrentMode == UiDisplayMode.Start; + var presentationMode = CurrentMode == UiDisplayMode.Presentation; + var callMode = CurrentMode == UiDisplayMode.Call; + + TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + if (CurrentRoom != null) { - CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call + CallButtonSig.BoolValue = startMode && CurrentRoom.ShutdownType == eShutdownType.None; - ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation + ShareButtonSig.BoolValue = presentationMode && CurrentRoom.ShutdownType == eShutdownType.None; EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; + } } @@ -645,9 +653,9 @@ namespace PepperDash.Essentials return; HideLogo(); HideNextMeetingPopup(); - TriList.SetBool(StartPageVisibleJoin, false); - TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); - TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + //TriList.SetBool(StartPageVisibleJoin, false); + //TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); + //TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); if (CurrentSourcePageManager != null) CurrentSourcePageManager.Hide(); PowerOnFromCall(); @@ -664,9 +672,6 @@ namespace PepperDash.Essentials if (VCDriver.IsVisible) VCDriver.Hide(); HideNextMeetingPopup(); - TriList.SetBool(StartPageVisibleJoin, false); - TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false); - TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true); // Run default source when room is off and share is pressed if (!CurrentRoom.OnFeedback.BoolValue) { @@ -1240,8 +1245,8 @@ namespace PepperDash.Essentials VCDriver.Hide(); SetupActivityFooterWhenRoomOff(); ShowLogo(); - TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false; - TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; + //TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false; + //TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; // Clear this so that the pesky meeting warning can resurface every minute when off LastMeetingDismissedId = null; } From efa801137c00ac7e29b358594dbfe5871a3bd7b7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 14:53:41 -0600 Subject: [PATCH 316/480] fix(Essentials): moves code inside null check for CurrentRoom --- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index e12e94d9..66a544e9 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -626,21 +626,20 @@ namespace PepperDash.Essentials /// void SetActivityFooterFeedbacks() { - var startMode = CurrentMode == UiDisplayMode.Start; - var presentationMode = CurrentMode == UiDisplayMode.Presentation; - var callMode = CurrentMode == UiDisplayMode.Call; - - TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); - TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); - if (CurrentRoom != null) { + var startMode = CurrentMode == UiDisplayMode.Start; + var presentationMode = CurrentMode == UiDisplayMode.Presentation; + var callMode = CurrentMode == UiDisplayMode.Call; + + TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + CallButtonSig.BoolValue = startMode && CurrentRoom.ShutdownType == eShutdownType.None; ShareButtonSig.BoolValue = presentationMode && CurrentRoom.ShutdownType == eShutdownType.None; EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; - } } From 2a37e44d7d2508c250ba44463c641955f63551c7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 12 Aug 2021 15:33:17 -0600 Subject: [PATCH 317/480] fix(essentials): fixes inverted activity call button state --- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 66a544e9..55a4a16c 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -635,7 +635,7 @@ namespace PepperDash.Essentials TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); - CallButtonSig.BoolValue = startMode + CallButtonSig.BoolValue = callMode && CurrentRoom.ShutdownType == eShutdownType.None; ShareButtonSig.BoolValue = presentationMode && CurrentRoom.ShutdownType == eShutdownType.None; From 87ab43c7459bfe0b08fdb97a4f1dea5d11c073e2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 13 Aug 2021 13:45:46 -0600 Subject: [PATCH 318/480] fix(essentials): Updates to resolve oddities with ZoomRoom directory browsing and dialing --- .../VC/EssentialsVideoCodecUiDriver.cs | 25 +++- .../Codec/iHasDirectory.cs | 25 ++++ .../VideoCodec/ZoomRoom/ResponseObjects.cs | 29 +++-- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 110 ++++++++++++------ 4 files changed, 136 insertions(+), 53 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 53efb69f..f2bbcead 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -1080,10 +1080,12 @@ namespace PepperDash.Essentials.UIDrivers.VC { var codec = Codec as IHasDirectory; - SetCurrentDirectoryToRoot(); + if (codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) + { + SetCurrentDirectoryToRoot(); - RefreshDirectory(); - + RefreshDirectory(); + } } /// @@ -1161,10 +1163,23 @@ namespace PepperDash.Essentials.UIDrivers.VC }); } + else if (dc.ContactMethods.Count == 1) + { + var invitableContact = dc as IInvitableContact; + + if (invitableContact != null) + { + DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(invitableContact); }); + } + else + { + // If only one contact method, just dial that method + DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); }); + } + } else { - // If only one contact method, just dial that method - DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); }); + Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified"); } } else // is DirectoryFolder diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs index 3a59b62d..29a46466 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs @@ -69,6 +69,22 @@ namespace PepperDash.Essentials.Devices.Common.Codec [JsonProperty("directoryResults")] public List CurrentDirectoryResults { get; private set; } + public List Contacts + { + get + { + return CurrentDirectoryResults.OfType().Cast().ToList(); + } + } + + public List Folders + { + get + { + return CurrentDirectoryResults.OfType().Cast().ToList(); + } + } + /// /// Used to store the ID of the current folder for CurrentDirectoryResults /// @@ -104,6 +120,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec SortDirectory(); } + /// + /// Filters the CurrentDirectoryResults by the predicate + /// + /// + public void FilterContacts(Func predicate) + { + CurrentDirectoryResults = CurrentDirectoryResults.Where(predicate).ToList(); + } + /// /// Sorts the DirectoryResults list to display all folders alphabetically, then all contacts alphabetically /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 708abe34..21d8c3df 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -276,6 +276,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (zoomRooms.Count > 0) { // If so, setup a rooms and contacts folder and add them. + + directory.ResultsFolderId = "root"; + roomFolder.Name = "Rooms"; roomFolder.ParentFolderId = "root"; roomFolder.FolderId = "rooms"; @@ -292,22 +295,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom try { - if (zoomContacts.Count == 0) return directory; + if (zoomContacts.Count == 0) + { + return directory; + } + + foreach (Contact c in zoomContacts) { - foreach (Contact c in zoomContacts) + var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; + + contact.ContactMethods.Add(new ContactMethod() { Number = c.Jid, Device = eContactMethodDevice.Video, CallType = eContactMethodCallType.Video, ContactMethodId = c.Jid }); + + if (folders.Count > 0) { - var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; - - if (folders.Count > 0) - { - contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; - } - - contacts.Add(contact); + contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts"; } - directory.AddContactsToDirectory(contacts); + contacts.Add(contact); } + + directory.AddContactsToDirectory(contacts); } catch (Exception e) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 57433187..e65a16ae 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -361,6 +361,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public CodecDirectory CurrentDirectoryResult { get { return _currentDirectoryResult; } + private set + { + _currentDirectoryResult = value; + + Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", _currentDirectoryResult.ResultsFolderId); + + CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + + OnDirectoryResultReturned(_currentDirectoryResult); + } } public CodecPhonebookSyncState PhonebookSyncState { get; private set; } @@ -374,9 +384,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom c => c.Name.IndexOf(searchString, 0, StringComparison.OrdinalIgnoreCase) > -1)); DirectoryBrowseHistoryStack.Clear(); - _currentDirectoryResult = directoryResults; + CurrentDirectoryResult = directoryResults; - OnDirectoryResultReturned(directoryResults); } public void GetDirectoryFolderContents(string folderId) @@ -388,19 +397,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom DirectoryBrowseHistoryStack.Push(_currentDirectoryResult); - _currentDirectoryResult = directoryResults; + CurrentDirectoryResult = directoryResults; - OnDirectoryResultReturned(directoryResults); } public void SetCurrentDirectoryToRoot() { DirectoryBrowseHistoryStack.Clear(); - _currentDirectoryResult = DirectoryRoot; - - OnDirectoryResultReturned(DirectoryRoot); - } + CurrentDirectoryResult = DirectoryRoot; + } public void GetDirectoryParentFolderContents() { @@ -411,10 +417,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var currentDirectory = DirectoryBrowseHistoryStack.Pop(); - _currentDirectoryResult = currentDirectory; - - OnDirectoryResultReturned(currentDirectory); - } + CurrentDirectoryResult = currentDirectory; + } public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; } @@ -680,16 +684,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void SetUpDirectory() { - DirectoryRoot = new CodecDirectory(); + DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" }; - _currentDirectoryResult = DirectoryRoot; + CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root"); + + CurrentDirectoryResult = DirectoryRoot; DirectoryBrowseHistory = new List(); DirectoryBrowseHistoryStack = new Stack(); - CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => _currentDirectoryResult != DirectoryRoot); - - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); } private void SetUpRouting() @@ -1054,24 +1057,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } case "phonebooklistresult": { + // This result will always be the complete contents of the directory and never + // A subset of the results via a search + JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); + var directoryResults = + zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); + if (!PhonebookSyncState.InitialSyncComplete) { PhonebookSyncState.InitialPhonebookFoldersReceived(); PhonebookSyncState.PhonebookRootEntriesReceived(); - PhonebookSyncState.SetPhonebookHasFolders(false); + PhonebookSyncState.SetPhonebookHasFolders(true); PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); } - var directoryResults = - zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); + if (directoryResults.ResultsFolderId != "root") + { + directoryResults.ResultsFolderId = "root"; + } - DirectoryRoot = directoryResults; + DirectoryRoot = directoryResults; - _currentDirectoryResult = DirectoryRoot; - - OnDirectoryResultReturned(directoryResults); + CurrentDirectoryResult = directoryResults; break; } @@ -1227,7 +1236,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Direction = eCodecCallDirection.Incoming, Status = eCodecCallStatus.Ringing, - Type = eCodecCallType.Unknown, + Type = eCodecCallType.Video, Name = incomingCall.callerName, Id = incomingCall.callerJID }; @@ -1580,8 +1589,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var newCall = new CodecActiveCallItem { Name = Status.Call.Info.meeting_list_item.meetingName, + Number = Status.Call.Info.meeting_id, Id = Status.Call.Info.meeting_id, - Status = newStatus + Status = newStatus, + Type = eCodecCallType.Video, }; ActiveCalls.Add(newCall); @@ -1999,18 +2010,43 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// private void OnDirectoryResultReturned(CodecDirectory result) { - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + try + { + Debug.Console(2, this, "OnDirectoryResultReturned"); - // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology - var handler = DirectoryResultReturned; - if (handler != null) - { - handler(this, new DirectoryEventArgs - { - Directory = result, - DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue - }); - } + var directoryResult = new CodecDirectory(); + + // If result is Root, create a copy and filter out contacts whose parent folder is not root + if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) + { + Debug.Console(2, this, "Filtering DirectoryRoot to remove contacts for display"); + + directoryResult.ResultsFolderId = result.ResultsFolderId; + directoryResult.AddFoldersToDirectory(result.Folders); + directoryResult.AddContactsToDirectory(result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList()); + } + else + { + directoryResult = result; + } + + Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + + // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology + var handler = DirectoryResultReturned; + if (handler != null) + { + handler(this, new DirectoryEventArgs + { + Directory = directoryResult, + DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue + }); + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error: {0}", e); + } //PrintDirectory(result); } From d193de79dabadef0f91e4c5cbca159eb2160482f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 16 Aug 2021 08:26:27 -0500 Subject: [PATCH 319/480] Added GetSelfViewMode method to ZoomRoom.cs, upated Removed if statement in HideConfSelfVideo property that was blocking feedback updates and setting of the property from boot. Tested with Zoom Rooms system on site and verified working. Closes #781. --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 6 +++--- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 21d8c3df..c116a4a8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1168,11 +1168,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } set { - if (value != _hideConfSelfVideo) - { + //if (value != _hideConfSelfVideo) + //{ _hideConfSelfVideo = value; NotifyPropertyChanged("HideConfSelfVideo"); - } + //} } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index e65a16ae..9398f2c9 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -329,6 +329,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public BoolFeedback SelfviewIsOnFeedback { get; private set; } + public void GetSelfViewMode() + { + SendText("zConfiguration Video hide_conf_self_video"); + } + public void SelfViewModeOn() { SendText("zConfiguration Video hide_conf_self_video: off"); From 23e828090439366138e733ff42e8ce796fca36b1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 16 Aug 2021 09:42:11 -0600 Subject: [PATCH 320/480] refactor: Add RefreshDirectory overload This allows the directory to be refreshed by the event that updates the directory correctly --- .../VC/EssentialsVideoCodecUiDriver.cs | 90 +++++++++++-------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index f2bbcead..612f7eeb 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -1041,22 +1041,21 @@ namespace PepperDash.Essentials.UIDrivers.VC void SetupDirectoryList() { var codec = Codec as IHasDirectory; - if (codec != null) - { - DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList], - true, 1300); - codec.DirectoryResultReturned += new EventHandler(dir_DirectoryResultReturned); + if (codec == null) + { + return; + } - if (codec.PhonebookSyncState.InitialSyncComplete) - SetCurrentDirectoryToRoot(); - else - { - codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler(PhonebookSyncState_InitialSyncCompleted); - } + DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList], + true, 1300); + codec.DirectoryResultReturned += dir_DirectoryResultReturned; - RefreshDirectory(); - - } + if (codec.PhonebookSyncState.InitialSyncComplete) + SetCurrentDirectoryToRoot(); + else + { + codec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted; + } } /// @@ -1064,11 +1063,15 @@ namespace PepperDash.Essentials.UIDrivers.VC /// void SetCurrentDirectoryToRoot() { - (Codec as IHasDirectory).SetCurrentDirectoryToRoot(); + var hasDirectory = Codec as IHasDirectory; + if (hasDirectory == null) + { + return; + } + + hasDirectory.SetCurrentDirectoryToRoot(); SearchKeypadClear(); - - RefreshDirectory(); } /// @@ -1080,12 +1083,17 @@ namespace PepperDash.Essentials.UIDrivers.VC { var codec = Codec as IHasDirectory; - if (codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) + if (codec == null) { - SetCurrentDirectoryToRoot(); - - RefreshDirectory(); + return; } + + if (!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) + { + return; + } + + SetCurrentDirectoryToRoot(); } /// @@ -1095,8 +1103,7 @@ namespace PepperDash.Essentials.UIDrivers.VC /// void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e) { - - RefreshDirectory(); + RefreshDirectory(e.Directory); } /// @@ -1125,16 +1132,27 @@ namespace PepperDash.Essentials.UIDrivers.VC } - /// - /// - /// - /// - void RefreshDirectory() + /// + /// + /// + void RefreshDirectory() { - if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0) + var codec = Codec as IHasDirectory; + + if (codec == null) + { + return; + } + + RefreshDirectory(codec.CurrentDirectoryResult); + } + + void RefreshDirectory(CodecDirectory directory) + { + if (directory.CurrentDirectoryResults.Count > 0) { ushort i = 0; - foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults) + foreach (var r in directory.CurrentDirectoryResults) { if (i == DirectoryList.MaxCount) { @@ -1154,12 +1172,13 @@ namespace PepperDash.Essentials.UIDrivers.VC // If more than one contact method, show contact method modal dialog DirectoryList.SetItemButtonAction(i, b => { - if (!b) + if (b) { - // Refresh the contact methods list - RefreshContactMethodsModalList(dc); - Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible); + return; } + // Refresh the contact methods list + RefreshContactMethodsModalList(dc); + Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible); }); } @@ -1206,8 +1225,7 @@ namespace PepperDash.Essentials.UIDrivers.VC DirectoryList.SetItemMainText(1, "No Results Found"); } - - } + } void RefreshContactMethodsModalList(DirectoryContact contact) { From 01b713e6e1af7181a6efe6c2666d3b67dbcf9504 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 16 Aug 2021 14:27:28 -0600 Subject: [PATCH 321/480] feat(essentials): Adds IMobileControl3 interface to maintain backwards compatibility --- PepperDashEssentials/ControlSystem.cs | 19 ++++++++++++++----- .../DeviceTypeInterfaces/IMobileControl.cs | 8 ++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 2495340c..ef1a9378 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -484,7 +484,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else if (room is IEssentialsHuddleVtc1Room) { @@ -495,7 +495,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else if (room is EssentialsTechRoom) { @@ -507,7 +507,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge"); - CreateMobileControlBridge(room as EssentialsRoomBase); + CreateMobileControlBridge(room); } else { @@ -524,13 +524,22 @@ namespace PepperDash.Essentials } - private static void CreateMobileControlBridge(EssentialsRoomBase room) + private static void CreateMobileControlBridge(object room) { var mobileControl = GetMobileControlDevice(); if (mobileControl == null) return; - mobileControl.CreateMobileControlRoomBridge(room, mobileControl); + var mobileControl3 = mobileControl as IMobileControl3; + + if (mobileControl3 != null) + { + mobileControl3.CreateMobileControlRoomBridge(room as IEssentialsRoom, mobileControl); + } + else + { + mobileControl.CreateMobileControlRoomBridge(room as EssentialsRoomBase, mobileControl); + } Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added..."); } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs index c87e7865..ba9e6609 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IMobileControl.cs @@ -13,6 +13,14 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces void LinkSystemMonitorToAppServer(); } + /// + /// Describes a MobileSystemController that accepts IEssentialsRoom + /// + public interface IMobileControl3 : IMobileControl + { + void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent); + } + /// /// Describes a MobileControl Room Bridge /// From 6bdda5451b46f809bd69f22cd2e98addf38e743f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 17 Aug 2021 15:14:02 -0500 Subject: [PATCH 322/480] Updated UpdateCallStatus method to fix call status references previously looking at Status.Call.Sharing.State. Added else statement to 'if(ActiveCalls.Count == 0)' used to cleanup after calls that refreshs the participant list. Added GetCurrentCallParticipant method used to poll the participant list. --- .../VideoCodec/Interfaces/IHasParticipants.cs | 170 +++++++++--------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 156 +++++++++++----- 2 files changed, 204 insertions(+), 122 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index f6d32149..361e0cae 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -1,100 +1,108 @@ using System; using System.Collections.Generic; +using PepperDash.Core; using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { - /// - /// Describes a device that has call participants - /// - public interface IHasParticipants - { - CodecParticipants Participants { get; } - } + /// + /// Describes a device that has call participants + /// + public interface IHasParticipants + { + CodecParticipants Participants { get; } + } - /// - /// Describes the ability to mute and unmute a participant's video in a meeting - /// - public interface IHasParticipantVideoMute:IHasParticipants - { - void MuteVideoForParticipant(int userId); - void UnmuteVideoForParticipant(int userId); - void ToggleVideoForParticipant(int userId); - } + /// + /// Describes the ability to mute and unmute a participant's video in a meeting + /// + public interface IHasParticipantVideoMute : IHasParticipants + { + void MuteVideoForParticipant(int userId); + void UnmuteVideoForParticipant(int userId); + void ToggleVideoForParticipant(int userId); + } - /// - /// Describes the ability to mute and unmute a participant's audio in a meeting - /// - public interface IHasParticipantAudioMute : IHasParticipantVideoMute - { - void MuteAudioForParticipant(int userId); - void UnmuteAudioForParticipant(int userId); - void ToggleAudioForParticipant(int userId); - } + /// + /// Describes the ability to mute and unmute a participant's audio in a meeting + /// + public interface IHasParticipantAudioMute : IHasParticipantVideoMute + { + void MuteAudioForParticipant(int userId); + void UnmuteAudioForParticipant(int userId); + void ToggleAudioForParticipant(int userId); + } - /// - /// Describes the ability to pin and unpin a participant in a meeting - /// - public interface IHasParticipantPinUnpin : IHasParticipants - { - IntFeedback NumberOfScreensFeedback { get; } - int ScreenIndexToPinUserTo { get; } + /// + /// Describes the ability to pin and unpin a participant in a meeting + /// + public interface IHasParticipantPinUnpin : IHasParticipants + { + IntFeedback NumberOfScreensFeedback { get; } + int ScreenIndexToPinUserTo { get; } - void PinParticipant(int userId, int screenIndex); - void UnPinParticipant(int userId); - void ToggleParticipantPinState(int userId, int screenIndex); - } + void PinParticipant(int userId, int screenIndex); + void UnPinParticipant(int userId); + void ToggleParticipantPinState(int userId, int screenIndex); + } - public class CodecParticipants - { - private List _currentParticipants; - - public List CurrentParticipants { - get { return _currentParticipants; } - set - { - _currentParticipants = value; - OnParticipantsChanged(); - } - } + public class CodecParticipants + { + private List _currentParticipants; - public event EventHandler ParticipantsListHasChanged; + public List CurrentParticipants + { + get { return _currentParticipants; } + set + { + _currentParticipants = value; + foreach (var participant in _currentParticipants) + { + Debug.Console(1, "[CurrentParticipants] participant UserId: {0} Name: {1} IsHost: {2}", participant.UserId, participant.Name, participant.IsHost); + } + OnParticipantsChanged(); + } + } - public CodecParticipants() - { - _currentParticipants = new List(); - } + public event EventHandler ParticipantsListHasChanged; - public void OnParticipantsChanged() - { - var handler = ParticipantsListHasChanged; + public CodecParticipants() + { + _currentParticipants = new List(); + } - if (handler == null) return; + public void OnParticipantsChanged() + { + var handler = ParticipantsListHasChanged; - handler(this, new EventArgs()); - } - } + Debug.Console(1, "[OnParticipantsChanged] Event Fired - handler is {0}", handler == null ? "null" : "not null"); - /// - /// Represents a call participant - /// - public class Participant - { - public int UserId { get; set; } - public bool IsHost { get; set; } - public string Name { get; set; } - public bool CanMuteVideo { get; set; } - public bool CanUnmuteVideo { get; set; } - public bool VideoMuteFb { get; set; } - public bool AudioMuteFb { get; set; } - public bool HandIsRaisedFb { get; set; } - public bool IsPinnedFb { get; set; } - public int ScreenIndexIsPinnedToFb { get; set; } + if (handler == null) return; - public Participant() - { - // Initialize to -1 (no screen) - ScreenIndexIsPinnedToFb = -1; - } - } + handler(this, new EventArgs()); + } + } + + /// + /// Represents a call participant + /// + public class Participant + { + public int UserId { get; set; } + public bool IsHost { get; set; } + public string Name { get; set; } + public bool CanMuteVideo { get; set; } + public bool CanUnmuteVideo { get; set; } + public bool VideoMuteFb { get; set; } + public bool AudioMuteFb { get; set; } + public bool HandIsRaisedFb { get; set; } + public bool IsPinnedFb { get; set; } + public int ScreenIndexIsPinnedToFb { get; set; } + + public Participant() + { + // Initialize to -1 (no screen) + ScreenIndexIsPinnedToFb = -1; + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 9398f2c9..bd8d1215 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO.Ports; using System.Linq; using System.Text; using Crestron.SimplSharp; @@ -763,12 +764,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (s == "1") { CommDebuggingIsOn = true; - Debug.Console(0, this, "Comm Debug Enabled."); + Debug.Console(1, this, "Comm Debug Enabled."); } else { CommDebuggingIsOn = false; - Debug.Console(0, this, "Comm Debug Disabled."); + Debug.Console(1, this, "Comm Debug Disabled."); } } @@ -876,7 +877,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // Counts the curly braces if (message.Contains("client_loop: send disconnect: Broken pipe")) { - Debug.Console(0, this, Debug.ErrorLogLevel.Error, + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Zoom Room Controller or App connected. Essentials will NOT control the Zoom Room until it is disconnected."); return; @@ -966,7 +967,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("echo off"); Thread.Sleep(100); // set feedback exclusions - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); Thread.Sleep(100); SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list"); Thread.Sleep(100); @@ -1110,6 +1111,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (participant != null) { + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} **********************************", participant.Event); + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} - UserId: {1} Name: {2} IsHost: {3}", + participant.Event, participant.UserId, participant.UserName, participant.IsHost); + switch (participant.Event) { case "ZRCUserChangedEventUserInfoUpdated": @@ -1135,9 +1140,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } break; case "ZRCUserChangedEventJoinedMeeting": - Status.Call.Participants.Add(participant); + { + var existingParticipant = + Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId)); + + // found matching participant.UserId + if (existingParticipant != null) + { + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); + + JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant); + } + else + { + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); + + Status.Call.Participants.Add(participant); + + //var emptyList = new List(); + //Participants.CurrentParticipants = emptyList; + + //GetCurrentCallParticipants(); + } + break; + } } + + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ***********************************", participant.Event); } } break; @@ -1148,7 +1180,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Call.Participants); Participants.CurrentParticipants = participants; - PrintCurrentCallParticipants(); break; @@ -1282,23 +1313,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var disconnectEvent = JsonConvert.DeserializeObject(responseObj.ToString()); + Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************"); + Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - disconnectEvent.Successful: {0}", disconnectEvent.Successful); + if (disconnectEvent.Successful) { if (ActiveCalls.Count > 0) - { + { var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); - + if (activeCall != null) { + Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - ActiveCalls.Count: {0} activeCall.Id: {1}, activeCall.Number: {2} activeCall.Name: {3}, activeCall.IsActive: {4}", ActiveCalls.Count, activeCall.Id, activeCall.Number, activeCall.Name, activeCall.IsActiveCall); activeCall.Status = eCodecCallStatus.Disconnected; OnCallStatusChange(activeCall); } - } + } + var emptyList = new List(); Participants.CurrentParticipants = emptyList; + //Participants.OnParticipantsChanged(); } + Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************"); + UpdateCallStatus(); break; } @@ -1431,6 +1470,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { JsonConvert.PopulateObject(responseObj.ToString(), Status.Call); + Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Info.meeting_id: {0} Status.Call.Info.meeting_list_item.meetingName: {1}", Status.Call.Info.meeting_id, Status.Call.Info.meeting_list_item.meetingName); + foreach (var participant in Status.Call.Participants) + { + Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Participants participant.UserId: {0} participant.UserName: {1}", participant.UserId, participant.UserName); + } + UpdateCallStatus(); break; @@ -1536,12 +1581,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "*************************** Call Participants **************************"); foreach (var participant in Participants.CurrentParticipants) { - Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name, - participant.AudioMuteFb, participant.IsHost); + Debug.Console(1, this, "UserId: {3} Name: {0} Audio: {1} IsHost: {2}", + participant.Name, participant.AudioMuteFb, participant.IsHost, participant.UserId); } Debug.Console(1, this, "************************************************************************"); } + public void GetCurrentCallParticipants() + { + SendText("zCommand Call ListParticipants"); + } + /// /// Retrieves bookings list /// @@ -1557,16 +1607,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void UpdateCallStatus() { Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + Status.Call != null ? Status.Call.Status.ToString() : "no call"); + + //var emptyList = new List(); if (Status.Call != null) { var callStatus = Status.Call.Status; - // If not currently in a meeting, intialize the call object + // If not crrently in a meeting, intialize the call object if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING) { - Debug.Console(1, this, "Creating new Status.Call object"); + Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object"); Status.Call = new zStatus.Call { Status = callStatus }; OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected }); @@ -1583,7 +1635,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (callStatus) { - case zStatus.eCallStatus.CONNECTING_MEETING: + case zStatus.eCallStatus.CONNECTING_MEETING: newStatus = eCodecCallStatus.Connecting; break; case zStatus.eCallStatus.IN_MEETING: @@ -1591,28 +1643,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; } - var newCall = new CodecActiveCallItem - { - Name = Status.Call.Info.meeting_list_item.meetingName, - Number = Status.Call.Info.meeting_id, - Id = Status.Call.Info.meeting_id, - Status = newStatus, - Type = eCodecCallType.Video, - }; + if (!string.IsNullOrEmpty(Status.Call.Info.meeting_id)) + { + var newCall = new CodecActiveCallItem + { + Name = Status.Call.Info.meeting_list_item.meetingName, + Number = Status.Call.Info.meeting_list_item.meetingNumber, + Id = Status.Call.Info.meeting_id, + Status = newStatus, + Type = eCodecCallType.Video, + }; - ActiveCalls.Add(newCall); + //Participants.CurrentParticipants = emptyList; - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + ActiveCalls.Add(newCall); - OnCallStatusChange(newCall); + Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", + Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + + OnCallStatusChange(newCall); + } + else + { + Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", + Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + + //Participants.CurrentParticipants = emptyList; + } } - - } else { - var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); + var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); switch (callStatus) { @@ -1620,18 +1682,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom existingCall.Status = eCodecCallStatus.Connected; break; case zStatus.eCallStatus.NOT_IN_MEETING: + //Participants.CurrentParticipants = emptyList; existingCall.Status = eCodecCallStatus.Disconnected; - break; + break; + //default: + // Participants.CurrentParticipants = emptyList; + // break; } - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + Debug.Console(1, this, "[UpdateCallStatus] ELSE ActiveCalls.Count == {1} - Current Call Status: {0}", + Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); OnCallStatusChange(existingCall); } } - Debug.Console(1, this, "*************************** Active Calls ********************************"); + Debug.Console(1, this, "[UpdateCallStatus] Active Calls ------------------------------"); // Clean up any disconnected calls left in the list for (int i = 0; i < ActiveCalls.Count; i++) @@ -1639,26 +1705,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var call = ActiveCalls[i]; Debug.Console(1, this, - @"Name: {0} - ID: {1} + @"ID: {1} + Number: {5} + Name: {0} IsActive: {2} Status: {3} - Direction: {4}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction); + Direction: {4} + IsActiveCall: {6}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction, call.Number, call.IsActiveCall); if (!call.IsActiveCall) { - Debug.Console(1, this, "***** Removing Inactive Call: {0} *****", call.Name); + Debug.Console(1, this, "[UpdateCallStatus] Removing Inactive call.Id: {1} call.Name: {0}", call.Name, call.Id); ActiveCalls.Remove(call); } } - Debug.Console(1, this, "**************************************************************************"); + Debug.Console(1, this, "[UpdateCallStatus] Active Calls ------------------------------"); //clear participants list after call cleanup if (ActiveCalls.Count == 0) { - var emptyList = new List(); + var emptyList = new List(); Participants.CurrentParticipants = emptyList; } + else + { + var emptyList = new List(); + Participants.CurrentParticipants = emptyList; + GetCurrentCallParticipants(); + } } protected override void OnCallStatusChange(CodecActiveCallItem item) @@ -1666,7 +1740,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom base.OnCallStatusChange(item); Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}", - Status.Call != null ? Status.Call.Sharing.State.ToString() : "no call"); + Status.Call != null ? Status.Call.Status.ToString() : "no call"); if (_props.AutoDefaultLayouts) { From c4f6afa412fdd92abc447c191d9d1ed64718b2e9 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 17 Aug 2021 15:56:57 -0500 Subject: [PATCH 323/480] Fixed debug references used for call status that were printing Status.Call.Sharing.State. Added GetCurrentCallParticipants method to referesh participant list. Updated UpdateCallStatus to resolve issue with duplicate participants when admitted from the waiting room. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 491 +++++++++--------- 1 file changed, 233 insertions(+), 258 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index bd8d1215..0e1d31fb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -33,11 +33,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private const uint DefaultMeetingDurationMin = 30; private const string Delimiter = "\x0D\x0A"; - private readonly GenericQueue _receiveQueue; - //private readonly CrestronQueue _receiveQueue; + private readonly GenericQueue _receiveQueue; + //private readonly CrestronQueue _receiveQueue; - //private readonly Thread _receiveThread; + //private readonly Thread _receiveThread; private readonly ZoomRoomSyncState _syncState; public bool CommDebuggingIsOn; @@ -55,7 +55,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { _props = JsonConvert.DeserializeObject(config.Properties.ToString()); - _receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512); + _receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512); Communication = comm; @@ -95,9 +95,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this); - Output2 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, - eRoutingSignalType.Video, - eRoutingPortConnectionType.DisplayPort, null, this); + Output2 = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, + eRoutingSignalType.Video, + eRoutingPortConnectionType.DisplayPort, null, this); SelfviewIsOnFeedback = new BoolFeedback(SelfViewIsOnFeedbackFunc); @@ -115,7 +115,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // TODO: #714 [ ] SelfviewPipSizeFeedback SelfviewPipSizeFeedback = new StringFeedback(SelfviewPipSizeFeedbackFunc); - + SetUpFeedbackActions(); Cameras = new List(); @@ -158,18 +158,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { get { - return () => - { - var scaledVol = CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); + return () => + { + var scaledVol = CrestronEnvironment.ScaleWithLimits(Configuration.Audio.Output.Volume, 100, 0, 65535, 0); - if (Configuration.Audio.Output.Volume != 0) - { - Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, scaledVol); - _previousVolumeLevel = scaledVol; // Store the previous level for recall - } + if (Configuration.Audio.Output.Volume != 0) + { + Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, scaledVol); + _previousVolumeLevel = scaledVol; // Store the previous level for recall + } - return scaledVol; - }; + return scaledVol; + }; } } @@ -267,7 +267,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public RoutingInputPort CodecOsdIn { get; private set; } public RoutingOutputPort Output1 { get; private set; } - public RoutingOutputPort Output2 { get; private set; } + public RoutingOutputPort Output2 { get; private set; } #region ICommunicationMonitor Members @@ -367,16 +367,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public CodecDirectory CurrentDirectoryResult { get { return _currentDirectoryResult; } - private set - { - _currentDirectoryResult = value; + private set + { + _currentDirectoryResult = value; - Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", _currentDirectoryResult.ResultsFolderId); + Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", _currentDirectoryResult.ResultsFolderId); - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); - OnDirectoryResultReturned(_currentDirectoryResult); - } + OnDirectoryResultReturned(_currentDirectoryResult); + } } public CodecPhonebookSyncState PhonebookSyncState { get; private set; } @@ -411,8 +411,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { DirectoryBrowseHistoryStack.Clear(); - CurrentDirectoryResult = DirectoryRoot; - } + CurrentDirectoryResult = DirectoryRoot; + } public void GetDirectoryParentFolderContents() { @@ -423,8 +423,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var currentDirectory = DirectoryBrowseHistoryStack.Pop(); - CurrentDirectoryResult = currentDirectory; - } + CurrentDirectoryResult = currentDirectory; + } public BoolFeedback CurrentDirectoryResultIsNotDirectoryRoot { get; private set; } @@ -553,44 +553,44 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; } case "Size": - { - // TODO: #714 [ ] SetupFeedbackActions >> Size - ComputeSelfviewPipSizeStatus(); + { + // TODO: #714 [ ] SetupFeedbackActions >> Size + ComputeSelfviewPipSizeStatus(); - SelfviewPipSizeFeedback.FireUpdate(); + SelfviewPipSizeFeedback.FireUpdate(); - break; - } + break; + } } }; - // This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3 - Configuration.Client.Call.Layout.PropertyChanged += (o,a) => - { - switch (a.PropertyName) - { - case "Position": - { - ComputeSelfviewPipPositionStatus(); + // This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3 + Configuration.Client.Call.Layout.PropertyChanged += (o, a) => + { + switch (a.PropertyName) + { + case "Position": + { + ComputeSelfviewPipPositionStatus(); - SelfviewPipPositionFeedback.FireUpdate(); + SelfviewPipPositionFeedback.FireUpdate(); - break; - } - case "ShareThumb": - { - ContentSwappedWithThumbnailFeedback.FireUpdate(); - break; - } - case "Style": - { - LocalLayoutFeedback.FireUpdate(); - break; - } + break; + } + case "ShareThumb": + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } + case "Style": + { + LocalLayoutFeedback.FireUpdate(); + break; + } - } - }; + } + }; Status.Call.Sharing.PropertyChanged += (o, a) => { @@ -690,11 +690,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void SetUpDirectory() { - DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" }; + DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" }; - CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root"); + CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root"); - CurrentDirectoryResult = DirectoryRoot; + CurrentDirectoryResult = DirectoryRoot; DirectoryBrowseHistory = new List(); DirectoryBrowseHistoryStack = new Stack(); @@ -709,7 +709,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // Set up output ports OutputPorts.Add(Output1); - OutputPorts.Add(Output2); + OutputPorts.Add(Output2); } /// @@ -967,12 +967,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("echo off"); Thread.Sleep(100); // set feedback exclusions - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); Thread.Sleep(100); SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list"); Thread.Sleep(100); - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); - Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); + Thread.Sleep(100); if (!_props.DisablePhonebookAutoDownload) { @@ -1063,13 +1063,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } case "phonebooklistresult": { - // This result will always be the complete contents of the directory and never - // A subset of the results via a search + // This result will always be the complete contents of the directory and never + // A subset of the results via a search JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); - var directoryResults = - zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); + var directoryResults = + zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); if (!PhonebookSyncState.InitialSyncComplete) { @@ -1079,12 +1079,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); } - if (directoryResults.ResultsFolderId != "root") - { - directoryResults.ResultsFolderId = "root"; - } + if (directoryResults.ResultsFolderId != "root") + { + directoryResults.ResultsFolderId = "root"; + } - DirectoryRoot = directoryResults; + DirectoryRoot = directoryResults; CurrentDirectoryResult = directoryResults; @@ -1114,7 +1114,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} **********************************", participant.Event); Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} - UserId: {1} Name: {2} IsHost: {3}", participant.Event, participant.UserId, participant.UserName, participant.IsHost); - + switch (participant.Event) { case "ZRCUserChangedEventUserInfoUpdated": @@ -1140,35 +1140,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } break; case "ZRCUserChangedEventJoinedMeeting": - { - var existingParticipant = - Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId)); - - // found matching participant.UserId - if (existingParticipant != null) { - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}", - participant.Event, participant.UserId, participant.UserName); - - JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant); - } - else - { - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}", - participant.Event, participant.UserId, participant.UserName); + var existingParticipant = + Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId)); + + if (existingParticipant != null) + { + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); - Status.Call.Participants.Add(participant); - - //var emptyList = new List(); - //Participants.CurrentParticipants = emptyList; - - //GetCurrentCallParticipants(); - } + JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant); + } + else + { + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); - break; - } + Status.Call.Participants.Add(participant); + } + + break; + } } - + Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ***********************************", participant.Event); } } @@ -1319,9 +1313,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (disconnectEvent.Successful) { if (ActiveCalls.Count > 0) - { + { var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); - + if (activeCall != null) { Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - ActiveCalls.Count: {0} activeCall.Id: {1}, activeCall.Number: {2} activeCall.Name: {3}, activeCall.IsActive: {4}", ActiveCalls.Count, activeCall.Id, activeCall.Number, activeCall.Name, activeCall.IsActiveCall); @@ -1329,11 +1323,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom OnCallStatusChange(activeCall); } - } - - var emptyList = new List(); - Participants.CurrentParticipants = emptyList; - //Participants.OnParticipantsChanged(); + } } Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************"); @@ -1388,24 +1378,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var status = responseObj.ToObject(); - Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); + Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); - Participant alreadyPinnedParticipant = null; + Participant alreadyPinnedParticipant = null; - // Check for a participant already pinned to the same screen index. - if (status.PinnedUserId > 0) - { - alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + // Check for a participant already pinned to the same screen index. + if (status.PinnedUserId > 0) + { + alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); - // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. - if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) - { - Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", - alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); - alreadyPinnedParticipant.IsPinnedFb = false; - alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; - } - } + // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. + if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) + { + Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", + alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); + alreadyPinnedParticipant.IsPinnedFb = false; + alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; + } + } var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); @@ -1425,7 +1415,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } else if (participant != null) { - Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex); + Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex); participant.IsPinnedFb = false; participant.ScreenIndexIsPinnedToFb = -1; } @@ -1475,7 +1465,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Participants participant.UserId: {0} participant.UserName: {1}", participant.UserId, participant.UserName); } - + UpdateCallStatus(); break; @@ -1571,27 +1561,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + /// + /// Retrieves the current call participants list + /// + public void GetCurrentCallParticipants() + { + SendText("zCommand Call ListParticipants"); + } + + /// + /// Prints the current call particiapnts list + /// public void PrintCurrentCallParticipants() { - if (Debug.Level <= 0) - { - return; - } + if (Debug.Level <= 0) return; Debug.Console(1, this, "*************************** Call Participants **************************"); foreach (var participant in Participants.CurrentParticipants) { - Debug.Console(1, this, "UserId: {3} Name: {0} Audio: {1} IsHost: {2}", + Debug.Console(1, this, "UserId: {3} Name: {0} Audio: {1} IsHost: {2}", participant.Name, participant.AudioMuteFb, participant.IsHost, participant.UserId); } Debug.Console(1, this, "************************************************************************"); } - public void GetCurrentCallParticipants() - { - SendText("zCommand Call ListParticipants"); - } - /// /// Retrieves bookings list /// @@ -1609,8 +1602,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", Status.Call != null ? Status.Call.Status.ToString() : "no call"); - //var emptyList = new List(); - if (Status.Call != null) { var callStatus = Status.Call.Status; @@ -1621,7 +1612,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object"); Status.Call = new zStatus.Call { Status = callStatus }; - OnCallStatusChange( new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected }); + OnCallStatusChange(new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected }); SetUpCallFeedbackActions(); } @@ -1635,7 +1626,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (callStatus) { - case zStatus.eCallStatus.CONNECTING_MEETING: + case zStatus.eCallStatus.CONNECTING_MEETING: newStatus = eCodecCallStatus.Connecting; break; case zStatus.eCallStatus.IN_MEETING: @@ -1654,8 +1645,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Type = eCodecCallType.Video, }; - //Participants.CurrentParticipants = emptyList; - ActiveCalls.Add(newCall); Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", @@ -1667,14 +1656,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); - - //Participants.CurrentParticipants = emptyList; } } } else { - var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); + var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing)); switch (callStatus) { @@ -1682,12 +1669,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom existingCall.Status = eCodecCallStatus.Connected; break; case zStatus.eCallStatus.NOT_IN_MEETING: - //Participants.CurrentParticipants = emptyList; existingCall.Status = eCodecCallStatus.Disconnected; - break; - //default: - // Participants.CurrentParticipants = emptyList; - // break; + break; } Debug.Console(1, this, "[UpdateCallStatus] ELSE ActiveCalls.Count == {1} - Current Call Status: {0}", @@ -1722,17 +1705,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "[UpdateCallStatus] Active Calls ------------------------------"); //clear participants list after call cleanup - if (ActiveCalls.Count == 0) - { - var emptyList = new List(); - Participants.CurrentParticipants = emptyList; - } - else - { - var emptyList = new List(); - Participants.CurrentParticipants = emptyList; - GetCurrentCallParticipants(); - } + var emptyList = new List(); + Participants.CurrentParticipants = emptyList; + if (ActiveCalls.Count > 0) GetCurrentCallParticipants(); } protected override void OnCallStatusChange(CodecActiveCallItem item) @@ -1785,7 +1760,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void MuteOff() { - Debug.Console(2, this, "Unmuting to previous level: {0}", _previousVolumeLevel); + Debug.Console(2, this, "Unmuting to previous level: {0}", _previousVolumeLevel); SetVolume((ushort)_previousVolumeLevel); } @@ -1877,7 +1852,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LinkVideoCodecToApi(this, trilist, joinMap); - LinkZoomRoomToApi(trilist, joinMap); + LinkZoomRoomToApi(trilist, joinMap); } /// @@ -1907,7 +1882,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetString(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip.ToString()); trilist.SetString(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll.ToString()); }; - + trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); @@ -1932,7 +1907,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }); - layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); + layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); } var pinCodec = this as IHasParticipantPinUnpin; @@ -1953,7 +1928,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { try { - var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); + var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); var cmd = SelfviewPipSizes.FirstOrDefault(c => c.Command.Equals(size.ToString())); SelfviewPipSizeSet(cmd); } @@ -1971,7 +1946,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (!args.DeviceOnLine) return; ComputeAvailableLayouts(); - layoutsCodec.LocalLayoutFeedback.FireUpdate(); + layoutsCodec.LocalLayoutFeedback.FireUpdate(); layoutsCodec.CanSwapContentWithThumbnailFeedback.FireUpdate(); layoutsCodec.ContentSwappedWithThumbnailFeedback.FireUpdate(); layoutsCodec.LayoutViewIsOnFirstPageFeedback.FireUpdate(); @@ -1979,7 +1954,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom pinCodec.NumberOfScreensFeedback.FireUpdate(); layoutSizeCodec.SelfviewPipSizeFeedback.FireUpdate(); }; - } + } public override void ExecuteSwitch(object selector) { @@ -2089,43 +2064,43 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// private void OnDirectoryResultReturned(CodecDirectory result) { - try - { - Debug.Console(2, this, "OnDirectoryResultReturned"); + try + { + Debug.Console(2, this, "OnDirectoryResultReturned"); - var directoryResult = new CodecDirectory(); + var directoryResult = new CodecDirectory(); - // If result is Root, create a copy and filter out contacts whose parent folder is not root - if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) - { - Debug.Console(2, this, "Filtering DirectoryRoot to remove contacts for display"); + // If result is Root, create a copy and filter out contacts whose parent folder is not root + if (!CurrentDirectoryResultIsNotDirectoryRoot.BoolValue) + { + Debug.Console(2, this, "Filtering DirectoryRoot to remove contacts for display"); - directoryResult.ResultsFolderId = result.ResultsFolderId; - directoryResult.AddFoldersToDirectory(result.Folders); - directoryResult.AddContactsToDirectory(result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList()); - } - else - { - directoryResult = result; - } + directoryResult.ResultsFolderId = result.ResultsFolderId; + directoryResult.AddFoldersToDirectory(result.Folders); + directoryResult.AddContactsToDirectory(result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList()); + } + else + { + directoryResult = result; + } - Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); - // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology - var handler = DirectoryResultReturned; - if (handler != null) - { - handler(this, new DirectoryEventArgs - { - Directory = directoryResult, - DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue - }); - } - } - catch (Exception e) - { - Debug.Console(2, this, "Error: {0}", e); - } + // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology + var handler = DirectoryResultReturned; + if (handler != null) + { + handler(this, new DirectoryEventArgs + { + Directory = directoryResult, + DirectoryIsOnRoot = !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue + }); + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error: {0}", e); + } //PrintDirectory(result); } @@ -2141,15 +2116,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom foreach (var cam in Status.Cameras) { - // Known Issue: - // Crestron UC engine systems seem to report an item in the cameras list that represnts the USB bridge device. - // If we know the name and it's reliably consistent, we could ignore it here... + // Known Issue: + // Crestron UC engine systems seem to report an item in the cameras list that represnts the USB bridge device. + // If we know the name and it's reliably consistent, we could ignore it here... - if (cam.Name.IndexOf("HD-CONV-USB") > -1) - { - // Skip this as it's the Crestron USB box, not a real camera - continue; - } + if (cam.Name.IndexOf("HD-CONV-USB") > -1) + { + // Skip this as it's the Crestron USB box, not a real camera + continue; + } var camera = new ZoomRoomCamera(cam.id, cam.Name, this); @@ -2517,7 +2492,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom availableLayouts |= zConfiguration.eLayoutStyle.Strip; } - Debug.Console(1, this, "availablelayouts: {0}", availableLayouts); + Debug.Console(1, this, "availablelayouts: {0}", availableLayouts); var handler = AvailableLayoutsChanged; if (handler != null) @@ -2564,68 +2539,68 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #region IHasCodecLayouts Members - private Func LocalLayoutFeedbackFunc - { - get - { - return () => - { - if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None) - return Configuration.Call.Layout.Style.ToString(); - else - return Configuration.Client.Call.Layout.Style.ToString(); - }; - } - } + private Func LocalLayoutFeedbackFunc + { + get + { + return () => + { + if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None) + return Configuration.Call.Layout.Style.ToString(); + else + return Configuration.Client.Call.Layout.Style.ToString(); + }; + } + } public StringFeedback LocalLayoutFeedback { get; private set; } public void LocalLayoutToggle() { - var currentLayout = LocalLayoutFeedback.StringValue; + var currentLayout = LocalLayoutFeedback.StringValue; - var eCurrentLayout = (int)Enum.Parse(typeof(zConfiguration.eLayoutStyle), currentLayout, true); + var eCurrentLayout = (int)Enum.Parse(typeof(zConfiguration.eLayoutStyle), currentLayout, true); - var nextLayout = GetNextLayout(eCurrentLayout); + var nextLayout = GetNextLayout(eCurrentLayout); - if (nextLayout != zConfiguration.eLayoutStyle.None) - { - SetLayout(nextLayout); - } + if (nextLayout != zConfiguration.eLayoutStyle.None) + { + SetLayout(nextLayout); + } } - /// - /// Tries to get the next available layout - /// - /// - /// - private zConfiguration.eLayoutStyle GetNextLayout(int currentLayout) - { - if (AvailableLayouts == zConfiguration.eLayoutStyle.None) - { - return zConfiguration.eLayoutStyle.None; - } + /// + /// Tries to get the next available layout + /// + /// + /// + private zConfiguration.eLayoutStyle GetNextLayout(int currentLayout) + { + if (AvailableLayouts == zConfiguration.eLayoutStyle.None) + { + return zConfiguration.eLayoutStyle.None; + } - zConfiguration.eLayoutStyle nextLayout; + zConfiguration.eLayoutStyle nextLayout; - if (((zConfiguration.eLayoutStyle)currentLayout & zConfiguration.eLayoutStyle.ShareAll) == zConfiguration.eLayoutStyle.ShareAll) - { - nextLayout = zConfiguration.eLayoutStyle.Gallery; - } - else - { - nextLayout = (zConfiguration.eLayoutStyle)(currentLayout << 1); - } + if (((zConfiguration.eLayoutStyle)currentLayout & zConfiguration.eLayoutStyle.ShareAll) == zConfiguration.eLayoutStyle.ShareAll) + { + nextLayout = zConfiguration.eLayoutStyle.Gallery; + } + else + { + nextLayout = (zConfiguration.eLayoutStyle)(currentLayout << 1); + } - if ((AvailableLayouts & nextLayout) == nextLayout) - { - return nextLayout; - } - else - { - return GetNextLayout((int)nextLayout); - } - } + if ((AvailableLayouts & nextLayout) == nextLayout) + { + return nextLayout; + } + else + { + return GetNextLayout((int)nextLayout); + } + } public void LocalLayoutToggleSingleProminent() { @@ -2635,7 +2610,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void MinMaxLayoutToggle() { throw new NotImplementedException(); - } + } #endregion From 3fa2954ca06db3a41b9c3d42c6ad7db768a92232 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 17 Aug 2021 16:46:24 -0500 Subject: [PATCH 324/480] style: Updated formatting for ZoomRoom.cs and IHasParticipants.cs --- .../VideoCodec/Interfaces/IHasParticipants.cs | 6 - .../VideoCodec/ZoomRoom/ZoomRoom.cs | 1352 +++++++++-------- 2 files changed, 705 insertions(+), 653 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index 361e0cae..d8c0c55c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -56,10 +56,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces set { _currentParticipants = value; - foreach (var participant in _currentParticipants) - { - Debug.Console(1, "[CurrentParticipants] participant UserId: {0} Name: {1} IsHost: {2}", participant.UserId, participant.Name, participant.IsHost); - } OnParticipantsChanged(); } } @@ -75,8 +71,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { var handler = ParticipantsListHasChanged; - Debug.Console(1, "[OnParticipantsChanged] Event Fired - handler is {0}", handler == null ? "null" : "not null"); - if (handler == null) return; handler(this, new EventArgs()); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 0e1d31fb..701ce6f2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1,16 +1,13 @@ using System; using System.Collections.Generic; -using System.IO.Ports; using System.Linq; using System.Text; using Crestron.SimplSharp; -using Crestron.SimplSharp.Reflection; using Crestron.SimplSharpPro.CrestronThread; using Crestron.SimplSharpPro.DeviceSupport; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PepperDash.Core; -using PepperDash.Core.Intersystem.Tokens; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; @@ -27,7 +24,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor, IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, - IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, IHasParticipantAudioMute, IHasSelfviewSize + IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, + IHasParticipantAudioMute, IHasSelfviewSize { private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; @@ -84,7 +82,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom PhonebookSyncState = new CodecPhonebookSyncState(Key + "--PhonebookSync"); - PortGather = new CommunicationGather(Communication, "\x0A") { IncludeDelimiter = true }; + PortGather = new CommunicationGather(Communication, "\x0A") {IncludeDelimiter = true}; PortGather.LineReceived += Port_LineReceived; CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, @@ -124,7 +122,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants = new CodecParticipants(); - SupportsCameraOff = true; // Always allow turning off the camera for zoom calls? + SupportsCameraOff = true; // Always allow turning off the camera for zoom calls? SupportsCameraAutoMode = _props.SupportsCameraAutoMode; PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc); @@ -139,7 +137,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); - } public CommunicationGather PortGather { get; private set; } @@ -164,7 +161,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (Configuration.Audio.Output.Volume != 0) { - Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, scaledVol); + Debug.Console(2, this, "Storing previous volume level as: {0}, scaled: {1}", Configuration.Audio.Output.Volume, + scaledVol); _previousVolumeLevel = scaledVol; // Store the previous level for recall } @@ -371,7 +369,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { _currentDirectoryResult = value; - Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", _currentDirectoryResult.ResultsFolderId); + Debug.Console(2, this, "CurrentDirectoryResult Updated. ResultsFolderId: {0}", + _currentDirectoryResult.ResultsFolderId); CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); @@ -391,12 +390,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom DirectoryBrowseHistoryStack.Clear(); CurrentDirectoryResult = directoryResults; - } public void GetDirectoryFolderContents(string folderId) { - var directoryResults = new CodecDirectory { ResultsFolderId = folderId }; + var directoryResults = new CodecDirectory {ResultsFolderId = folderId}; directoryResults.AddContactsToDirectory( DirectoryRoot.CurrentDirectoryResults.FindAll(c => c.ParentFolderId.Equals(folderId))); @@ -404,7 +402,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom DirectoryBrowseHistoryStack.Push(_currentDirectoryResult); CurrentDirectoryResult = directoryResults; - } public void SetCurrentDirectoryToRoot() @@ -535,33 +532,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (a.PropertyName) { case "Position": - { - ComputeSelfviewPipPositionStatus(); + { + ComputeSelfviewPipPositionStatus(); - SelfviewPipPositionFeedback.FireUpdate(); + SelfviewPipPositionFeedback.FireUpdate(); - break; - } + break; + } case "ShareThumb": - { - ContentSwappedWithThumbnailFeedback.FireUpdate(); - break; - } + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } case "Style": - { - LocalLayoutFeedback.FireUpdate(); - break; - } + { + LocalLayoutFeedback.FireUpdate(); + break; + } case "Size": - { - // TODO: #714 [ ] SetupFeedbackActions >> Size - ComputeSelfviewPipSizeStatus(); + { + // TODO: #714 [ ] SetupFeedbackActions >> Size + ComputeSelfviewPipSizeStatus(); - SelfviewPipSizeFeedback.FireUpdate(); - - break; - } + SelfviewPipSizeFeedback.FireUpdate(); + break; + } } }; @@ -571,24 +567,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (a.PropertyName) { case "Position": - { - ComputeSelfviewPipPositionStatus(); + { + ComputeSelfviewPipPositionStatus(); - SelfviewPipPositionFeedback.FireUpdate(); + SelfviewPipPositionFeedback.FireUpdate(); - break; - } + break; + } case "ShareThumb": - { - ContentSwappedWithThumbnailFeedback.FireUpdate(); - break; - } + { + ContentSwappedWithThumbnailFeedback.FireUpdate(); + break; + } case "Style": - { - LocalLayoutFeedback.FireUpdate(); - break; - } - + { + LocalLayoutFeedback.FireUpdate(); + break; + } } }; @@ -652,45 +647,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "can_switch_speaker_view": case "can_switch_wall_view": case "can_switch_share_on_all_screens": - { - ComputeAvailableLayouts(); - break; - } + { + ComputeAvailableLayouts(); + break; + } case "is_in_first_page": - { - LayoutViewIsOnFirstPageFeedback.FireUpdate(); - break; - } + { + LayoutViewIsOnFirstPageFeedback.FireUpdate(); + break; + } case "is_in_last_page": - { - LayoutViewIsOnLastPageFeedback.FireUpdate(); - break; - } - //case "video_type": - // { - // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style - // LocalLayoutFeedback.FireUpdate(); - // break; - // } + { + LayoutViewIsOnLastPageFeedback.FireUpdate(); + break; + } + //case "video_type": + // { + // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style + // LocalLayoutFeedback.FireUpdate(); + // break; + // } } }; Status.NumberOfScreens.PropertyChanged += (o, a) => + { + switch (a.PropertyName) { - switch (a.PropertyName) + case "NumberOfScreens": { - case "NumberOfScreens": - { - NumberOfScreensFeedback.FireUpdate(); - break; - } + NumberOfScreensFeedback.FireUpdate(); + break; } - }; + } + }; } private void SetUpDirectory() { - DirectoryRoot = new CodecDirectory() { ResultsFolderId = "root" }; + DirectoryRoot = new CodecDirectory() {ResultsFolderId = "root"}; CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult.ResultsFolderId != "root"); @@ -698,7 +693,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom DirectoryBrowseHistory = new List(); DirectoryBrowseHistoryStack = new Stack(); - } private void SetUpRouting() @@ -896,7 +890,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //Debug.Console(2, this, "JSON Curly Brace Count: {0}", _jsonCurlyBraceCounter); if (!_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "{" + Delimiter) - // Check for the beginning of a new JSON message + // Check for the beginning of a new JSON message { _jsonFeedbackMessageIsIncoming = true; _jsonCurlyBraceCounter = 1; // reset the counter for each new message @@ -913,7 +907,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom return; } if (_jsonFeedbackMessageIsIncoming && message.Trim('\x20') == "}" + Delimiter) - // Check for the end of a JSON message + // Check for the end of a JSON message { _jsonMessage.Append(message); @@ -956,34 +950,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (message.Trim().ToLower()) // remove the whitespace { case "*r login successful": + { + _syncState.LoginMessageReceived(); + + // Fire up a thread to send the intial commands. + CrestronInvoke.BeginInvoke(o => { - _syncState.LoginMessageReceived(); + Thread.Sleep(100); + // disable echo of commands + SendText("echo off"); + Thread.Sleep(100); + // set feedback exclusions + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); + Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list"); + Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); + Thread.Sleep(100); - // Fire up a thread to send the intial commands. - CrestronInvoke.BeginInvoke(o => + if (!_props.DisablePhonebookAutoDownload) { - Thread.Sleep(100); - // disable echo of commands - SendText("echo off"); - Thread.Sleep(100); - // set feedback exclusions - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callin_country_list"); - Thread.Sleep(100); - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/callout_country_list"); - Thread.Sleep(100); - SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); - Thread.Sleep(100); + SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact"); + } + // switch to json format + SendText("format json"); + }); - if (!_props.DisablePhonebookAutoDownload) - { - SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact"); - } - // switch to json format - SendText("format json"); - }); - - break; - } + break; + } } } } @@ -1007,7 +1001,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var eType = (eZoomRoomResponseType) - Enum.Parse(typeof(eZoomRoomResponseType), message["type"].Value(), true); + Enum.Parse(typeof (eZoomRoomResponseType), message["type"].Value(), true); var topKey = message["topKey"].Value(); @@ -1018,523 +1012,545 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (eType) { case eZoomRoomResponseType.zConfiguration: + { + switch (topKey.ToLower()) { - switch (topKey.ToLower()) + case "call": { - case "call": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Call); + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Call); - break; - } - case "audio": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Audio); - - break; - } - case "video": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Video); - - break; - } - case "client": - { - JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Client); - - break; - } - default: - { - break; - } + break; + } + case "audio": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Audio); + + break; + } + case "video": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Video); + + break; + } + case "client": + { + JsonConvert.PopulateObject(responseObj.ToString(), Configuration.Client); + + break; + } + default: + { + break; } - break; } + break; + } case eZoomRoomResponseType.zCommand: + { + switch (topKey.ToLower()) { - switch (topKey.ToLower()) + case "inforesult": { - case "inforesult": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info); - break; - } - case "phonebooklistresult": - { - // This result will always be the complete contents of the directory and never - // A subset of the results via a search - - JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); - - var directoryResults = - zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); - - if (!PhonebookSyncState.InitialSyncComplete) - { - PhonebookSyncState.InitialPhonebookFoldersReceived(); - PhonebookSyncState.PhonebookRootEntriesReceived(); - PhonebookSyncState.SetPhonebookHasFolders(true); - PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); - } - - if (directoryResults.ResultsFolderId != "root") - { - directoryResults.ResultsFolderId = "root"; - } - - DirectoryRoot = directoryResults; - - CurrentDirectoryResult = directoryResults; - - break; - } - case "listparticipantsresult": - { - Debug.Console(1, this, "JTokenType: {0}", responseObj.Type); - - switch (responseObj.Type) - { - case JTokenType.Array: - Status.Call.Participants = - JsonConvert.DeserializeObject>( - responseObj.ToString()); - break; - case JTokenType.Object: - { - // this is a single participant event notification - - var participant = - JsonConvert.DeserializeObject( - responseObj.ToString()); - - if (participant != null) - { - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} **********************************", participant.Event); - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} - UserId: {1} Name: {2} IsHost: {3}", - participant.Event, participant.UserId, participant.UserName, participant.IsHost); - - switch (participant.Event) - { - case "ZRCUserChangedEventUserInfoUpdated": - case "ZRCUserChangedEventLeftMeeting": - { - var existingParticipant = - Status.Call.Participants.FirstOrDefault( - p => p.UserId.Equals(participant.UserId)); - - if (existingParticipant != null) - { - switch (participant.Event) - { - case "ZRCUserChangedEventLeftMeeting": - Status.Call.Participants.Remove(existingParticipant); - break; - case "ZRCUserChangedEventUserInfoUpdated": - JsonConvert.PopulateObject(responseObj.ToString(), - existingParticipant); - break; - } - } - } - break; - case "ZRCUserChangedEventJoinedMeeting": - { - var existingParticipant = - Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId)); - - if (existingParticipant != null) - { - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}", - participant.Event, participant.UserId, participant.UserName); - - JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant); - } - else - { - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}", - participant.Event, participant.UserId, participant.UserName); - - Status.Call.Participants.Add(participant); - } - - break; - } - } - - Debug.Console(1, this, "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ***********************************", participant.Event); - } - } - break; - } - - var participants = - zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult( - Status.Call.Participants); - - Participants.CurrentParticipants = participants; - PrintCurrentCallParticipants(); - - break; - } - default: - { - break; - } + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Info); + break; } - break; - } - case eZoomRoomResponseType.zEvent: - { - switch (topKey.ToLower()) + case "phonebooklistresult": { - case "phonebook": - { - if (responseObj["Updated Contact"] != null) - { - var updatedContact = - JsonConvert.DeserializeObject( - responseObj["Updated Contact"].ToString()); + // This result will always be the complete contents of the directory and never + // A subset of the results via a search - var existingContact = - Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid)); + JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook); - if (existingContact != null) - { - // Update existing contact - JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(), - existingContact); - } - } - else if (responseObj["Added Contact"] != null) - { - var jToken = responseObj["Updated Contact"]; - if (jToken != null) - { - var newContact = - JsonConvert.DeserializeObject( - jToken.ToString()); + var directoryResults = + zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts); - // Add a new contact - Status.Phonebook.Contacts.Add(newContact); - } - } + if (!PhonebookSyncState.InitialSyncComplete) + { + PhonebookSyncState.InitialPhonebookFoldersReceived(); + PhonebookSyncState.PhonebookRootEntriesReceived(); + PhonebookSyncState.SetPhonebookHasFolders(true); + PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count); + } + if (directoryResults.ResultsFolderId != "root") + { + directoryResults.ResultsFolderId = "root"; + } + + DirectoryRoot = directoryResults; + + CurrentDirectoryResult = directoryResults; + + break; + } + case "listparticipantsresult": + { + Debug.Console(1, this, "JTokenType: {0}", responseObj.Type); + + switch (responseObj.Type) + { + case JTokenType.Array: + Status.Call.Participants = + JsonConvert.DeserializeObject>( + responseObj.ToString()); break; - } - case "bookingslistresult": + case JTokenType.Object: { - if (!_syncState.InitialSyncComplete) - { - _syncState.LastQueryResponseReceived(); - } + // this is a single participant event notification - var codecBookings = JsonConvert.DeserializeObject>( - responseObj.ToString()); - - if (codecBookings != null && codecBookings.Count > 0) - { - CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( - codecBookings, CodecSchedule.MeetingWarningMinutes); - } - - break; - } - case "bookings updated": - { - GetBookings(); - - break; - } - case "sharingstate": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing); - - SetLayout(); - - break; - } - case "incomingcallindication": - { - var incomingCall = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (incomingCall != null) - { - var newCall = new CodecActiveCallItem - { - Direction = eCodecCallDirection.Incoming, - Status = eCodecCallStatus.Ringing, - Type = eCodecCallType.Video, - Name = incomingCall.callerName, - Id = incomingCall.callerJID - }; - - ActiveCalls.Add(newCall); - - OnCallStatusChange(newCall); - } - - break; - } - case "treatedincomingcallindication": - { - var incomingCall = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (incomingCall != null) - { - var existingCall = - ActiveCalls.FirstOrDefault(c => c.Id.Equals(incomingCall.callerJID)); - - if (existingCall != null) - { - existingCall.Status = !incomingCall.accepted - ? eCodecCallStatus.Disconnected - : eCodecCallStatus.Connecting; - - OnCallStatusChange(existingCall); - } - - UpdateCallStatus(); - } - - break; - } - case "calldisconnect": - { - var disconnectEvent = - JsonConvert.DeserializeObject(responseObj.ToString()); - - Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************"); - Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - disconnectEvent.Successful: {0}", disconnectEvent.Successful); - - if (disconnectEvent.Successful) - { - if (ActiveCalls.Count > 0) - { - var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); - - if (activeCall != null) - { - Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - ActiveCalls.Count: {0} activeCall.Id: {1}, activeCall.Number: {2} activeCall.Name: {3}, activeCall.IsActive: {4}", ActiveCalls.Count, activeCall.Id, activeCall.Number, activeCall.Name, activeCall.IsActiveCall); - activeCall.Status = eCodecCallStatus.Disconnected; - - OnCallStatusChange(activeCall); - } - } - } - - Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect ********************************************"); - - UpdateCallStatus(); - break; - } - case "callconnecterror": - { - UpdateCallStatus(); - break; - } - case "videounmuterequest": - { - // TODO: notify room of a request to unmute video - break; - } - case "meetingneedspassword": - { - // TODO: notify user to enter a password - break; - } - case "needwaitforhost": - { - var needWait = - JsonConvert.DeserializeObject(responseObj.ToString()); - - if (needWait.Wait) - { - // TODO: notify user to wait for host - } - - break; - } - case "openvideofailforhoststop": - { - // TODO: notify user that host has disabled unmuting video - break; - } - case "updatedcallrecordinfo": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.CallRecordInfo); - - break; - } - case "phonecallstatus": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall); - break; - } - case "pinstatusofscreennotification": - { - var status = responseObj.ToObject(); - - Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, status.ScreenIndex); - - Participant alreadyPinnedParticipant = null; - - // Check for a participant already pinned to the same screen index. - if (status.PinnedUserId > 0) - { - alreadyPinnedParticipant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); - - // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. - if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) - { - Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", - alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); - alreadyPinnedParticipant.IsPinnedFb = false; - alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; - } - } - - var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); + var participant = + JsonConvert.DeserializeObject( + responseObj.ToString()); if (participant != null) { - participant.IsPinnedFb = true; - participant.ScreenIndexIsPinnedToFb = status.ScreenIndex; - } - else - { - participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + Debug.Console(1, this, + "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} **********************************", + participant.Event); + Debug.Console(1, this, + "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} - UserId: {1} Name: {2} IsHost: {3}", + participant.Event, participant.UserId, participant.UserName, participant.IsHost); - if (participant == null && alreadyPinnedParticipant == null) + switch (participant.Event) { - Debug.Console(1, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex); - return; - } - else if (participant != null) - { - Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, participant.UserId, status.ScreenIndex); - participant.IsPinnedFb = false; - participant.ScreenIndexIsPinnedToFb = -1; + case "ZRCUserChangedEventUserInfoUpdated": + case "ZRCUserChangedEventLeftMeeting": + { + var existingParticipant = + Status.Call.Participants.FirstOrDefault( + p => p.UserId.Equals(participant.UserId)); + + if (existingParticipant != null) + { + switch (participant.Event) + { + case "ZRCUserChangedEventLeftMeeting": + Status.Call.Participants.Remove(existingParticipant); + break; + case "ZRCUserChangedEventUserInfoUpdated": + JsonConvert.PopulateObject(responseObj.ToString(), + existingParticipant); + break; + } + } + } + break; + case "ZRCUserChangedEventJoinedMeeting": + { + var existingParticipant = + Status.Call.Participants.FirstOrDefault(p => p.UserId.Equals(participant.UserId)); + + if (existingParticipant != null) + { + Debug.Console(1, this, + "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...updating matching UserId participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); + + JsonConvert.PopulateObject(responseObj.ToString(), existingParticipant); + } + else + { + Debug.Console(1, this, + "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ...adding participant with UserId: {1} UserName: {2}", + participant.Event, participant.UserId, participant.UserName); + + Status.Call.Participants.Add(participant); + } + + break; + } } + + Debug.Console(1, this, + "[DeserializeResponse] zCommands.listparticipantresult - participant.event: {0} ***********************************", + participant.Event); } - - // fire the event as we've modified the participants list - Participants.OnParticipantsChanged(); - - break; } - default: - { break; - } + } + + var participants = + zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult( + Status.Call.Participants); + + Participants.CurrentParticipants = participants; + PrintCurrentCallParticipants(); + + break; } - break; - } - case eZoomRoomResponseType.zStatus: - { - switch (topKey.ToLower()) + default: { - case "login": - { - _syncState.LoginMessageReceived(); - - if (!_syncState.InitialQueryMessagesWereSent) - { - SetUpSyncQueries(); - } - - JsonConvert.PopulateObject(responseObj.ToString(), Status.Login); - - break; - } - case "systemunit": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.SystemUnit); - - break; - } - case "call": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Call); - - Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Info.meeting_id: {0} Status.Call.Info.meeting_list_item.meetingName: {1}", Status.Call.Info.meeting_id, Status.Call.Info.meeting_list_item.meetingName); - foreach (var participant in Status.Call.Participants) - { - Debug.Console(1, this, "[DeserializeResponse] zStatus.call - Status.Call.Participants participant.UserId: {0} participant.UserName: {1}", participant.UserId, participant.UserName); - } - - UpdateCallStatus(); - - break; - } - case "capabilities": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Capabilities); - break; - } - case "sharing": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Sharing); - - break; - } - case "numberofscreens": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.NumberOfScreens); - break; - } - case "video": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Video); - break; - } - case "camerashare": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.CameraShare); - break; - } - case "layout": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Layout); - break; - } - case "audio input line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioInputs); - break; - } - case "audio output line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioOuputs); - break; - } - case "video camera line": - { - JsonConvert.PopulateObject(responseObj.ToString(), Status.Cameras); - - if (!_syncState.CamerasHaveBeenSetUp) - { - SetUpCameras(); - } - - break; - } - default: - { - break; - } + break; } - - break; } - default: + break; + } + case eZoomRoomResponseType.zEvent: + { + switch (topKey.ToLower()) { - Debug.Console(1, "Unknown Response Type:"); - break; + case "phonebook": + { + if (responseObj["Updated Contact"] != null) + { + var updatedContact = + JsonConvert.DeserializeObject( + responseObj["Updated Contact"].ToString()); + + var existingContact = + Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid)); + + if (existingContact != null) + { + // Update existing contact + JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(), + existingContact); + } + } + else if (responseObj["Added Contact"] != null) + { + var jToken = responseObj["Updated Contact"]; + if (jToken != null) + { + var newContact = + JsonConvert.DeserializeObject( + jToken.ToString()); + + // Add a new contact + Status.Phonebook.Contacts.Add(newContact); + } + } + + break; + } + case "bookingslistresult": + { + if (!_syncState.InitialSyncComplete) + { + _syncState.LastQueryResponseReceived(); + } + + var codecBookings = JsonConvert.DeserializeObject>( + responseObj.ToString()); + + if (codecBookings != null && codecBookings.Count > 0) + { + CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( + codecBookings, CodecSchedule.MeetingWarningMinutes); + } + + break; + } + case "bookings updated": + { + GetBookings(); + + break; + } + case "sharingstate": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.Sharing); + + SetLayout(); + + break; + } + case "incomingcallindication": + { + var incomingCall = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (incomingCall != null) + { + var newCall = new CodecActiveCallItem + { + Direction = eCodecCallDirection.Incoming, + Status = eCodecCallStatus.Ringing, + Type = eCodecCallType.Video, + Name = incomingCall.callerName, + Id = incomingCall.callerJID + }; + + ActiveCalls.Add(newCall); + + OnCallStatusChange(newCall); + } + + break; + } + case "treatedincomingcallindication": + { + var incomingCall = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (incomingCall != null) + { + var existingCall = + ActiveCalls.FirstOrDefault(c => c.Id.Equals(incomingCall.callerJID)); + + if (existingCall != null) + { + existingCall.Status = !incomingCall.accepted + ? eCodecCallStatus.Disconnected + : eCodecCallStatus.Connecting; + + OnCallStatusChange(existingCall); + } + + UpdateCallStatus(); + } + + break; + } + case "calldisconnect": + { + var disconnectEvent = + JsonConvert.DeserializeObject(responseObj.ToString()); + + Debug.Console(1, this, + "[DeserializeResponse] zEvent.calldisconnect ********************************************"); + Debug.Console(1, this, "[DeserializeResponse] zEvent.calldisconnect - disconnectEvent.Successful: {0}", + disconnectEvent.Successful); + + if (disconnectEvent.Successful) + { + if (ActiveCalls.Count > 0) + { + var activeCall = ActiveCalls.FirstOrDefault(c => c.IsActiveCall); + + if (activeCall != null) + { + Debug.Console(1, this, + "[DeserializeResponse] zEvent.calldisconnect - ActiveCalls.Count: {0} activeCall.Id: {1}, activeCall.Number: {2} activeCall.Name: {3}, activeCall.IsActive: {4}", + ActiveCalls.Count, activeCall.Id, activeCall.Number, activeCall.Name, activeCall.IsActiveCall); + activeCall.Status = eCodecCallStatus.Disconnected; + + OnCallStatusChange(activeCall); + } + } + } + + Debug.Console(1, this, + "[DeserializeResponse] zEvent.calldisconnect ********************************************"); + + UpdateCallStatus(); + break; + } + case "callconnecterror": + { + UpdateCallStatus(); + break; + } + case "videounmuterequest": + { + // TODO: notify room of a request to unmute video + break; + } + case "meetingneedspassword": + { + // TODO: notify user to enter a password + break; + } + case "needwaitforhost": + { + var needWait = + JsonConvert.DeserializeObject(responseObj.ToString()); + + if (needWait.Wait) + { + // TODO: notify user to wait for host + } + + break; + } + case "openvideofailforhoststop": + { + // TODO: notify user that host has disabled unmuting video + break; + } + case "updatedcallrecordinfo": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call.CallRecordInfo); + + break; + } + case "phonecallstatus": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall); + break; + } + case "pinstatusofscreennotification": + { + var status = responseObj.ToObject(); + + Debug.Console(1, this, "Pin Status notification for UserId: {0}, ScreenIndex: {1}", status.PinnedUserId, + status.ScreenIndex); + + Participant alreadyPinnedParticipant = null; + + // Check for a participant already pinned to the same screen index. + if (status.PinnedUserId > 0) + { + alreadyPinnedParticipant = + Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + // Make sure that the already pinned participant isn't the same ID as for this message. If true, clear the pinned fb. + if (alreadyPinnedParticipant != null && alreadyPinnedParticipant.UserId != status.PinnedUserId) + { + Debug.Console(1, this, "Participant: {0} with id: {1} already pinned to screenIndex {2}. Clearing pinned fb.", + alreadyPinnedParticipant.Name, alreadyPinnedParticipant.UserId, + alreadyPinnedParticipant.ScreenIndexIsPinnedToFb); + alreadyPinnedParticipant.IsPinnedFb = false; + alreadyPinnedParticipant.ScreenIndexIsPinnedToFb = -1; + } + } + + var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId)); + + if (participant != null) + { + participant.IsPinnedFb = true; + participant.ScreenIndexIsPinnedToFb = status.ScreenIndex; + } + else + { + participant = + Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex)); + + if (participant == null && alreadyPinnedParticipant == null) + { + Debug.Console(1, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", + status.PinnedUserId, status.ScreenIndex); + return; + } + else if (participant != null) + { + Debug.Console(2, this, "Unpinning {0} with id: {1} from screen index: {2}", participant.Name, + participant.UserId, status.ScreenIndex); + participant.IsPinnedFb = false; + participant.ScreenIndexIsPinnedToFb = -1; + } + } + + // fire the event as we've modified the participants list + Participants.OnParticipantsChanged(); + + break; + } + default: + { + break; + } } + break; + } + case eZoomRoomResponseType.zStatus: + { + switch (topKey.ToLower()) + { + case "login": + { + _syncState.LoginMessageReceived(); + + if (!_syncState.InitialQueryMessagesWereSent) + { + SetUpSyncQueries(); + } + + JsonConvert.PopulateObject(responseObj.ToString(), Status.Login); + + break; + } + case "systemunit": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.SystemUnit); + + break; + } + case "call": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Call); + + Debug.Console(1, this, + "[DeserializeResponse] zStatus.call - Status.Call.Info.meeting_id: {0} Status.Call.Info.meeting_list_item.meetingName: {1}", + Status.Call.Info.meeting_id, Status.Call.Info.meeting_list_item.meetingName); + foreach (var participant in Status.Call.Participants) + { + Debug.Console(1, this, + "[DeserializeResponse] zStatus.call - Status.Call.Participants participant.UserId: {0} participant.UserName: {1}", + participant.UserId, participant.UserName); + } + + UpdateCallStatus(); + + break; + } + case "capabilities": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Capabilities); + break; + } + case "sharing": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Sharing); + + break; + } + case "numberofscreens": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.NumberOfScreens); + break; + } + case "video": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Video); + break; + } + case "camerashare": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.CameraShare); + break; + } + case "layout": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Layout); + break; + } + case "audio input line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioInputs); + break; + } + case "audio output line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.AudioOuputs); + break; + } + case "video camera line": + { + JsonConvert.PopulateObject(responseObj.ToString(), Status.Cameras); + + if (!_syncState.CamerasHaveBeenSetUp) + { + SetUpCameras(); + } + + break; + } + default: + { + break; + } + } + + break; + } + default: + { + Debug.Console(1, "Unknown Response Type:"); + break; + } } } catch (Exception ex) @@ -1610,9 +1626,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING) { Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object"); - Status.Call = new zStatus.Call { Status = callStatus }; + Status.Call = new zStatus.Call {Status = callStatus}; - OnCallStatusChange(new CodecActiveCallItem() { Status = eCodecCallStatus.Disconnected }); + OnCallStatusChange(new CodecActiveCallItem() {Status = eCodecCallStatus.Disconnected}); SetUpCallFeedbackActions(); } @@ -1620,7 +1636,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (ActiveCalls.Count == 0) { if (callStatus == zStatus.eCallStatus.CONNECTING_MEETING || - callStatus == zStatus.eCallStatus.IN_MEETING) + callStatus == zStatus.eCallStatus.IN_MEETING) { var newStatus = eCodecCallStatus.Unknown; @@ -1694,7 +1710,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IsActive: {2} Status: {3} Direction: {4} - IsActiveCall: {6}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction, call.Number, call.IsActiveCall); + IsActiveCall: {6}", call.Name, call.Id, call.IsActiveCall, call.Status, call.Direction, call.Number, + call.IsActiveCall); if (!call.IsActiveCall) { @@ -1761,12 +1778,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void MuteOff() { Debug.Console(2, this, "Unmuting to previous level: {0}", _previousVolumeLevel); - SetVolume((ushort)_previousVolumeLevel); + SetVolume((ushort) _previousVolumeLevel); } public override void MuteOn() { - SetVolume(0); } @@ -1868,13 +1884,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutsCodec.AvailableLayoutsChanged += (o, a) => { trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); + == + (a.AvailableLayouts & + zConfiguration.eLayoutStyle.Gallery)); trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); + == + (a.AvailableLayouts & + zConfiguration.eLayoutStyle.Speaker)); trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); + == + (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.ShareAll - == (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll)); + == + (a.AvailableLayouts & + zConfiguration.eLayoutStyle.ShareAll)); // pass the names used to set the layout through the bridge trilist.SetString(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery.ToString()); @@ -1885,27 +1908,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail()); - layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); - layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); + layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]); + layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]); - layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); + layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]); layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]); trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage()); trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage()); trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts()); trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) => + { + try { - try - { - var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true); - SetLayout(style); - } - catch (Exception e) - { - Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); - } - }); + var style = (zConfiguration.eLayoutStyle) Enum.Parse(typeof (zConfiguration.eLayoutStyle), s, true); + SetLayout(style); + } + catch (Exception e) + { + Debug.Console(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e); + } + }); layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]); } @@ -1928,7 +1954,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { try { - var size = (zConfiguration.eLayoutSize)Enum.Parse(typeof(zConfiguration.eLayoutSize), s, true); + var size = (zConfiguration.eLayoutSize) Enum.Parse(typeof (zConfiguration.eLayoutSize), s, true); var cmd = SelfviewPipSizes.FirstOrDefault(c => c.Command.Equals(size.ToString())); SelfviewPipSizeSet(cmd); } @@ -2077,14 +2103,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom directoryResult.ResultsFolderId = result.ResultsFolderId; directoryResult.AddFoldersToDirectory(result.Folders); - directoryResult.AddContactsToDirectory(result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList()); + directoryResult.AddContactsToDirectory( + result.Contacts.Where((c) => c.ParentFolderId == result.ResultsFolderId).ToList()); } else { directoryResult = result; } - Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + Debug.Console(2, this, "Updating directoryResult. IsOnRoot: {0}", + !CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology var handler = DirectoryResultReturned; @@ -2228,7 +2256,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #region IHasParticipantPinUnpin Members - private Func NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } } + private Func NumberOfScreensFeedbackFunc + { + get { return () => Status.NumberOfScreens.NumOfScreens; } + } public IntFeedback NumberOfScreensFeedback { get; private set; } @@ -2353,12 +2384,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } public List SelfviewPipPositions = new List() - { - new CodecCommandWithLabel("UpLeft", "Center Left"), - new CodecCommandWithLabel("UpRight", "Center Right"), - new CodecCommandWithLabel("DownRight", "Lower Right"), - new CodecCommandWithLabel("DownLeft", "Lower Left") - }; + { + new CodecCommandWithLabel("UpLeft", "Center Left"), + new CodecCommandWithLabel("UpRight", "Center Right"), + new CodecCommandWithLabel("DownRight", "Lower Right"), + new CodecCommandWithLabel("DownLeft", "Lower Left") + }; private void ComputeSelfviewPipPositionStatus() { @@ -2370,6 +2401,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #endregion // TODO: #714 [ ] Implementation of IHasSelfviewPipSize + #region Implementation of IHasSelfviewPipSize private CodecCommandWithLabel _currentSelfviewPipSize; @@ -2396,13 +2428,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } public List SelfviewPipSizes = new List() - { - new CodecCommandWithLabel("Off", "Off"), - new CodecCommandWithLabel("Size1", "Size 1"), - new CodecCommandWithLabel("Size2", "Size 2"), - new CodecCommandWithLabel("Size3", "Size 3"), + { + new CodecCommandWithLabel("Off", "Off"), + new CodecCommandWithLabel("Size1", "Size 1"), + new CodecCommandWithLabel("Size2", "Size 2"), + new CodecCommandWithLabel("Size3", "Size 3"), new CodecCommandWithLabel("Strip", "Strip") - }; + }; private void ComputeSelfviewPipSizeStatus() { @@ -2411,14 +2443,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom p => p.Command.ToLower().Equals(Configuration.Call.Layout.Size.ToString().ToLower())); } - #endregion #region Implementation of IHasPhoneDialing - private Func PhoneOffHookFeedbackFunc { get { return () => Status.PhoneCall.OffHook; } } - private Func CallerIdNameFeedbackFunc { get { return () => Status.PhoneCall.PeerDisplayName; } } - private Func CallerIdNumberFeedbackFunc { get { return () => Status.PhoneCall.PeerNumber; } } + private Func PhoneOffHookFeedbackFunc + { + get { return () => Status.PhoneCall.OffHook; } + } + + private Func CallerIdNameFeedbackFunc + { + get { return () => Status.PhoneCall.PeerDisplayName; } + } + + private Func CallerIdNumberFeedbackFunc + { + get { return () => Status.PhoneCall.PeerNumber; } + } public BoolFeedback PhoneOffHookFeedback { get; private set; } public StringFeedback CallerIdNameFeedback { get; private set; } @@ -2445,10 +2487,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public event EventHandler AvailableLayoutsChanged; - private Func LayoutViewIsOnFirstPageFeedbackFunc { get { return () => Status.Layout.is_In_First_Page; } } - private Func LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } } - private Func CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } } - private Func ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } } + private Func LayoutViewIsOnFirstPageFeedbackFunc + { + get { return () => Status.Layout.is_In_First_Page; } + } + + private Func LayoutViewIsOnLastPageFeedbackFunc + { + get { return () => Status.Layout.is_In_Last_Page; } + } + + private Func CanSwapContentWithThumbnailFeedbackFunc + { + get { return () => Status.Layout.can_Switch_Floating_Share_Content; } + } + + private Func ContentSwappedWithThumbnailFeedbackFunc + { + get { return () => Configuration.Call.Layout.ShareThumb; } + } public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; } @@ -2497,7 +2554,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var handler = AvailableLayoutsChanged; if (handler != null) { - handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts }); + handler(this, new LayoutInfoChangedEventArgs() {AvailableLayouts = availableLayouts}); } AvailableLayouts = availableLayouts; @@ -2518,7 +2575,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { if (CanSwapContentWithThumbnailFeedback.BoolValue) { - var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state + var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; + // Get the value based on the opposite of the current state // TODO: #697 [*] Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback // to toggle the state SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue)); @@ -2544,12 +2602,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom get { return () => - { - if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None) - return Configuration.Call.Layout.Style.ToString(); - else - return Configuration.Client.Call.Layout.Style.ToString(); - }; + { + if (Configuration.Call.Layout.Style != zConfiguration.eLayoutStyle.None) + return Configuration.Call.Layout.Style.ToString(); + else + return Configuration.Client.Call.Layout.Style.ToString(); + }; } } @@ -2559,7 +2617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var currentLayout = LocalLayoutFeedback.StringValue; - var eCurrentLayout = (int)Enum.Parse(typeof(zConfiguration.eLayoutStyle), currentLayout, true); + var eCurrentLayout = (int) Enum.Parse(typeof (zConfiguration.eLayoutStyle), currentLayout, true); var nextLayout = GetNextLayout(eCurrentLayout); @@ -2583,13 +2641,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom zConfiguration.eLayoutStyle nextLayout; - if (((zConfiguration.eLayoutStyle)currentLayout & zConfiguration.eLayoutStyle.ShareAll) == zConfiguration.eLayoutStyle.ShareAll) + if (((zConfiguration.eLayoutStyle) currentLayout & zConfiguration.eLayoutStyle.ShareAll) == + zConfiguration.eLayoutStyle.ShareAll) { nextLayout = zConfiguration.eLayoutStyle.Gallery; } else { - nextLayout = (zConfiguration.eLayoutStyle)(currentLayout << 1); + nextLayout = (zConfiguration.eLayoutStyle) (currentLayout << 1); } if ((AvailableLayouts & nextLayout) == nextLayout) @@ -2598,7 +2657,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } else { - return GetNextLayout((int)nextLayout); + return GetNextLayout((int) nextLayout); } } @@ -2613,7 +2672,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion - } /// @@ -2814,7 +2872,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void CheckSyncStatus() { if (LoginMessageWasReceived && InitialQueryMessagesWereSent && LastQueryResponseWasReceived && - CamerasHaveBeenSetUp) + CamerasHaveBeenSetUp) { InitialSyncComplete = true; Debug.Console(1, this, "Initial Codec Sync Complete!"); @@ -2830,7 +2888,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { public ZoomRoomFactory() { - TypeNames = new List { "zoomroom" }; + TypeNames = new List {"zoomroom"}; } public override EssentialsDevice BuildDevice(DeviceConfig dc) From 5c02d72ed1b27a45a71edc3bf8581fbd71d9f715 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Aug 2021 16:38:51 -0600 Subject: [PATCH 325/480] fix(essentials): Allows SubpageReferenceListSourceItem to deregister from room's CurrentSourceInfoChange event on Clear() --- PepperDashEssentials/UI/SubpageReferenceListSourceItem.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PepperDashEssentials/UI/SubpageReferenceListSourceItem.cs b/PepperDashEssentials/UI/SubpageReferenceListSourceItem.cs index 3e1869cc..27409007 100644 --- a/PepperDashEssentials/UI/SubpageReferenceListSourceItem.cs +++ b/PepperDashEssentials/UI/SubpageReferenceListSourceItem.cs @@ -14,6 +14,8 @@ namespace PepperDash.Essentials { public SourceListItem SourceItem { get; private set; } + private IHasCurrentSourceInfoChange _room; + public SubpageReferenceListSourceItem(uint index, SubpageReferenceList owner, SourceListItem sourceItem, Action routeAction) : base(index, owner) @@ -25,6 +27,7 @@ namespace PepperDash.Essentials public void RegisterForSourceChange(IHasCurrentSourceInfoChange room) { + _room = room; room.CurrentSourceChange -= room_CurrentSourceInfoChange; room.CurrentSourceChange += room_CurrentSourceInfoChange; } @@ -44,6 +47,9 @@ namespace PepperDash.Essentials { Owner.BoolInputSig(Index, 1).UserObject = null; Owner.StringInputSig(Index, 1).StringValue = ""; + + if(_room != null) + _room.CurrentSourceChange -= room_CurrentSourceInfoChange; } /// From 12e8dca47e8b09ef806e39725bdce24f7edca3ef Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Aug 2021 16:41:23 -0600 Subject: [PATCH 326/480] fix(essentials): #792 refactors logic to show/hide SelectASourceVisible subpage --- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 1 + ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 47 +++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index 1141b5fa..e58172de 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -918,6 +918,7 @@ namespace PepperDash.Essentials TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; + TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; } } diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 0e132ce6..5852526e 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -633,7 +633,10 @@ namespace PepperDash.Essentials var callMode = CurrentMode == UiDisplayMode.Call; TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + if (!presentationMode) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); CallButtonSig.BoolValue = callMode && CurrentRoom.ShutdownType == eShutdownType.None; @@ -674,19 +677,19 @@ namespace PepperDash.Essentials // Run default source when room is off and share is pressed if (!CurrentRoom.OnFeedback.BoolValue) { - if (!CurrentRoom.OnFeedback.BoolValue) - { - // If there's no default, show UI elements - if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) - TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - } - } + // If there's no default, show UI elements + if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + } else // room is on show what's active or select a source if nothing is yet active { - if(CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == CurrentRoom.DefaultCodecRouteString) + if(CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); else if (CurrentSourcePageManager != null) + { + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); CurrentSourcePageManager.Show(); + } } CurrentMode = UiDisplayMode.Presentation; SetupSourceList(); @@ -1131,6 +1134,30 @@ namespace PepperDash.Essentials /// void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type) { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange"); + + // Show the Select a source subpage + if (TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue) + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange SourceStagingBarVisisble: true"); + + if (_CurrentRoom.CurrentSourceInfo == null || (_CurrentRoom.VideoCodec != null && _CurrentRoom.CurrentSourceInfo.SourceDevice.Key == _CurrentRoom.VideoCodec.OsdSource.Key)) + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Showing SelectASourceVisible"); + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + } + else + { + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible"); + } + } + else + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible"); + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + } + if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null) TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName; } @@ -1228,12 +1255,12 @@ namespace PepperDash.Essentials var value = _CurrentRoom.OnFeedback.BoolValue; TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value; - TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; + //TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; if (value) //ON { SetupActivityFooterWhenRoomOn(); - TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; + //TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true; } From b9479bab7001bddd48cbf4800c3732bcd7134658 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 17 Aug 2021 16:50:35 -0600 Subject: [PATCH 327/480] refactor: Rename `Initialize` to `InitializeRoom` --- PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs | 4 ++-- PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs | 4 ++-- PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs index d58f6ac7..d3812feb 100644 --- a/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs @@ -207,7 +207,7 @@ namespace PepperDash.Essentials DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; - Initialize(); + InitializeRoom(); } catch (Exception e) { @@ -215,7 +215,7 @@ namespace PepperDash.Essentials } } - void Initialize() + void InitializeRoom() { if (DefaultAudioDevice is IBasicVolumeControls) DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls; diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 7a57e9c1..3123f20f 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -156,7 +156,7 @@ namespace PepperDash.Essentials DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching; - Initialize(); + InitializeRoom(); } catch (Exception e) { @@ -164,7 +164,7 @@ namespace PepperDash.Essentials } } - void Initialize() + void InitializeRoom() { if (DefaultAudioDevice is IBasicVolumeControls) DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls; diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index b2450abe..f2b17526 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -226,7 +226,7 @@ namespace PepperDash.Essentials DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; - Initialize(); + InitializeRoom(); } catch (Exception e) { @@ -234,7 +234,7 @@ namespace PepperDash.Essentials } } - void Initialize() + void InitializeRoom() { try { From 92f4d37cd640c4a22e1a56169447fab268736da3 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 17 Aug 2021 16:52:11 -0600 Subject: [PATCH 328/480] refactor: Clean up Room Interfaces to help with ambiguities --- .../Room/Types/IEssentialsHuddleSpaceRoom.cs | 8 ++------ .../PepperDashEssentialsBase/Room/IEssentialsRoom.cs | 3 +-- .../AudioCodec/Interfaces/IHasAudioCodec.cs | 3 +-- .../VideoCodec/Interfaces/IHasVideoCodec.cs | 8 +------- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs index efc126f6..45074fb7 100644 --- a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs @@ -17,7 +17,7 @@ using PepperDash.Core; namespace PepperDash.Essentials { - public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay + public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay { bool ExcludeFromGlobalFunctions { get; } @@ -31,7 +31,7 @@ namespace PepperDash.Essentials } public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, - IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback + IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay { EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; } @@ -39,10 +39,6 @@ namespace PepperDash.Essentials IHasScheduleAwareness ScheduleSource { get; } - BoolFeedback InCallFeedback { get; } - - BoolFeedback PrivacyModeIsOnFeedback { get; } - string DefaultCodecRouteString { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs index e83c4b2f..5f94a5cd 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core /// /// Describes the basic functionality of an EssentialsRoom /// - public interface IEssentialsRoom : IKeyName, IReconfigurableDevice + public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute { BoolFeedback OnFeedback { get; } @@ -56,7 +56,6 @@ namespace PepperDash.Essentials.Core void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes); void PowerOnToDefaultOrLastSource(); - bool RunDefaultPresentRoute(); void SetDefaultLevels(); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/Interfaces/IHasAudioCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/Interfaces/IHasAudioCodec.cs index e4cb5ee4..b6fa079d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/Interfaces/IHasAudioCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/AudioCodec/Interfaces/IHasAudioCodec.cs @@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec /// /// For rooms that have audio codec /// - public interface IHasAudioCodec + public interface IHasAudioCodec:IHasInCallFeedback { AudioCodecBase AudioCodec { get; } - BoolFeedback InCallFeedback { get; } ///// ///// Make this more specific diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasVideoCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasVideoCodec.cs index 1d0f4850..d8494334 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasVideoCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasVideoCodec.cs @@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// /// For rooms that have video codec /// - public interface IHasVideoCodec + public interface IHasVideoCodec:IHasInCallFeedback,IPrivacy { VideoCodecBase VideoCodec { get; } - BoolFeedback InCallFeedback { get; } ///// ///// Make this more specific @@ -26,11 +25,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// IntFeedback CallTypeFeedback { get; } - /// - /// - /// - BoolFeedback PrivacyModeIsOnFeedback { get; } - /// /// When something in the room is sharing with the far end or through other means /// From 26bf7d8f736590a3326ba0d2b0e89e946c32fe63 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Aug 2021 17:58:32 -0600 Subject: [PATCH 329/480] feat(essentials): #793 Implements IHasDirectoryHistoryStack on CiscoSparkCodec --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index ae740dbf..893d9b0d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -24,9 +24,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration }; public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other} - public enum eExternalSourceMode {Ready, NotReady, Hidden, Error} + public enum eExternalSourceMode {Ready, NotReady, Hidden, Error} - public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, + public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectoryHistoryStack, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute { @@ -106,6 +106,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public CodecDirectory DirectoryRoot { get; private set; } + + private CodecDirectory _currentDirectoryResult; + /// /// Represents the current state of the directory and is computed on get /// @@ -113,10 +116,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { get { - if (DirectoryBrowseHistory.Count > 0) - return DirectoryBrowseHistory[DirectoryBrowseHistory.Count - 1]; - else - return DirectoryRoot; + return _currentDirectoryResult; + } + private set + { + _currentDirectoryResult = value; + + CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + + OnDirectoryResultReturned(_currentDirectoryResult); } } @@ -127,6 +135,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public List DirectoryBrowseHistory { get; private set; } + public Stack DirectoryBrowseHistoryStack { get; private set; } + public CodecScheduleAwareness CodecSchedule { get; private set; } /// @@ -362,9 +372,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco DirectoryBrowseHistory = new List(); - CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => DirectoryBrowseHistory.Count > 0); + DirectoryBrowseHistoryStack = new Stack(); - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); + CurrentDirectoryResultIsNotDirectoryRoot = new BoolFeedback(() => CurrentDirectoryResult != DirectoryRoot); CodecSchedule = new CodecScheduleAwareness(); @@ -1024,6 +1034,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco PhonebookSyncState.PhonebookRootEntriesReceived(); + CurrentDirectoryResult = DirectoryRoot; + PrintDirectory(DirectoryRoot); } else if (PhonebookSyncState.InitialSyncComplete) @@ -1035,9 +1047,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco PrintDirectory(directoryResults); - DirectoryBrowseHistory.Add(directoryResults); - - OnDirectoryResultReturned(directoryResults); + CurrentDirectoryResult = directoryResults; } } @@ -1068,8 +1078,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// void OnDirectoryResultReturned(CodecDirectory result) { - CurrentDirectoryResultIsNotDirectoryRoot.FireUpdate(); - // This will return the latest results to all UIs. Multiple indendent UI Directory browsing will require a different methodology var handler = DirectoryResultReturned; if (handler != null) @@ -1221,6 +1229,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void SearchDirectory(string searchString) { + DirectoryBrowseHistoryStack.Push(CurrentDirectoryResult); + SendText(string.Format("xCommand Phonebook Search SearchString: \"{0}\" PhonebookType: {1} ContactType: Contact Limit: {2}", searchString, PhonebookMode, PhonebookResultsLimit)); } @@ -1230,6 +1240,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void GetDirectoryFolderContents(string folderId) { + DirectoryBrowseHistoryStack.Push(CurrentDirectoryResult); + SendText(string.Format("xCommand Phonebook Search FolderId: {0} PhonebookType: {1} ContactType: Any Limit: {2}", folderId, PhonebookMode, PhonebookResultsLimit)); } @@ -1239,24 +1251,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void GetDirectoryParentFolderContents() { - var currentDirectory = new CodecDirectory(); - - if (DirectoryBrowseHistory.Count > 0) + if (DirectoryBrowseHistoryStack.Count == 0) { - var lastItemIndex = DirectoryBrowseHistory.Count - 1; - var parentDirectoryContents = DirectoryBrowseHistory[lastItemIndex]; - - DirectoryBrowseHistory.Remove(DirectoryBrowseHistory[lastItemIndex]); - - currentDirectory = parentDirectoryContents; - - } - else - { - currentDirectory = DirectoryRoot; + return; } - OnDirectoryResultReturned(currentDirectory); + CurrentDirectoryResult = DirectoryBrowseHistoryStack.Pop(); } /// @@ -1264,9 +1264,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// public void SetCurrentDirectoryToRoot() { - DirectoryBrowseHistory.Clear(); + DirectoryBrowseHistoryStack.Clear(); - OnDirectoryResultReturned(DirectoryRoot); + CurrentDirectoryResult = DirectoryRoot; } /// From 36a41ac4770e528e126c698b3017368ce4d6fc3a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 17 Aug 2021 16:41:23 -0600 Subject: [PATCH 330/480] fix(essentials): #792 refactors logic to show/hide SelectASourceVisible subpage --- .../EssentialsHuddlePanelAvFunctionsDriver.cs | 1 + ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 47 +++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index a0d5947c..78a06301 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -918,6 +918,7 @@ namespace PepperDash.Essentials TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true; TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; + TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; } } diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 55a4a16c..8082a6cb 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -633,7 +633,10 @@ namespace PepperDash.Essentials var callMode = CurrentMode == UiDisplayMode.Call; TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + if (!presentationMode) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); CallButtonSig.BoolValue = callMode && CurrentRoom.ShutdownType == eShutdownType.None; @@ -674,19 +677,19 @@ namespace PepperDash.Essentials // Run default source when room is off and share is pressed if (!CurrentRoom.OnFeedback.BoolValue) { - if (!CurrentRoom.OnFeedback.BoolValue) - { - // If there's no default, show UI elements - if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) - TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - } - } + // If there's no default, show UI elements + if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + } else // room is on show what's active or select a source if nothing is yet active { - if(CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == CurrentRoom.DefaultCodecRouteString) + if(CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); else if (CurrentSourcePageManager != null) + { + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); CurrentSourcePageManager.Show(); + } } CurrentMode = UiDisplayMode.Presentation; SetupSourceList(); @@ -1131,6 +1134,30 @@ namespace PepperDash.Essentials /// void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type) { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange"); + + // Show the Select a source subpage + if (TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue) + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange SourceStagingBarVisisble: true"); + + if (_CurrentRoom.CurrentSourceInfo == null || (_CurrentRoom.VideoCodec != null && _CurrentRoom.CurrentSourceInfo.SourceDevice.Key == _CurrentRoom.VideoCodec.OsdSource.Key)) + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Showing SelectASourceVisible"); + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + } + else + { + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible"); + } + } + else + { + Debug.Console(1, "AvFunctionsDriver: CurrentSingleSourceChange Hiding SelectASourceVisible"); + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + } + if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null) TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName; } @@ -1228,12 +1255,12 @@ namespace PepperDash.Essentials var value = _CurrentRoom.OnFeedback.BoolValue; TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value; - TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; + //TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; if (value) //ON { SetupActivityFooterWhenRoomOn(); - TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; + //TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true; } From 9a1a23c88a9c6cb5a478b9e6a6d0cc63a39cf6c1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 17 Aug 2021 22:23:41 -0600 Subject: [PATCH 331/480] fix: Instantiate Availability class when --- .../Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index 8184289e..c1cd92cf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -327,6 +327,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public SpeakerTrack() { Status = new Status2(); + Availability = new Availability(); } } From 6a1671aae1e77b5c682ccca78ea74f0170345682 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 17 Aug 2021 22:25:18 -0600 Subject: [PATCH 332/480] ci: Remove PR trigger --- .github/workflows/docker.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a74ca03e..94c45937 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -8,12 +8,9 @@ on: - bugfix/* - release/* - development - pull_request: - branches: - - development env: - # solution path doesn't need slashes unless there it is multiple folders deep + # solution path doesn't need slashes unless it is multiple folders deep # solution name does not include extension. .sln is assumed SOLUTION_PATH: PepperDashEssentials SOLUTION_FILE: PepperDashEssentials From dbdaedcca3446028128e181057ab694f4dcca1c8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Aug 2021 13:25:26 -0600 Subject: [PATCH 333/480] feat(essentials): #800 Adds IPasswordPrompt --- .../DeviceTypeInterfaces/IPasswordPrompt.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs new file mode 100644 index 00000000..be23725c --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Describes the functionality required to prompt a user to enter a password + /// + public interface IPasswordPrompt + { + /// + /// Notifies when a password is required or is entered incorrectly + /// + event EventHandler PasswordRequired; + + /// + /// Submits the password + /// + /// + void SubmitPassword(string password); + } + + public class PasswordPromptEventArgs : EventArgs + { + /// + /// Indicates if the last submitted password was incorrect + /// + bool LastAttemptWasIncorrect { get; private set; } + + /// + /// Indicates that the login attempt has failed + /// + bool LoginAttemptFailed { get; private set; } + + /// + /// Indicates that the process was cancelled and the prompt should be dismissed + /// + bool LoginAttemptCancelled { get; private set; } + + /// + /// A message to be displayed to the user + /// + string Message { get; private set; } + + public PasswordPromptEventArgs(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message) + { + LastAttemptWasIncorrect = lastAttemptIncorrect; + LoginAttemptFailed = loginFailed; + LoginAttemptCancelled = loginCancelled; + Message = message; + } + } +} \ No newline at end of file From f8129fe7ae108137e910ee778dd2c0718ec82871 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Aug 2021 13:35:48 -0600 Subject: [PATCH 334/480] feat(essentials): #800 adds public access modifier on properties --- .../DeviceTypeInterfaces/IPasswordPrompt.cs | 8 ++++---- .../PepperDash_Essentials_Core.csproj | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs index be23725c..6ecdd775 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/IPasswordPrompt.cs @@ -28,22 +28,22 @@ namespace PepperDash.Essentials.Core /// /// Indicates if the last submitted password was incorrect /// - bool LastAttemptWasIncorrect { get; private set; } + public bool LastAttemptWasIncorrect { get; private set; } /// /// Indicates that the login attempt has failed /// - bool LoginAttemptFailed { get; private set; } + public bool LoginAttemptFailed { get; private set; } /// /// Indicates that the process was cancelled and the prompt should be dismissed /// - bool LoginAttemptCancelled { get; private set; } + public bool LoginAttemptCancelled { get; private set; } /// /// A message to be displayed to the user /// - string Message { get; private set; } + public string Message { get; private set; } public PasswordPromptEventArgs(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 36992629..85c66a13 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -203,6 +203,7 @@ + From f298b5cc41ef9545203ca7ca307aa6154f2806b7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Aug 2021 14:45:16 -0600 Subject: [PATCH 335/480] feat(essentials): Implements IPasswordPrompt on ZoomRoom --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 9 ++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 47 +++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index c116a4a8..d07476dd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -927,6 +927,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom PhoneCallStatus_InCall, PhoneCallStatus_Init, } + + public class MeetingNeedsPassword + { + [JsonProperty("needsPassword")] + public bool NeedsPassword { get; set; } + + [JsonProperty("wrongAndRetry")] + public bool WrongAndRetry { get; set; } + } } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 701ce6f2..05602001 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt { private const long MeetingRefreshTimer = 60000; private const uint DefaultMeetingDurationMin = 30; @@ -45,6 +45,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private StringBuilder _jsonMessage; private int _previousVolumeLevel; private CameraBase _selectedCamera; + private string _lastDialedMeetingNumber; private readonly ZoomRoomPropertiesConfig _props; @@ -1349,7 +1350,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } case "meetingneedspassword": { - // TODO: notify user to enter a password + var meetingNeedsPassword = + responseObj.ToObject(); + + if (meetingNeedsPassword.NeedsPassword) + { + var prompt = "Password required to join this meeting. Please enter the meeting password."; + + OnPasswordRequired(meetingNeedsPassword.WrongAndRetry, false, false, prompt); + } + break; } case "needwaitforhost": @@ -2041,9 +2051,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void Dial(string number) { + _lastDialedMeetingNumber = number; SendText(string.Format("zCommand Dial Join meetingNumber: {0}", number)); } + /// + /// Dials a meeting with a password + /// + /// + /// + public void Dial(string number, string password) + { + SendText(string.Format("zCommand Dial Join meetingNumber: {0} password: {1}", number, password)); + } + /// /// Invites a contact to either a new meeting (if not already in a meeting) or the current meeting. /// Currently only invites a single user @@ -2672,7 +2693,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion - } + + #region IPasswordPrompt Members + + public event EventHandler PasswordRequired; + + public void SubmitPassword(string password) + { + Dial(_lastDialedMeetingNumber, password); + } + + void OnPasswordRequired(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message) + { + var handler = PasswordRequired; + if (handler != null) + { + handler(this, new PasswordPromptEventArgs(lastAttemptIncorrect, loginFailed, loginCancelled, message)); + } + } + + #endregion + } /// /// Zoom Room specific info object From dad986414c097901f0babed38aa945d456cb42ed Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 18 Aug 2021 17:55:04 -0600 Subject: [PATCH 336/480] feat(essentials): Updated EssentialsVideoCodecUIDriver to display password prompt when joining password protected meeting --- .../UI/JoinConstants/UIBoolJoin.cs | 19 +++ .../UI/JoinConstants/UIStringlJoin.cs | 8 + .../VC/EssentialsVideoCodecUiDriver.cs | 160 +++++++++++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 6 + 4 files changed, 191 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index 81be9002..dd454d97 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -948,5 +948,24 @@ namespace PepperDash.Essentials /// 15214 /// public const uint PinDialogDot4 = 15214; + + // Password Prompt Dialog ************************** + + /// + /// 15301 + /// + public const uint PasswordPromptDialogVisible = 15301; + /// + /// 15302 + /// + public const uint PasswordPromptTextPress = 15302; + /// + /// 15306 + /// + public const uint PasswordPromptCancelPress = 15306; + /// + /// 15307 + /// + public const uint PasswordPromptErrorVisible = 15307; } } \ No newline at end of file diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index 9b2b8a95..67a5c6e2 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -118,6 +118,14 @@ namespace PepperDash.Essentials //----- through 3120 + /// + /// 3201 + /// + public const uint PasswordPromptMessageText = 3201; + /// + /// 3202 + /// + public const uint PasswordPromptPasswordText = 3202; /// /// 3812 diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 612f7eeb..f92e0114 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -83,6 +83,9 @@ namespace PepperDash.Essentials.UIDrivers.VC StringBuilder SearchStringBuilder = new StringBuilder(); BoolFeedback SearchStringBackspaceVisibleFeedback; + StringFeedback PasswordStringFeedback; + StringBuilder PasswordStringBuilder = new StringBuilder(); + ModalDialog IncomingCallModal; eKeypadMode KeypadMode; @@ -180,8 +183,22 @@ namespace PepperDash.Essentials.UIDrivers.VC }); SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]); - SetupDirectoryList(); + PasswordStringFeedback = new StringFeedback(() => + { + if (PasswordStringBuilder.Length > 0) + { + Parent.Keyboard.EnableGoButton(); + return PasswordStringBuilder.ToString(); + } + else + { + Parent.Keyboard.DisableGoButton(); + return "Tap for keyboard"; + } + }); + PasswordStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.PasswordPromptPasswordText]); + SetupDirectoryList(); SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0); SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]); @@ -199,6 +216,12 @@ namespace PepperDash.Essentials.UIDrivers.VC triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500, StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress); + + if (Codec is IPasswordPrompt) + { + SetupPasswordPrompt(); + } + } catch (Exception e) { @@ -1328,7 +1351,21 @@ namespace PepperDash.Essentials.UIDrivers.VC /// void RevealKeyboard() { - if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial) + if (_passwordPromptDialogVisible) + { + Debug.Console(2, "Attaching Keyboard to PasswordPromptDialog"); + DetachDialKeyboard(); + DetachSearchKeyboard(); + var kb = Parent.Keyboard; + kb.KeyPress -= Keyboard_PasswordKeyPress; + kb.KeyPress += Keyboard_PasswordKeyPress; + kb.HideAction = this.DetachPasswordKeyboard; + kb.GoButtonText = "Submit"; + kb.GoButtonVisible = true; + PasswordStringCheckEnables(); + kb.Show(); + } + else if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial) { var kb = Parent.Keyboard; kb.KeyPress -= Keyboard_DialKeyPress; @@ -1350,6 +1387,7 @@ namespace PepperDash.Essentials.UIDrivers.VC SearchStringKeypadCheckEnables(); kb.Show(); } + } /// @@ -1405,6 +1443,32 @@ namespace PepperDash.Essentials.UIDrivers.VC } } + /// + /// Event handler for keyboard dialing + /// + void Keyboard_PasswordKeyPress(object sender, PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs e) + { + if (_passwordPromptDialogVisible) + { + if (e.Text != null) + PasswordStringBuilder.Append(e.Text); + else + { + if (e.SpecialKey == KeyboardSpecialKey.Backspace) + PasswordKeypadBackspacePress(); + else if (e.SpecialKey == KeyboardSpecialKey.Clear) + PasswordKeypadClear(); + else if (e.SpecialKey == KeyboardSpecialKey.GoButton) + { + (Codec as IPasswordPrompt).SubmitPassword(PasswordStringBuilder.ToString()); + HidePasswordPrompt(); + } + } + PasswordStringFeedback.FireUpdate(); + PasswordStringCheckEnables(); + } + } + /// /// Call /// @@ -1418,6 +1482,11 @@ namespace PepperDash.Essentials.UIDrivers.VC Parent.Keyboard.KeyPress -= Keyboard_SearchKeyPress; } + void DetachPasswordKeyboard() + { + Parent.Keyboard.KeyPress -= Keyboard_PasswordKeyPress; + } + /// /// Shows the camera controls subpage /// @@ -1671,6 +1740,40 @@ namespace PepperDash.Essentials.UIDrivers.VC Parent.Keyboard.DisableGoButton(); } + /// + /// Clears the Password keypad + /// + void PasswordKeypadClear() + { + PasswordStringBuilder.Remove(0, SearchStringBuilder.Length); + PasswordStringFeedback.FireUpdate(); + PasswordStringCheckEnables(); + + } + + /// + /// + /// + void PasswordKeypadBackspacePress() + { + PasswordStringBuilder.Remove(PasswordStringBuilder.Length - 1, 1); + + PasswordStringFeedback.FireUpdate(); + PasswordStringCheckEnables(); + } + + /// + /// Checks the enabled states of various elements around the keypad + /// + void PasswordStringCheckEnables() + { + var textIsEntered = PasswordStringBuilder.Length > 0; + if (textIsEntered) + Parent.Keyboard.EnableGoButton(); + else + Parent.Keyboard.DisableGoButton(); + } + /// /// Returns the text value for the keypad dial entry field @@ -1716,5 +1819,58 @@ namespace PepperDash.Essentials.UIDrivers.VC Dial = 0, DTMF } + + void SetupPasswordPrompt() + { + var passwordPromptCodec = Codec as IPasswordPrompt; + + passwordPromptCodec.PasswordRequired += new EventHandler(passwordPromptCodec_PasswordRequired); + + TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptCancelPress, HidePasswordPrompt); + TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptTextPress, RevealKeyboard); + } + + void passwordPromptCodec_PasswordRequired(object sender, PasswordPromptEventArgs e) + { + if (e.LoginAttemptCancelled) + { + HidePasswordPrompt(); + return; + } + + if (!string.IsNullOrEmpty(e.Message)) + { + TriList.SetString(UIStringJoin.PasswordPromptMessageText, e.Message); + } + + if (e.LoginAttemptFailed) + { + // TODO: Show a message modal to indicate the login attempt failed + return; + } + + TriList.SetBool(UIBoolJoin.PasswordPromptErrorVisible, e.LastAttemptWasIncorrect); + + ShowPasswordPrompt(); + } + + private bool _passwordPromptDialogVisible; + + void ShowPasswordPrompt() + { + // Clear out any previous data + PasswordStringBuilder.Remove(0, PasswordStringBuilder.Length); + + _passwordPromptDialogVisible = true; + TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); + RevealKeyboard(); + } + + void HidePasswordPrompt() + { + _passwordPromptDialogVisible = false; + Parent.Keyboard.Hide(); + TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 05602001..ce4ff852 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1359,6 +1359,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom OnPasswordRequired(meetingNeedsPassword.WrongAndRetry, false, false, prompt); } + else + { + OnPasswordRequired(false, false, true, ""); + } break; } @@ -2062,6 +2066,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// public void Dial(string number, string password) { + Debug.Console(2, this, "Dialing meeting number: {0} with password: {1}", number, password); SendText(string.Format("zCommand Dial Join meetingNumber: {0} password: {1}", number, password)); } @@ -2700,6 +2705,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public void SubmitPassword(string password) { + Debug.Console(2, this, "Password Submitted: {0}", password); Dial(_lastDialedMeetingNumber, password); } From 62fcf3856f17496001867e9877352c6d139ab83d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 09:37:21 -0600 Subject: [PATCH 337/480] fix(essentials): Minor update to clear out previous password text when displaying password prompt --- .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index f92e0114..ebec4568 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -193,7 +193,7 @@ namespace PepperDash.Essentials.UIDrivers.VC else { Parent.Keyboard.DisableGoButton(); - return "Tap for keyboard"; + return ""; } }); PasswordStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.PasswordPromptPasswordText]); @@ -1859,7 +1859,7 @@ namespace PepperDash.Essentials.UIDrivers.VC void ShowPasswordPrompt() { // Clear out any previous data - PasswordStringBuilder.Remove(0, PasswordStringBuilder.Length); + PasswordKeypadClear(); _passwordPromptDialogVisible = true; TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); From 621205e65c42b08d24dab8e6aedd9a2ddfa4def8 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 12:04:11 -0600 Subject: [PATCH 338/480] fix(essentials): Hides password prompt on successful call connection --- .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index ebec4568..6dba53f5 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -322,6 +322,7 @@ namespace PepperDash.Essentials.UIDrivers.VC { case eCodecCallStatus.Connected: // fire at SRL item + HidePasswordPrompt(); KeypadMode = eKeypadMode.DTMF; DialStringBuilder.Remove(0, DialStringBuilder.Length); DialStringFeedback.FireUpdate(); @@ -1868,9 +1869,12 @@ namespace PepperDash.Essentials.UIDrivers.VC void HidePasswordPrompt() { - _passwordPromptDialogVisible = false; - Parent.Keyboard.Hide(); - TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); + if (_passwordPromptDialogVisible) + { + _passwordPromptDialogVisible = false; + Parent.Keyboard.Hide(); + TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); + } } } } \ No newline at end of file From 8bf4b0d568326679a781b0dc9cfd1fe99c90f128 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 12:49:11 -0600 Subject: [PATCH 339/480] fix(essentails): Increase phonebook list limit to 10000 --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index ce4ff852..6b9db714 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -852,7 +852,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (!_props.DisablePhonebookAutoDownload) { - _syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 512"); + _syncState.AddQueryToQueue("zCommand Phonebook List Offset: 0 Limit: 10000"); } _syncState.AddQueryToQueue("zCommand Bookings List"); From b2331fa1e544328fe824e2a4a12e93a650690be6 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 14:14:14 -0600 Subject: [PATCH 340/480] feat(essentials): Adds IsInvitableContact property with getter to DirectoryContact --- .../Essentials Devices Common/Codec/iHasDirectory.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs index 29a46466..38946759 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs @@ -209,7 +209,14 @@ namespace PepperDash.Essentials.Devices.Common.Codec [JsonProperty("title")] public string Title { get; set; } - + [JsonProperty("isInvitableContact")] + public bool IsInvitableContact + { + get + { + return this is IInvitableContact; + } + } [JsonProperty("contactMethods")] public List ContactMethods { get; set; } From f922b871a16dc6320e684a560a782dc2e7065f31 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 14:57:00 -0600 Subject: [PATCH 341/480] refactor(essentials): Switches from zoom specific contact class to generic InvitableDirectoryContact class --- .../Codec/iHasDirectory.cs | 21 +++++++++++-------- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 10 +-------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs index 38946759..b2ccb29c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs @@ -160,7 +160,19 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public interface IInvitableContact { + bool IsInvitableContact { get; } + } + public class InvitableDirectoryContact : DirectoryContact, IInvitableContact + { + [JsonProperty("isInvitableContact")] + public bool IsInvitableContact + { + get + { + return this is IInvitableContact; + } + } } /// @@ -209,15 +221,6 @@ namespace PepperDash.Essentials.Devices.Common.Codec [JsonProperty("title")] public string Title { get; set; } - [JsonProperty("isInvitableContact")] - public bool IsInvitableContact - { - get - { - return this is IInvitableContact; - } - } - [JsonProperty("contactMethods")] public List ContactMethods { get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index d07476dd..28073eb8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -236,14 +236,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } - /// - /// Used to be able to inplement IInvitableContact on DirectoryContact - /// - public class ZoomDirectoryContact : DirectoryContact, IInvitableContact - { - - } - public class Phonebook { [JsonProperty("Contacts")] @@ -302,7 +294,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom foreach (Contact c in zoomContacts) { - var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; + var contact = new InvitableDirectoryContact { Name = c.ScreenName, ContactId = c.Jid }; contact.ContactMethods.Add(new ContactMethod() { Number = c.Jid, Device = eContactMethodDevice.Video, CallType = eContactMethodCallType.Video, ContactMethodId = c.Jid }); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 6b9db714..9bcdd44b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2077,7 +2077,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// public override void Dial(IInvitableContact contact) { - var ic = contact as zStatus.ZoomDirectoryContact; + var ic = contact as InvitableDirectoryContact; if (ic != null) { From 0014dd7a1448033a5020867f06da8ec843b28863 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 15:19:19 -0600 Subject: [PATCH 342/480] feat(essentials): #801 Adds IHasStartMeeting interface and implments on ZoomRoom --- .../VideoCodec/Interfaces/IHasStartMeeting.cs | 25 +++++++++++++++++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 22 ++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs new file mode 100644 index 00000000..a01ec099 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Describes the ability to start an ad-hoc meeting + /// + public interface IHasStartMeeting + { + /// + /// The default meeting duration in minutes + /// + uint DefaultMeetingDurationMin { get; } + + /// + /// Start an ad-hoc meeting for the specified duration + /// + /// + void StartMeeting(uint duration); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 9bcdd44b..4712f12d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -25,10 +25,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting { private const long MeetingRefreshTimer = 60000; - private const uint DefaultMeetingDurationMin = 30; + public uint DefaultMeetingDurationMin { get; private set; } + private const string Delimiter = "\x0D\x0A"; private readonly GenericQueue _receiveQueue; @@ -52,6 +53,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public ZoomRoom(DeviceConfig config, IBasicCommunication comm) : base(config) { + DefaultMeetingDurationMin = 30; + _props = JsonConvert.DeserializeObject(config.Properties.ToString()); _receiveQueue = new GenericQueue(Key + "-rxQueue", Thread.eThreadPriority.MediumPriority, 512); @@ -2095,6 +2098,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + + /// + /// Starts a PMI Meeting for the specified duration (or default meeting duration if 0 is specified) + /// + /// duration of meeting + public void StartMeeting(uint duration) + { + uint dur = DefaultMeetingDurationMin; + + if (duration > 0) + dur = duration; + + SendText(string.Format("zCommand Dial StartPmi Duration: {0}", dur); + } + public override void EndCall(CodecActiveCallItem call) { SendText("zCommand Call Disconnect"); From 540a00861cc9ee265d6118b7c0bce2a1966641e2 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 19 Aug 2021 16:02:24 -0600 Subject: [PATCH 343/480] fix(essentials): Adds missing file in .csproj --- .../Essentials Devices Common.csproj | 1 + .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 4 ++++ .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 21821d22..75d01b0f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -123,6 +123,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index d31fbda1..4db4084c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -736,6 +736,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } + /// + /// Appends the delimiter and send the command to the codec + /// + /// public void SendText(string command) { if (CommDebuggingIsOn) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 4712f12d..83597081 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -734,7 +734,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ConsoleAccessLevelEnum.AccessOperator); if (!_props.DisablePhonebookAutoDownload) { - CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 512"), + CrestronConsole.AddNewConsoleCommand(s => SendText("zCommand Phonebook List Offset: 0 Limit: 10000"), "GetZoomRoomContacts", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator); } @@ -2110,7 +2110,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (duration > 0) dur = duration; - SendText(string.Format("zCommand Dial StartPmi Duration: {0}", dur); + SendText(string.Format("zCommand Dial StartPmi Duration: {0}", dur)); } public override void EndCall(CodecActiveCallItem call) From e7cfe1143db2092af3c213b7442ae2ac8f9d7941 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 25 Aug 2021 16:24:18 -0600 Subject: [PATCH 344/480] fix(essentials): updates MockVc to instantiate the OsdSource and add its tie line --- .../VideoCodec/MockVC/MockVC.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index 5d701f7b..e8988ad2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -78,6 +78,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec SetupCameras(); + CreateOsdSource(); + SetIsReady(); } @@ -117,6 +119,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } bool _StandbyIsOn; + /// + /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input + /// to enable routing + /// + void CreateOsdSource() + { + OsdSource = new DummyRoutingInputsDevice(Key + "[osd]"); + DeviceManager.AddDevice(OsdSource); + var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn); + TieLineCollection.Default.Add(tl); + } /// /// Dials, yo! From acd2be3679a5a1df6bd2dc4719a148cd3766fe0b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 25 Aug 2021 17:23:24 -0600 Subject: [PATCH 345/480] feat(essentials): Updates to get scenarios to activate/deactivate --- .../Room/Combining/EssentialsRoomCombiner.cs | 16 +++++++++++++++- .../Room/Combining/IEssentialsRoomCombiner.cs | 5 +++++ .../Room/Combining/RoomCombinationScenario.cs | 10 ++++++++-- packages.config | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs index d9886e70..820d363f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/EssentialsRoomCombiner.cs @@ -171,8 +171,22 @@ namespace PepperDash.Essentials.Core { if (value != _currentScenario) { + // Deactivate the old scenario first + if (_currentScenario != null) + { + _currentScenario.Deactivate(); + } + _currentScenario = value; - Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name); + + // Activate the new scenario + if (_currentScenario != null) + { + _currentScenario.Activate(); + + Debug.Console(1, this, "Current Scenario: {0}", _currentScenario.Name); + } + var handler = RoomCombinationScenarioChanged; if (handler != null) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs index c0c8101b..e6bdd983 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/IEssentialsRoomCombiner.cs @@ -78,6 +78,11 @@ namespace PepperDash.Essentials.Core /// void Activate(); + /// + /// Deactivates this room combination scenario + /// + void Deactivate(); + /// /// The state of the partitions that would activate this scenario /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs index a5534edc..460241a0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Combining/RoomCombinationScenario.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + using Newtonsoft.Json; namespace PepperDash.Essentials.Core @@ -27,9 +29,9 @@ namespace PepperDash.Essentials.Core public BoolFeedback IsActiveFeedback { get; private set; } - List activationActions; + private List activationActions; - List deactivationActions; + private List deactivationActions; public RoomCombinationScenario(RoomCombinationScenarioConfig config) { @@ -52,6 +54,8 @@ namespace PepperDash.Essentials.Core public void Activate() { + Debug.Console(1, "Activating Scenario: '{0}' with {1} action(s) defined", Name, activationActions.Count); + if (activationActions != null) { foreach (var action in activationActions) @@ -66,6 +70,8 @@ namespace PepperDash.Essentials.Core public void Deactivate() { + Debug.Console(1, "Deactivating Scenario: '{0}' with {1} action(s) defined", Name, deactivationActions.Count); + if (deactivationActions != null) { foreach (var action in deactivationActions) diff --git a/packages.config b/packages.config index 3494f2eb..06d30eaa 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 4444328600ecb720f8e5ce1b6bde9abdecadca0a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 26 Aug 2021 16:48:56 -0600 Subject: [PATCH 346/480] fix(essentials): #804 #805 Updates to prevent attempting to access null AudioSourceFeedback property on 4kz TX models --- .../Transmitters/DmTx4kz202CController.cs | 680 +++++++++--------- .../Transmitters/DmTx4kz302CController.cs | 6 +- 2 files changed, 343 insertions(+), 343 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz202CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz202CController.cs index da1685cc..a241d60d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz202CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz202CController.cs @@ -1,40 +1,40 @@ -using Crestron.SimplSharpPro; -using System; -using System.Linq; -//using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.DM -{ - using eVst = eX02VideoSourceType; +using Crestron.SimplSharpPro; +using System; +using System.Linq; +//using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.DM +{ + using eVst = eX02VideoSourceType; using eAst = eX02AudioSourceType; - public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback, - IIROutputPorts, IComPorts - { - public DmTx4kz202C Tx { get; private set; } - - public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } - public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } - public RoutingOutputPort DmOut { get; private set; } - public RoutingOutputPort HdmiLoopOut { get; private set; } - - public override StringFeedback ActiveVideoInputFeedback { get; protected set; } - public IntFeedback VideoSourceNumericFeedback { get; protected set; } - public IntFeedback AudioSourceNumericFeedback { get; protected set; } - public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } - public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } - public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } - public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } - - //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } + public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback, + IIROutputPorts, IComPorts + { + public DmTx4kz202C Tx { get; private set; } + + public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } + public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } + public RoutingOutputPort DmOut { get; private set; } + public RoutingOutputPort HdmiLoopOut { get; private set; } + + public override StringFeedback ActiveVideoInputFeedback { get; protected set; } + public IntFeedback VideoSourceNumericFeedback { get; protected set; } + public IntFeedback AudioSourceNumericFeedback { get; protected set; } + public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } + public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } + public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } + public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } + + //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; } //IroutingNumericEvent public event EventHandler NumericSwitchChange; @@ -47,48 +47,48 @@ namespace PepperDash.Essentials.DM { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } - - - - /// - /// Helps get the "real" inputs, including when in Auto - /// - public eX02VideoSourceType ActualActiveVideoInput - { - get - { - if (Tx.VideoSourceFeedback != eVst.Auto) - return Tx.VideoSourceFeedback; - - if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - return eVst.Hdmi1; - - return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled; - } - } - public RoutingPortCollection InputPorts - { - get - { - return new RoutingPortCollection - { - HdmiIn1, - HdmiIn2, - AnyVideoInput - }; - } - } - public RoutingPortCollection OutputPorts - { - get - { - return new RoutingPortCollection { DmOut, HdmiLoopOut }; - } - } - public DmTx4kz202CController(string key, string name, DmTx4kz202C tx) - : base(key, name, tx) - { + } + + + + /// + /// Helps get the "real" inputs, including when in Auto + /// + public eX02VideoSourceType ActualActiveVideoInput + { + get + { + if (Tx.VideoSourceFeedback != eVst.Auto) + return Tx.VideoSourceFeedback; + + if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + return eVst.Hdmi1; + + return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled; + } + } + public RoutingPortCollection InputPorts + { + get + { + return new RoutingPortCollection + { + HdmiIn1, + HdmiIn2, + AnyVideoInput + }; + } + } + public RoutingPortCollection OutputPorts + { + get + { + return new RoutingPortCollection { DmOut, HdmiLoopOut }; + } + } + public DmTx4kz202CController(string key, string name, DmTx4kz202C tx) + : base(key, name, tx) + { Tx = tx; HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, @@ -104,208 +104,208 @@ namespace PepperDash.Essentials.DM FeedbackMatchObject = eVst.Hdmi2 }; - ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", - () => ActualActiveVideoInput.ToString()); - - - - Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; - Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; - Tx.BaseEvent += Tx_BaseEvent; - Tx.OnlineStatusChange += Tx_OnlineStatusChange; - - VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - - //Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway - AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - - HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); - - HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpStateFeedback = - new IntFeedback( - () => - tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback - ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback - : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; - - Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); - - Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); - - var combinedFuncs = new VideoStatusFuncsWrapper - { - HdcpActiveFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), - - HdcpStateFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); - if (ActualActiveVideoInput == eVst.Hdmi2) - return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString(); - return ""; - }, - - VideoResolutionFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); - if (ActualActiveVideoInput == eVst.Hdmi2) - return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); - return ""; - }, - VideoSyncFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) - - }; - - AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); - - DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, null, this); - HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - - - AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, - AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, - AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, - AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, - Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback); - - // Set Ports for CEC - HdmiIn1.Port = Tx.HdmiInputs[1]; - HdmiIn2.Port = Tx.HdmiInputs[2]; - HdmiLoopOut.Port = Tx.HdmiOutput; - DmOut.Port = Tx.DmOutput; - } - - - - public override bool CustomActivate() - { - // Link up all of these damned events to the various RoutingPorts via a helper handler - Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); - Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); - - Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); - Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); - - // Base does register and sets up comm monitoring. - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); - - if (Hdmi1VideoSyncFeedback != null) - { - Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); - } - if (Hdmi2VideoSyncFeedback != null) - { - Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); - } - - LinkDmTxToApi(this, trilist, joinMap, bridge); - } - - public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) - { - Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); - - switch (type) - { - case eRoutingSignalType.Video: - switch (input) - { - case 0: - { - ExecuteSwitch(eVst.Auto, null, type); - break; - } - case 1: - { - ExecuteSwitch(HdmiIn1.Selector, null, type); - break; - } - case 2: - { - ExecuteSwitch(HdmiIn2.Selector, null, type); - break; - } - case 3: - { - ExecuteSwitch(eVst.AllDisabled, null, type); - break; - } - } - break; - case eRoutingSignalType.Audio: - switch (input) - { - case 0: - { - ExecuteSwitch(eAst.Auto, null, type); - break; - } - case 1: - { - ExecuteSwitch(eAst.Hdmi1, null, type); - break; - } - case 2: - { - ExecuteSwitch(eAst.Hdmi2, null, type); - break; - } - case 3: - { - ExecuteSwitch(eAst.AllDisabled, null, type); - break; - } - } - break; - } - } - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video) - Tx.VideoSource = (eVst)inputSelector; - if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)) - Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); - } - - void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) - { - Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); - - switch (args.EventId) - { - case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: - case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: - case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); - break; - case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); - break; - } + ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", + () => ActualActiveVideoInput.ToString()); + + + + Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; + Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; + Tx.BaseEvent += Tx_BaseEvent; + Tx.OnlineStatusChange += Tx_OnlineStatusChange; + + VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + + //Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway + AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + + HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); + + HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpStateFeedback = + new IntFeedback( + () => + tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback + ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback + : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; + + Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); + + Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); + + var combinedFuncs = new VideoStatusFuncsWrapper + { + HdcpActiveFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), + + HdcpStateFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); + if (ActualActiveVideoInput == eVst.Hdmi2) + return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString(); + return ""; + }, + + VideoResolutionFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); + if (ActualActiveVideoInput == eVst.Hdmi2) + return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); + return ""; + }, + VideoSyncFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) + + }; + + AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); + + DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, null, this); + HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + + AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, + AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, + AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, + AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, + Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback); + + // Set Ports for CEC + HdmiIn1.Port = Tx.HdmiInputs[1]; + HdmiIn2.Port = Tx.HdmiInputs[2]; + HdmiLoopOut.Port = Tx.HdmiOutput; + DmOut.Port = Tx.DmOutput; + } + + + + public override bool CustomActivate() + { + // Link up all of these damned events to the various RoutingPorts via a helper handler + Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); + Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); + + Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); + Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); + + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); + + if (Hdmi1VideoSyncFeedback != null) + { + Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); + } + if (Hdmi2VideoSyncFeedback != null) + { + Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); + } + + LinkDmTxToApi(this, trilist, joinMap, bridge); + } + + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) + { + Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); + + switch (type) + { + case eRoutingSignalType.Video: + switch (input) + { + case 0: + { + ExecuteSwitch(eVst.Auto, null, type); + break; + } + case 1: + { + ExecuteSwitch(HdmiIn1.Selector, null, type); + break; + } + case 2: + { + ExecuteSwitch(HdmiIn2.Selector, null, type); + break; + } + case 3: + { + ExecuteSwitch(eVst.AllDisabled, null, type); + break; + } + } + break; + case eRoutingSignalType.Audio: + switch (input) + { + case 0: + { + ExecuteSwitch(eAst.Auto, null, type); + break; + } + case 1: + { + ExecuteSwitch(eAst.Hdmi1, null, type); + break; + } + case 2: + { + ExecuteSwitch(eAst.Hdmi2, null, type); + break; + } + case 3: + { + ExecuteSwitch(eAst.AllDisabled, null, type); + break; + } + } + break; + } + } + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video) + Tx.VideoSource = (eVst)inputSelector; + if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)) + Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); + } + + void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) + { + Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); + + switch (args.EventId) + { + case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: + case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: + case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); + break; + case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); + break; + } } void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) @@ -313,7 +313,7 @@ namespace PepperDash.Essentials.DM var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); var localAudioInputPort = - InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback); + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); ActiveVideoInputFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate(); @@ -338,68 +338,68 @@ namespace PepperDash.Essentials.DM OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); break; case EndpointTransmitterBase.AudioSourceFeedbackEventId: - var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback); - Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); + var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); + Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback); AudioSourceNumericFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio)); break; } - } - - /// - /// Relays the input stream change to the appropriate RoutingInputPort. - /// - void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) - { - return; - } - inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); - } - - /// - /// Relays the VideoAttributes change to a RoutingInputPort - /// - void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds - //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", - // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); - switch (eventId) - { - case VideoAttributeEventIds.HdcpActiveFeedbackEventId: - inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HdcpStateFeedbackEventId: - inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: - case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - } - } - - - - - #region IIROutputPorts Members - public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } - public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } - #endregion - - #region IComPorts Members - public CrestronCollection ComPorts { get { return Tx.ComPorts; } } - public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } - #endregion - } + } + + /// + /// Relays the input stream change to the appropriate RoutingInputPort. + /// + void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) + { + return; + } + inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); + } + + /// + /// Relays the VideoAttributes change to a RoutingInputPort + /// + void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds + //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", + // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); + switch (eventId) + { + case VideoAttributeEventIds.HdcpActiveFeedbackEventId: + inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HdcpStateFeedbackEventId: + inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: + case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + } + } + + + + + #region IIROutputPorts Members + public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } + public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } + #endregion + + #region IComPorts Members + public CrestronCollection ComPorts { get { return Tx.ComPorts; } } + public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } + #endregion + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index fb8f3ac5..70df8259 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -339,7 +339,7 @@ namespace PepperDash.Essentials.DM var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); var localAudioInputPort = - InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback); + InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); ActiveVideoInputFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate(); @@ -364,8 +364,8 @@ namespace PepperDash.Essentials.DM OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video)); break; case EndpointTransmitterBase.AudioSourceFeedbackEventId: - var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback); - Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); + var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback); + Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback); AudioSourceNumericFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio)); break; From c84ec4c899abc153f3788e3f00fbda8281e1fb46 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 26 Aug 2021 17:09:46 -0600 Subject: [PATCH 347/480] fix(essentials): #806 switches method to print times for consistent 12h format fix(essentials): #806 Updates more uses of ToShortTimeString() fix(essentials): #806 fixes for VideoCodecUIDriver fix(essentials): #806 final fixes for time format --- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 15 +++++++++------ .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 3 ++- .../PepperDashEssentialsBase/Global/Global.cs | 5 +++++ .../VideoCodec/VideoCodecBase.cs | 8 ++++---- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 8082a6cb..77810c6c 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Collections.Generic; +using System.Globalization; using Crestron.SimplSharp; using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.UI; @@ -470,7 +471,7 @@ namespace PepperDash.Essentials Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", CurrentRoom.OnFeedback.BoolValue, LastMeetingDismissedId, - lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : ""); + lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToString("t", Global.Culture) : ""); var meeting = meetings.LastOrDefault(m => m.Joinable); if (CurrentRoom.OnFeedback.BoolValue @@ -487,9 +488,11 @@ namespace PepperDash.Essentials } else { + + TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting"); - TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToShortTimeString()); - TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToShortTimeString()); + TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToString("t", Global.Culture)); + TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToString("t", Global.Culture)); TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title); TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer); TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join"); @@ -512,7 +515,7 @@ namespace PepperDash.Essentials // indexOf = 3, 4 meetings : if (indexOfNext < meetings.Count) TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, - meetings[indexOfNext].StartTime.ToShortTimeString()); + meetings[indexOfNext].StartTime.ToString("t", Global.Culture)); else TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today"); @@ -1209,8 +1212,8 @@ namespace PepperDash.Essentials foreach (var m in CurrentRoom.ScheduleSource.CodecSchedule.Meetings) { i++; - MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToShortTimeString(); - MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToShortTimeString(); + MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = m.StartTime.ToString("t", Global.Culture); + MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = m.EndTime.ToString("t", Global.Culture); MeetingOrContactMethodModalSrl.StringInputSig(i, 3).StringValue = m.Title; MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = string.Format("
{0}",m.Organizer); MeetingOrContactMethodModalSrl.StringInputSig(i, 5).StringValue = "Join"; diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 6dba53f5..f3f707c3 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Globalization; using System.Text.RegularExpressions; using Crestron.SimplSharp; using Crestron.SimplSharpPro; @@ -1008,7 +1009,7 @@ namespace PepperDash.Essentials.UIDrivers.VC // if it's today, show a simpler string string timeText = null; if (c.StartTime.Date == DateTime.Now.Date) - timeText = c.StartTime.ToShortTimeString(); + timeText = c.StartTime.ToString("t", Global.Culture); else if (c.StartTime == DateTime.MinValue) timeText = ""; else diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index aa71c1f7..121bc9b7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -1,5 +1,6 @@ using System; using System.Text.RegularExpressions; +using System.Globalization; using Crestron.SimplSharp; using System.Collections.Generic; using Crestron.SimplSharp.CrestronIO; @@ -28,6 +29,10 @@ namespace PepperDash.Essentials.Core public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } } + // TODO: consider making this configurable later + public static IFormatProvider Culture = CultureInfo.CreateSpecificCulture("en-US"); + + /// /// The file path prefix to the folder containing configuration files /// 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 c5cff74e..d34c9e3b 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 @@ -836,10 +836,10 @@ ScreenIndexIsPinnedTo: {8} (a{17}) //serials tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString()); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString()); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString()); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString()); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToString("t", Global.Culture)); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToString("t", Global.Culture)); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToString("t", Global.Culture)); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToString("t", Global.Culture)); tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); From 47035d83861299191dea088251cd7973efff5009 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 26 Aug 2021 17:38:49 -0600 Subject: [PATCH 348/480] fix(essentials): Attempt to catch case where meeting popup may not be dismissed if the room is on and the meeting is no longer joinable --- .../EssentialsHuddleVtc1PanelAvFunctionsDriver.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 77810c6c..2d5bd1dd 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -477,6 +477,10 @@ namespace PepperDash.Essentials if (CurrentRoom.OnFeedback.BoolValue && lastMeetingDismissed == meeting) { + // meeting no longer joinable, hide popup + if(meeting == null) + HideNextMeetingPopup(); + return; } From bfd383dfc7279991426233d96a70eafdf0dd5c51 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 27 Aug 2021 09:48:43 -0600 Subject: [PATCH 349/480] fix(essentials): Minor fixes for MockVc to make behavior more consistent with real hardware --- .../VC/EssentialsVideoCodecUiDriver.cs | 12 ++++++------ .../VideoCodec/MockVC/MockVC.cs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index f3f707c3..097ea1c1 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -127,12 +127,6 @@ namespace PepperDash.Essentials.UIDrivers.VC codec.CallStatusChange += new EventHandler(Codec_CallStatusChange); - // If the codec is ready, then get the values we want, otherwise wait - if (Codec.IsReady) - Codec_IsReady(); - else - codec.IsReadyChange += (o, a) => Codec_IsReady(); - //InCall = new BoolFeedback(() => false); LocalPrivacyIsMuted = new BoolFeedback(() => false); @@ -223,6 +217,12 @@ namespace PepperDash.Essentials.UIDrivers.VC SetupPasswordPrompt(); } + + // If the codec is ready, then get the values we want, otherwise wait + if (Codec.IsReady) + Codec_IsReady(); + else + codec.IsReadyChange += (o, a) => Codec_IsReady(); } catch (Exception e) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index ca199957..78302fcc 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -78,6 +78,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec SetupCameras(); + CreateOsdSource(); + SetIsReady(); } @@ -117,6 +119,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } bool _StandbyIsOn; + /// + /// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input + /// to enable routing + /// + private void CreateOsdSource() + { + OsdSource = new DummyRoutingInputsDevice(Key + "[osd]"); + DeviceManager.AddDevice(OsdSource); + var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn); + TieLineCollection.Default.Add(tl); + + //foreach(var input in Status.Video. + } /// /// Dials, yo! @@ -567,6 +582,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec void SetupCameras() { + SupportsCameraAutoMode = true; + + SupportsCameraOff = false; + Cameras = new List(); var internalCamera = new MockVCCamera(Key + "-camera1", "Near End", this); From 532f3ba2370336349d9e6eadc62538de9ec065cc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 27 Aug 2021 17:57:21 -0600 Subject: [PATCH 350/480] feat(essentails): #811 Adds IHasMeetingInfo, implements on ZoomRoom and updates UI drivers #812 --- .../UI/JoinConstants/UIBoolJoin.cs | 19 ++++ .../UI/JoinConstants/UIStringlJoin.cs | 17 +++ .../Essentials/EssentialsHeaderDriver.cs | 6 +- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 64 +++++++++-- .../VC/EssentialsVideoCodecUiDriver.cs | 37 +++++- .../Essentials Devices Common.csproj | 1 + .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 51 +++++++++ .../VideoCodec/Interfaces/IHasParticipants.cs | 9 ++ .../VideoCodec/Interfaces/IHasStartMeeting.cs | 5 + .../VideoCodec/ZoomRoom/ResponseObjects.cs | 52 ++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 107 +++++++++++++++++- 11 files changed, 345 insertions(+), 23 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index dd454d97..d1fb6697 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -49,6 +49,15 @@ namespace PepperDash.Essentials /// 1006 /// public const uint CallEndAllConfirmVisible = 1006; + /// + /// 1007 + /// + public const uint MeetingPasswordVisible = 1007; + /// + /// 1008 + /// + public const uint MeetingLeavePress = 1008; + @@ -153,6 +162,11 @@ namespace PepperDash.Essentials public const uint VCFavoriteVisibleStart = 1221; // RANGE IN USE public const uint VCFavoriteVisibleEnd = 1225; + + /// + /// 1230 + /// + public const uint VCStagingMeetNowPress = 1230; /// /// 1231 /// @@ -844,6 +858,11 @@ namespace PepperDash.Essentials /// 15067 ///
public const uint NotificationRibbonVisible = 15067; + /// + /// 15068 + /// + public const uint HeaderMeetingInfoVisible = 15068; + /// /// 15083 - Press for Call help desk on AC/VC /// diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index 67a5c6e2..45a2d3ea 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -27,6 +27,23 @@ namespace PepperDash.Essentials /// 1004 ///
public const uint CallSharedSourceNameText = 1004; + /// + /// 1005 + /// + public const uint MeetingIdText = 1005; + /// + /// 1006 + /// + public const uint MeetingHostText = 1006; + /// + /// 1007 + /// + public const uint MeetingPasswordText = 1007; + /// + /// 1008 + /// + public const uint MeetingNameText = 1008; + /// diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index 818498d7..8cff13c2 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -164,7 +164,7 @@ namespace PepperDash.Essentials CallCaretVisible = tempJoin + 10; TriList.SetSigFalseAction(tempJoin, () => { - avDriver.ShowActiveCallsList(); + avDriver.ShowActiveCallsListOrMeetingInfo(); if(avDriver.CurrentRoom.InCallFeedback.BoolValue) CaretInterlock.ShowInterlocked(CallCaretVisible); }); @@ -256,7 +256,7 @@ namespace PepperDash.Essentials TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress, () => { - avDriver.ShowActiveCallsList(); + avDriver.ShowActiveCallsListOrMeetingInfo(); if (avDriver.CurrentRoom.InCallFeedback.BoolValue) CaretInterlock.ShowInterlocked(CallCaretVisible); }); @@ -354,6 +354,8 @@ namespace PepperDash.Essentials headerPopupShown = true; else if (e.NewJoin == UIBoolJoin.HeaderActiveCallsListVisible) headerPopupShown = true; + else if (e.NewJoin == UIBoolJoin.HeaderMeetingInfoVisible) + headerPopupShown = true; else if (e.NewJoin == UIBoolJoin.HelpPageVisible) headerPopupShown = true; else if (e.NewJoin == UIBoolJoin.MeetingsOrContacMethodsListVisible) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 2d5bd1dd..7ff0e7f5 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -14,6 +14,7 @@ using PepperDash.Essentials.Core.PageManagers; using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; namespace PepperDash.Essentials { @@ -99,6 +100,9 @@ namespace PepperDash.Essentials /// public SubpageReferenceList MeetingOrContactMethodModalSrl { get; set; } + public uint CallListOrMeetingInfoPopoverVisibilityJoin { get; private set; } + + /// /// The list of buttons on the header. Managed with visibility only /// @@ -351,15 +355,17 @@ namespace PepperDash.Essentials /// /// Allows PopupInterlock to be toggled if the calls list is already visible, or if the codec is in a call /// - public void ShowActiveCallsList() + public void ShowActiveCallsListOrMeetingInfo() { TriList.SetBool(UIBoolJoin.CallEndAllConfirmVisible, true); - if(PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible) - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible); + + + if(PopupInterlock.CurrentJoin == CallListOrMeetingInfoPopoverVisibilityJoin) + PopupInterlock.ShowInterlockedWithToggle(CallListOrMeetingInfoPopoverVisibilityJoin); else { - if((CurrentRoom.ScheduleSource as VideoCodecBase).IsInCall) - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible); + if(CurrentRoom.VideoCodec.IsInCall) + PopupInterlock.ShowInterlockedWithToggle(CallListOrMeetingInfoPopoverVisibilityJoin); } } @@ -948,6 +954,18 @@ namespace PepperDash.Essentials _CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange; _CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange; _CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange; + + var scheduleAwareCodec = _CurrentRoom.VideoCodec as IHasScheduleAwareness; + if (scheduleAwareCodec != null) + { + scheduleAwareCodec.CodecSchedule.MeetingsListHasChanged -= CodecSchedule_MeetingsListHasChanged; + } + + var meetingInfoCodec = _CurrentRoom.VideoCodec as IHasMeetingInfo; + if (meetingInfoCodec != null) + { + meetingInfoCodec.MeetingInfoChanged -= meetingInfoCodec_MeetingInfoChanged; + } } _CurrentRoom = room; @@ -980,9 +998,23 @@ namespace PepperDash.Essentials _CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange; RefreshSourceInfo(); - if (_CurrentRoom.VideoCodec is IHasScheduleAwareness) + + var scheduleAwareCodec = _CurrentRoom.VideoCodec as IHasScheduleAwareness; + if (scheduleAwareCodec != null) { - (_CurrentRoom.VideoCodec as IHasScheduleAwareness).CodecSchedule.MeetingsListHasChanged += CodecSchedule_MeetingsListHasChanged; + scheduleAwareCodec.CodecSchedule.MeetingsListHasChanged += CodecSchedule_MeetingsListHasChanged; + } + + var meetingInfoCodec = _CurrentRoom.VideoCodec as IHasMeetingInfo; + if (meetingInfoCodec != null) + { + meetingInfoCodec.MeetingInfoChanged += new EventHandler(meetingInfoCodec_MeetingInfoChanged); + + CallListOrMeetingInfoPopoverVisibilityJoin = UIBoolJoin.HeaderMeetingInfoVisible; + } + else + { + CallListOrMeetingInfoPopoverVisibilityJoin = UIBoolJoin.HeaderActiveCallsListVisible; } CallSharingInfoVisibleFeedback = new BoolFeedback(() => _CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue); @@ -994,7 +1026,8 @@ namespace PepperDash.Essentials if (_CurrentRoom != null) _CurrentRoom.CurrentSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange); - TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey)); + // Moved to EssentialsVideoCodecUiDriver + //TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey)); (Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom); } @@ -1005,6 +1038,19 @@ namespace PepperDash.Essentials } } + void meetingInfoCodec_MeetingInfoChanged(object sender, MeetingInfoEventArgs e) + { + TriList.SetString(UIStringJoin.MeetingIdText, e.Info.Id); + TriList.SetString(UIStringJoin.MeetingHostText, e.Info.Host); + TriList.SetString(UIStringJoin.MeetingNameText, e.Info.Name); + + TriList.SetString(UIStringJoin.MeetingPasswordText, e.Info.Password); + // Show the password fields if one is present + TriList.SetBool(UIBoolJoin.MeetingPasswordVisible, string.IsNullOrEmpty(e.Info.Password) ? false : true); + + TriList.SetString(UIStringJoin.CallSharedSourceNameText, e.Info.ShareStatus); + } + void SetCurrentRoom(IEssentialsHuddleVtc1Room room) { if (_CurrentRoom == room) return; @@ -1514,6 +1560,8 @@ namespace PepperDash.Essentials ///
void PrepareForCodecIncomingCall(); + uint CallListOrMeetingInfoPopoverVisibilityJoin { get; } + SubpageReferenceList MeetingOrContactMethodModalSrl { get; } } } diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 097ea1c1..a48fc7a9 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -15,6 +15,7 @@ using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.Touchpanels.Keyboards; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using PepperDash.Essentials.Devices.Common.Cameras; namespace PepperDash.Essentials.UIDrivers.VC @@ -422,8 +423,8 @@ namespace PepperDash.Essentials.UIDrivers.VC ActiveCallsSRL.Count = (ushort)activeList.Count; // If Active Calls list is visible and codec is not in a call, hide the list - if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible) - Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible); + if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == Parent.CallListOrMeetingInfoPopoverVisibilityJoin) + Parent.PopupInterlock.ShowInterlockedWithToggle(Parent.CallListOrMeetingInfoPopoverVisibilityJoin); } /// @@ -514,15 +515,19 @@ namespace PepperDash.Essentials.UIDrivers.VC TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents); TriList.SetSigFalseAction(UIBoolJoin.VCStagingCameraPress, ShowCameraControls); TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress); + TriList.SetSigFalseAction(UIBoolJoin.VCStagingMeetNowPress, MeetNowPress); + TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, CallStopSharingPress); + TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () => { if (Codec.ActiveCalls.Count > 1) { - Parent.PopupInterlock.ShowInterlocked(UIBoolJoin.HeaderActiveCallsListVisible); + Parent.PopupInterlock.ShowInterlocked(Parent.CallListOrMeetingInfoPopoverVisibilityJoin); } else Codec.EndAllCalls(); }); + TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () => { Parent.PopupInterlock.HideAndClear(); @@ -1566,6 +1571,22 @@ namespace PepperDash.Essentials.UIDrivers.VC StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress); } + /// + /// Meet Now button + /// + void MeetNowPress() + { + var startMeetingCodec = Codec as IHasStartMeeting; + if (startMeetingCodec != null) + { + startMeetingCodec.StartMeeting(startMeetingCodec.DefaultMeetingDurationMin); + } + else + { + Debug.Console(2, "Codce does not implment IHasStartMeeting. Cannot meet now"); + } + } + /// /// Connect call button /// @@ -1576,6 +1597,16 @@ namespace PepperDash.Essentials.UIDrivers.VC Codec.Dial(DialStringBuilder.ToString()); } + /// + /// Stop Sharing button + /// + void CallStopSharingPress() + { + Codec.StopSharing(); + Parent.CurrentRoom.RunRouteAction("codecOsd", Parent.CurrentRoom.SourceListKey); + } + + /// /// /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index 75d01b0f..cff1e4c0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -120,6 +120,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs new file mode 100644 index 00000000..46a10b99 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + /// + /// Describes a device that provides meeting information (like a ZoomRoom) + /// + public interface IHasMeetingInfo + { + event EventHandler MeetingInfoChanged; + + MeetingInfo MeetingInfo { get; } + } + + /// + /// Represents the information about a meeting in progress + /// Currently used for Zoom meetings + /// + public class MeetingInfo + { + public string Id { get; private set; } + public string Name { get; private set; } + public string Host { get; set; } + public string Password { get; private set; } + public string ShareStatus { get; private set; } + + public MeetingInfo(string id, string name, string host, string password, string shareStatus) + { + Id = id; + Name = name; + Host = host; + Password = password; + ShareStatus = shareStatus; + } + } + + public class MeetingInfoEventArgs : EventArgs + { + public MeetingInfo Info { get; private set; } + + public MeetingInfoEventArgs(MeetingInfo info) + { + Info = info; + } + + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index d8c0c55c..46b1391b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -60,6 +61,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces } } + public Participant Host + { + get + { + return _currentParticipants.FirstOrDefault(p => p.IsHost); + } + } + public event EventHandler ParticipantsListHasChanged; public CodecParticipants() diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs index a01ec099..6af59534 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStartMeeting.cs @@ -21,5 +21,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// /// void StartMeeting(uint duration); + + /// + /// Leaves a meeting without ending it + /// + void LeaveMeeting(); } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 28073eb8..c42d7eee 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -431,6 +431,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { private string _dispState; private string _password; + private bool _isAirHostClientConnected; + private bool _isSharingBlackMagic; + private bool _isDirectPresentationConnected; + public string directPresentationPairingCode { get; set; } /// @@ -452,11 +456,51 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } } - public bool isAirHostClientConnected { get; set; } + + public bool isAirHostClientConnected + { + get { return _isAirHostClientConnected; } + set + { + if (value != _isAirHostClientConnected) + { + _isAirHostClientConnected = value; + NotifyPropertyChanged("isAirHostClientConnected"); + } + } + } + public bool isBlackMagicConnected { get; set; } public bool isBlackMagicDataAvailable { get; set; } - public bool isDirectPresentationConnected { get; set; } - public bool isSharingBlackMagic { get; set; } + + public bool isDirectPresentationConnected + { + get { return _isDirectPresentationConnected; } + set + { + if (value != _isDirectPresentationConnected) + { + _isDirectPresentationConnected = value; + NotifyPropertyChanged("isDirectPresentationConnected"); + } + } + } + + public bool isSharingBlackMagic + { + get { return _isSharingBlackMagic; } + set + { + if (value != _isSharingBlackMagic) + { + _isSharingBlackMagic = value; + NotifyPropertyChanged("isSharingBlackMagic"); + } + } + } + + + /// /// IOS Airplay code /// @@ -779,7 +823,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private bool _paused; private eSharingState _state; - public bool IsSharing; + public bool IsSharing { get; private set; } [JsonProperty("paused")] public bool Paused diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 83597081..0a12e25f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo { private const long MeetingRefreshTimer = 60000; public uint DefaultMeetingDurationMin { get; private set; } @@ -470,6 +470,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { SharingContentIsOnFeedback.FireUpdate(); ReceivingContent.FireUpdate(); + + // Update the share status of the meeting info + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus()); + MeetingInfo = meetingInfo; } }; @@ -618,6 +622,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; case "password": break; + case "isAirHostClientConnected": + case "isDirectPresentationConnected": + case "isSharingBlackMagic": + { + // Update the share status of the meeting info + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus()); + MeetingInfo = meetingInfo; + break; + } } }; @@ -957,9 +970,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { _syncState.LoginMessageReceived(); + // Fire up a thread to send the intial commands. CrestronInvoke.BeginInvoke(o => { + // Currently the feedback exclusions don't work when using the API in JSON response mode + // But leave these here in case the API gets updated in the future + + Thread.Sleep(100); // disable echo of commands SendText("echo off"); @@ -1179,6 +1197,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Call.Participants); Participants.CurrentParticipants = participants; + + // Update the share status of the meeting info + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus); + MeetingInfo = meetingInfo; + PrintCurrentCallParticipants(); break; @@ -1642,7 +1665,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom // If not crrently in a meeting, intialize the call object if (callStatus != zStatus.eCallStatus.IN_MEETING && callStatus != zStatus.eCallStatus.CONNECTING_MEETING) { - Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object"); + //Debug.Console(1, this, "[UpdateCallStatus] Creating new Status.Call object"); Status.Call = new zStatus.Call {Status = callStatus}; OnCallStatusChange(new CodecActiveCallItem() {Status = eCodecCallStatus.Disconnected}); @@ -1680,15 +1703,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ActiveCalls.Add(newCall); - Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", - Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + //Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", + //Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); OnCallStatusChange(newCall); } else { - Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", - Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + //Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", + //Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); } } } @@ -1748,6 +1771,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { base.OnCallStatusChange(item); + if (item.Status == eCodecCallStatus.Connected) + { + + var host = ""; + + if (Participants.Host != null) + host = Participants.Host.Name; + + MeetingInfo = new MeetingInfo( + Status.Call.Info.meeting_id, + Status.Call.Info.meeting_list_item.meetingName, + host, + Status.Call.Info.meeting_password, + GetSharingStatus() + ); + } + Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}", Status.Call != null ? Status.Call.Status.ToString() : "no call"); @@ -1757,6 +1797,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + private string GetSharingStatus() + { + string sharingState = "None"; + + if (Status.Call.Sharing.State == zEvent.eSharingState.Receiving) + { + sharingState = "Receiving Content"; + } + if (Status.Sharing.isAirHostClientConnected) + { + sharingState = "Sharing AirPlay"; + } + if (Status.Sharing.isDirectPresentationConnected) + { + sharingState = "Sharing Laptop"; + } + if (Status.Sharing.isSharingBlackMagic) + { + sharingState = "Sharing HDMI Source"; + } + + return sharingState; + } + public override void StartSharing() { SendText("zCommand Call Sharing HDMI Start"); @@ -2113,6 +2177,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText(string.Format("zCommand Dial StartPmi Duration: {0}", dur)); } + public void LeaveMeeting() + { + SendText("zCommand Call Leave"); + } + public override void EndCall(CodecActiveCallItem call) { SendText("zCommand Call Disconnect"); @@ -2737,6 +2806,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion + + #region IHasMeetingInfo Members + + public event EventHandler MeetingInfoChanged; + + private MeetingInfo _meetingInfo; + + public MeetingInfo MeetingInfo + { + get { return _meetingInfo; } + private set + { + if (value != _meetingInfo) + { + _meetingInfo = value; + + var handler = MeetingInfoChanged; + if (handler != null) + { + handler(this, new MeetingInfoEventArgs(_meetingInfo)); + } + } + } + } + + #endregion } /// From 0a1af098308d6921ded9fe174be7eecda94e08dd Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 30 Aug 2021 12:07:09 -0600 Subject: [PATCH 351/480] fix(essentials): Disables dial feedback phone formatting if codec is IHasStartMeeting --- .../UIDrivers/VC/EssentialsVideoCodecUiDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index a48fc7a9..326ea1f5 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -152,7 +152,7 @@ namespace PepperDash.Essentials.UIDrivers.VC // Return formatted when dialing, straight digits when in call DialStringFeedback = new StringFeedback(() => { - if (KeypadMode == eKeypadMode.Dial) + if (KeypadMode == eKeypadMode.Dial && !(Codec is IHasStartMeeting)) return GetFormattedDialString(DialStringBuilder.ToString()); else return DialStringBuilder.ToString(); From 3edb0145d0d61f025a6ce8218a5b13213344bfc7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 30 Aug 2021 15:00:13 -0600 Subject: [PATCH 352/480] fix(essentials): Adds JsonProperty attributes to MeetingInfo properties for serialization --- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index 46a10b99..4f1744b9 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { /// @@ -22,10 +24,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public class MeetingInfo { + [JsonProperty("id")] public string Id { get; private set; } + [JsonProperty("name")] public string Name { get; private set; } + [JsonProperty("host")] public string Host { get; set; } + [JsonProperty("password")] public string Password { get; private set; } + [JsonProperty("shareStatus")] public string ShareStatus { get; private set; } public MeetingInfo(string id, string name, string host, string password, string shareStatus) From 8af7b4b1dba6ec064dbd5415fa35ffdeaba752bb Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 30 Aug 2021 17:48:37 -0600 Subject: [PATCH 353/480] feat(essentials): Adds IsHost property to MeetingInfo to determine if the room is the host --- .../VC/EssentialsVideoCodecUiDriver.cs | 1 + .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 5 +++- .../VideoCodec/Interfaces/IHasParticipants.cs | 1 + .../VideoCodec/ZoomRoom/ResponseObjects.cs | 1 + .../VideoCodec/ZoomRoom/ZoomRoom.cs | 26 ++++++++++++++++--- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 326ea1f5..ac0611d6 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -152,6 +152,7 @@ namespace PepperDash.Essentials.UIDrivers.VC // Return formatted when dialing, straight digits when in call DialStringFeedback = new StringFeedback(() => { + // Format the number feedback if in dial mode and the codec is not IHasStartMeeting (ZoomRoom) if (KeypadMode == eKeypadMode.Dial && !(Codec is IHasStartMeeting)) return GetFormattedDialString(DialStringBuilder.ToString()); else diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index 4f1744b9..b49733ad 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -34,14 +34,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public string Password { get; private set; } [JsonProperty("shareStatus")] public string ShareStatus { get; private set; } + [JsonProperty("isHost")] + public Boolean IsHost { get; private set; } - public MeetingInfo(string id, string name, string host, string password, string shareStatus) + public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost) { Id = id; Name = name; Host = host; Password = password; ShareStatus = shareStatus; + IsHost = IsHost; } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index 46b1391b..409ccd89 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -93,6 +93,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { public int UserId { get; set; } public bool IsHost { get; set; } + public bool IsMyself { get; set; } public string Name { get; set; } public bool CanMuteVideo { get; set; } public bool CanUnmuteVideo { get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index c42d7eee..aac45f51 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1489,6 +1489,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom UserId = p.UserId, Name = p.UserName, IsHost = p.IsHost, + IsMyself = p.IsMyself, CanMuteVideo = p.IsVideoCanMuteByHost, CanUnmuteVideo = p.IsVideoCanUnmuteByHost, AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED", diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 0a12e25f..a51555df 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -472,7 +472,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ReceivingContent.FireUpdate(); // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus()); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself()); MeetingInfo = meetingInfo; } }; @@ -627,7 +627,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "isSharingBlackMagic": { // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus()); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself()); MeetingInfo = meetingInfo; break; } @@ -1199,7 +1199,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants.CurrentParticipants = participants; // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself()); MeetingInfo = meetingInfo; PrintCurrentCallParticipants(); @@ -1784,7 +1784,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Call.Info.meeting_list_item.meetingName, host, Status.Call.Info.meeting_password, - GetSharingStatus() + GetSharingStatus(), + GetIsHostMyself() ); } @@ -1821,6 +1822,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom return sharingState; } + /// + /// Will return true if the host is myself (this zoom room) + /// + /// + private bool GetIsHostMyself() + { + var host = Participants.Host; + + if(host == null) + { + Debug.Console(2, this, "Host is currently null"); + return false; + } + Debug.Console(2, this, "Host is: {0} myself?: {1}", host.Name, host.IsMyself); + return host.IsMyself; + } + public override void StartSharing() { SendText("zCommand Call Sharing HDMI Start"); From a54cd9e1df3685f786dba017c27e89afdf04793a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 31 Aug 2021 10:13:56 -0600 Subject: [PATCH 354/480] feat(essentials): minor syntax updates --- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 2 +- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index b49733ad..a2d08a34 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -29,7 +29,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces [JsonProperty("name")] public string Name { get; private set; } [JsonProperty("host")] - public string Host { get; set; } + public string Host { get; private set; } [JsonProperty("password")] public string Password { get; private set; } [JsonProperty("shareStatus")] diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a51555df..379b1621 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1835,7 +1835,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(2, this, "Host is currently null"); return false; } - Debug.Console(2, this, "Host is: {0} myself?: {1}", host.Name, host.IsMyself); + Debug.Console(2, this, "Host is: '{0}' IsMyself?: {1}", host.Name, host.IsMyself); return host.IsMyself; } From adec25104cb40202df9f75c459254f3389f51ab0 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 31 Aug 2021 16:40:04 -0600 Subject: [PATCH 355/480] feat(essentials): Updates to UI to deal with sharing feedback with no external sources. Adds End/Leave meeting button logic on meeting info subpage --- .../UI/JoinConstants/UIBoolJoin.cs | 9 +++---- .../UI/JoinConstants/UIStringlJoin.cs | 7 +++++- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 24 +++++++++++++++++-- .../VC/EssentialsVideoCodecUiDriver.cs | 22 +++++++++++++++++ .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 2 +- 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index d1fb6697..1a127000 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -61,6 +61,7 @@ namespace PepperDash.Essentials + // Audio Conference /// /// 1101 @@ -766,10 +767,10 @@ namespace PepperDash.Essentials /// 15044 Close button for source modal overlay /// public const uint SourceBackgroundOverlayClosePress = 15044; - ///// - ///// 15045 - Visibility for the bar containing call navigation button list - ///// - //public const uint CallStagingBarVisible = 15045; + /// + /// 15045 + /// + public const uint ZoomRoomContentSharingVisible = 15045; /// /// 15046 /// diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index 45a2d3ea..38a86fbb 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -42,7 +42,12 @@ namespace PepperDash.Essentials /// /// 1008 /// - public const uint MeetingNameText = 1008; + public const uint MeetingLeaveText = 1008; + /// + /// 1009 + /// + public const uint MeetingNameText = 1009; + diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 7ff0e7f5..3eb78613 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -181,6 +181,8 @@ namespace PepperDash.Essentials private UiDisplayMode _currentMode; + private uint _sourceListCount; + /// /// The mode showing. Presentation or call. /// @@ -647,9 +649,24 @@ namespace PepperDash.Essentials TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); - TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + if (presentationMode && CurrentRoom.VideoCodec is IHasMeetingInfo && _sourceListCount < 2) + { + // For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); + TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true); + } + else + { + // Otherwise, show the staging bar + TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, false); + TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, presentationMode ? true : false); + + } if (!presentationMode) + { + TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, false); TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + } CallButtonSig.BoolValue = callMode && CurrentRoom.ShutdownType == eShutdownType.None; @@ -1049,6 +1066,8 @@ namespace PepperDash.Essentials TriList.SetBool(UIBoolJoin.MeetingPasswordVisible, string.IsNullOrEmpty(e.Info.Password) ? false : true); TriList.SetString(UIStringJoin.CallSharedSourceNameText, e.Info.ShareStatus); + + TriList.SetString(UIStringJoin.MeetingLeaveText, e.Info.IsHost ? "End Meeting" : "Leave Meeting"); } void SetCurrentRoom(IEssentialsHuddleVtc1Room room) @@ -1164,7 +1183,8 @@ namespace PepperDash.Essentials Debug.Console(1, "**** KEY {0}", kvp.Key); } - SourceStagingSrl.Count = (ushort)(i - 1); + _sourceListCount = (i - 1); + SourceStagingSrl.Count = (ushort)_sourceListCount; } } diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index ac0611d6..7ec44346 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -534,6 +534,28 @@ namespace PepperDash.Essentials.UIDrivers.VC Parent.PopupInterlock.HideAndClear(); Codec.EndAllCalls(); }); + + var meetingInfoCodec = Codec as IHasMeetingInfo; + if (meetingInfoCodec != null) + { + TriList.SetSigFalseAction(UIBoolJoin.MeetingLeavePress, () => + { + Parent.PopupInterlock.HideAndClear(); + + if (meetingInfoCodec.MeetingInfo.IsHost) + { + Codec.EndAllCalls(); + } + else + { + var startMeetingCodec = Codec as IHasStartMeeting; + if (startMeetingCodec != null) + { + startMeetingCodec.LeaveMeeting(); + } + } + }); + } } void SetupCameraControls() diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index a2d08a34..236fde80 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -44,7 +44,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces Host = host; Password = password; ShareStatus = shareStatus; - IsHost = IsHost; + IsHost = isHost; } } From 8539a6b79c3c0d60689c3c6a1249f25311631d67 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 31 Aug 2021 18:18:24 -0600 Subject: [PATCH 356/480] fix(essentials): minor fixes to UI oddities --- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 3eb78613..09443d45 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -181,6 +181,14 @@ namespace PepperDash.Essentials private UiDisplayMode _currentMode; + private bool _isZoomRoomWithNoExternalSources + { + get + { + return CurrentRoom.VideoCodec is Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom && _sourceListCount <= 1; + } + } + private uint _sourceListCount; /// @@ -649,7 +657,7 @@ namespace PepperDash.Essentials TriList.SetBool(StartPageVisibleJoin, startMode ? true : false); - if (presentationMode && CurrentRoom.VideoCodec is IHasMeetingInfo && _sourceListCount < 2) + if (presentationMode &&_isZoomRoomWithNoExternalSources) { // For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); @@ -704,25 +712,39 @@ namespace PepperDash.Essentials if (VCDriver.IsVisible) VCDriver.Hide(); HideNextMeetingPopup(); - // Run default source when room is off and share is pressed - if (!CurrentRoom.OnFeedback.BoolValue) - { - // If there's no default, show UI elements - if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) - TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - } - else // room is on show what's active or select a source if nothing is yet active + + + if (_isZoomRoomWithNoExternalSources) { - if(CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) - TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - else if (CurrentSourcePageManager != null) + (CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute(); + // For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage + TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true); + + if (CurrentSourcePageManager != null) + CurrentSourcePageManager.Hide(); + } + else + { + // Run default source when room is off and share is pressed + if (!CurrentRoom.OnFeedback.BoolValue) { - TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); - CurrentSourcePageManager.Show(); + // If there's no default, show UI elements + if (!(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute()) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); } + else // room is on show what's active or select a source if nothing is yet active + { + if (CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) + TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); + else if (CurrentSourcePageManager != null) + { + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + CurrentSourcePageManager.Show(); + } + } + SetupSourceList(); } CurrentMode = UiDisplayMode.Presentation; - SetupSourceList(); } /// @@ -761,7 +783,7 @@ namespace PepperDash.Essentials /// void ShowCurrentSource() { - if (CurrentRoom.CurrentSourceInfo == null) + if (CurrentRoom.CurrentSourceInfo == null || _isZoomRoomWithNoExternalSources) return; CurrentMode = UiDisplayMode.Presentation; From 9a1b069e2400a84e43560f0023a703fadc06f71d Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 2 Sep 2021 08:21:37 -0500 Subject: [PATCH 357/480] feat: Added debug statements to sensor set and sensitivity methods. fix: Replaced SetSigTrueAction and SetSigFalseAction calling SetEnable state with a single SetBoolSigAction. --- .../PartitionSensor/GlsPartitionSensorController.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index b0b58f34..bd67dfec 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -126,6 +126,7 @@ namespace PepperDash.Essentials.Core public void SetEnableState(bool state) { + Debug.Console(2, this, "Sensor is {0}, SetEnableState: {1}", _partitionSensor == null ? "null" : "not null", state); if (_partitionSensor == null) return; @@ -134,6 +135,7 @@ namespace PepperDash.Essentials.Core public void IncreaseSensitivity() { + Debug.Console(2, this, "Sensor is {0}, IncreaseSensitivity", _partitionSensor == null ? "null" : "not null"); if (_partitionSensor == null) return; @@ -142,6 +144,7 @@ namespace PepperDash.Essentials.Core public void DecreaseSensitivity() { + Debug.Console(2, this, "Sensor is {0}, DecreaseSensitivity", _partitionSensor == null ? "null" : "not null"); if (_partitionSensor == null) return; @@ -150,6 +153,7 @@ namespace PepperDash.Essentials.Core public void SetSensitivity(ushort value) { + Debug.Console(2, this, "Sensor is {0}, SetSensitivity: {1}", _partitionSensor == null ? "null" : "not null", value); if (_partitionSensor == null) return; @@ -177,8 +181,7 @@ namespace PepperDash.Essentials.Core Debug.Console(0, this, "Linking to Bridge Type {0}", GetType().Name); // link input from simpl - trilist.SetSigTrueAction(joinMap.Enable.JoinNumber, () => SetEnableState(true)); - trilist.SetSigFalseAction(joinMap.Enable.JoinNumber, () => SetEnableState(false)); + trilist.SetBoolSigAction(joinMap.Enable.JoinNumber, SetEnableState); trilist.SetSigTrueAction(joinMap.IncreaseSensitivity.JoinNumber, IncreaseSensitivity); trilist.SetSigTrueAction(joinMap.DecreaseSensitivity.JoinNumber, DecreaseSensitivity); trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity); From 9b64b7b7f38bb88e5b1b91edeb194bb5f8542f21 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 11:40:27 -0600 Subject: [PATCH 358/480] fix:(Essentials) Created MeetingInfo Object if it didn't previously exist --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 379b1621..d146ec4e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -626,6 +626,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "isDirectPresentationConnected": case "isSharingBlackMagic": { + Debug.Console(2, this, "Updating sharing status: {0}", a.PropertyName); + + if (MeetingInfo == null) + { + MeetingInfo = new MeetingInfo("", "", "", "", + GetSharingStatus(), GetIsHostMyself()); + } // Update the share status of the meeting info var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself()); MeetingInfo = meetingInfo; @@ -1828,6 +1835,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// private bool GetIsHostMyself() { + if (Participants.CurrentParticipants.Count == 0) + { + Debug.Console(2, this, "No current participants"); + return false; + } + var host = Participants.Host; if(host == null) From d50027cc826d41f71a606262f5d625e14af00353 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 17:33:53 -0600 Subject: [PATCH 359/480] feat:(Essentials) Add IHasPresentationOnlyMeeting interface --- .../Essentials Devices Common.csproj | 1 + .../Interfaces/IHasPresentationOnlyMeeting.cs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index cff1e4c0..fc5f68d4 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -122,6 +122,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs new file mode 100644 index 00000000..06730d2a --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasPresentationOnlyMeeting.cs @@ -0,0 +1,18 @@ +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + public interface IHasPresentationOnlyMeeting + { + void StartSharingOnlyMeeting(); + void StartSharingOnlyMeeting(eSharingMeetingMode mode); + void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration); + void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration, string password); + void StartNormalMeetingFromSharingOnlyMeeting(); + } + + public enum eSharingMeetingMode + { + None, + Laptop, + Ios, + } +} \ No newline at end of file From c255ae1525056acfcc4534baf5dc04239d61a631 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 18:11:14 -0600 Subject: [PATCH 360/480] feat:(Essentials) Add IsSharingMeeting property --- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index 236fde80..cd9e2906 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -36,8 +36,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public string ShareStatus { get; private set; } [JsonProperty("isHost")] public Boolean IsHost { get; private set; } + [JsonProperty("isSharingMeeting")] + public Boolean IsSharingMeeting { get; private set; } - public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost) + public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting) { Id = id; Name = name; @@ -45,6 +47,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces Password = password; ShareStatus = shareStatus; IsHost = isHost; + IsSharingMeeting = isSharingMeeting; } } From 2d0dcd7336697fdc9eeec2a0466abe468fadeee1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 18:11:48 -0600 Subject: [PATCH 361/480] feat:(Essentials) Add StartLocalPresentMeeting class --- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index aac45f51..35b6c3b2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -756,6 +756,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// public class zEvent { + public class StartLocalPresentMeeting + { + public bool Success { get; set; } + } public class NeedWaitForHost { public bool Wait { get; set; } From 44509dc5ae564ec96973f5a444b784db112818c2 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 18:12:13 -0600 Subject: [PATCH 362/480] feat:(Essentials) Add IsSharingMeeting setting to MeetingInfo --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index d146ec4e..a426193b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting { private const long MeetingRefreshTimer = 60000; public uint DefaultMeetingDurationMin { get; private set; } @@ -472,7 +472,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ReceivingContent.FireUpdate(); // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself()); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); MeetingInfo = meetingInfo; } }; @@ -630,11 +630,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (MeetingInfo == null) { - MeetingInfo = new MeetingInfo("", "", "", "", - GetSharingStatus(), GetIsHostMyself()); + //Ignoring for now, as the CallInfo return will create the appropriate value + return; } // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself()); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); MeetingInfo = meetingInfo; break; } @@ -1206,7 +1206,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants.CurrentParticipants = participants; // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself()); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself(), MeetingInfo.IsSharingMeeting); MeetingInfo = meetingInfo; PrintCurrentCallParticipants(); @@ -1485,6 +1485,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom break; } + case "startlocalpresentmeeting": + { + var result = JsonConvert.DeserializeObject(responseObj.ToString()); + + if (result.Success) + { + MeetingInfo = new MeetingInfo("", "", "", "", "", true, true); + break; + } + + break; + } default: { break; @@ -1776,8 +1788,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom protected override void OnCallStatusChange(CodecActiveCallItem item) { - base.OnCallStatusChange(item); - if (item.Status == eCodecCallStatus.Connected) { @@ -1792,10 +1802,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom host, Status.Call.Info.meeting_password, GetSharingStatus(), - GetIsHostMyself() + GetIsHostMyself(), + !String.Equals(Status.Call.Info.meeting_type,"NORMAL") ); } + base.OnCallStatusChange(item); + Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}", Status.Call != null ? Status.Call.Status.ToString() : "no call"); @@ -2153,6 +2166,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void Dial(string number) { + Debug.Console(2, this, "Dialing number: {0}", number); _lastDialedMeetingNumber = number; SendText(string.Format("zCommand Dial Join meetingNumber: {0}", number)); } @@ -2863,7 +2877,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion - } + + #region Implementation of IHasPresentationOnlyMeeting + + public void StartSharingOnlyMeeting() + { + StartSharingOnlyMeeting(eSharingMeetingMode.None, 30, String.Empty); + } + + public void StartSharingOnlyMeeting(eSharingMeetingMode mode) + { + StartSharingOnlyMeeting(mode, 30, String.Empty); + } + + public void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration) + { + StartSharingOnlyMeeting(mode, duration, String.Empty); + } + + public void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration, string password) + { + SendText(String.Format("zCommand Dial Sharing Duration: {0} DisplayState: {1} Password: {2}", duration, mode, password)); + } + + public void StartNormalMeetingFromSharingOnlyMeeting() + { + Debug.Console(2, this, "Converting Sharing Meeting to Normal Meeting"); + SendText("zCommand call sharing ToNormal"); + } + + #endregion + } /// /// Zoom Room specific info object From f791feb848a17ac5cbbd38a82d35e8e7b62f5215 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 18:12:52 -0600 Subject: [PATCH 363/480] feat:(Essentials) Update UI functionality depending on Zoom Meeting type --- .../Essentials/EssentialsHeaderDriver.cs | 12 +++- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 9 ++- .../VC/EssentialsVideoCodecUiDriver.cs | 56 ++++++++++++++++--- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index 8cff13c2..f42b9de2 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -12,6 +12,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.PageManagers; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; @@ -191,6 +192,8 @@ namespace PepperDash.Essentials return; } + var meetingInfoCodec = codec as IHasMeetingInfo; + // Set mode of header button if (!codec.IsInCall) { @@ -210,8 +213,15 @@ namespace PepperDash.Essentials Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count); if (codec.ActiveCalls.Count > 0) { - if (codec.ActiveCalls.Count == 1) + if (codec.ActiveCalls.Count == 1 && meetingInfoCodec == null) TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "1 Active Call"); + else if (codec.ActiveCalls.Count == 1 && meetingInfoCodec != null) + { + var headerCallStatusLabel = meetingInfoCodec.MeetingInfo.IsSharingMeeting + ? "Sharing Active" + : "Active Meeting"; + TriList.SetString(UIStringJoin.HeaderCallStatusLabel, headerCallStatusLabel); + } else if (codec.ActiveCalls.Count > 1) TriList.SetString(UIStringJoin.HeaderCallStatusLabel, string.Format("{0} Active Calls", codec.ActiveCalls.Count)); } diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 09443d45..246573a9 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -716,10 +716,17 @@ namespace PepperDash.Essentials if (_isZoomRoomWithNoExternalSources) { - (CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute(); + CurrentRoom.RunDefaultPresentRoute(); // For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true); + var presentationMeetingCodec = CurrentRoom.VideoCodec as IHasPresentationOnlyMeeting; + + if (presentationMeetingCodec != null && !CurrentRoom.VideoCodec.IsInCall) + { + presentationMeetingCodec.StartSharingOnlyMeeting(eSharingMeetingMode.Laptop); + } + if (CurrentSourcePageManager != null) CurrentSourcePageManager.Hide(); } diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 7ec44346..9bbaad6f 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -134,11 +134,12 @@ namespace PepperDash.Essentials.UIDrivers.VC VCControlsInterlock = new JoinedSigInterlock(triList); VCCameraControlModeInterlock = new JoinedSigInterlock(triList); + VCControlsInterlock.HideAndClear(); - if (CodecHasFavorites) + /* if (CodecHasFavorites || codec is IHasZoomRoomLayouts) //Checking for Zoom Room...picked a ZoomRoom specific interface to check for VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadWithFavoritesVisible); else - VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); + VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); */ StagingBarsInterlock = new JoinedSigInterlock(triList); if(Codec is IHasCallHistory) @@ -320,6 +321,7 @@ namespace PepperDash.Essentials.UIDrivers.VC void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e) { var call = e.CallItem; + var meetingInfoSender = sender as IHasMeetingInfo; switch (e.CallItem.Status) { @@ -354,7 +356,10 @@ namespace PepperDash.Essentials.UIDrivers.VC DialStringBuilder.Remove(0, DialStringBuilder.Length); DialStringFeedback.FireUpdate(); Parent.ShowNotificationRibbon("Disconnected", 2000); + Debug.Console(0, "Setting Connect Button mode to 0"); } + + break; case eCodecCallStatus.Disconnecting: break; @@ -375,12 +380,23 @@ namespace PepperDash.Essentials.UIDrivers.VC ShowIncomingModal(call); break; } - default: - break; } - TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0); - - uint stageJoin; + + if (meetingInfoSender != null && Codec.IsInCall) + { + var meetingInfo = meetingInfoSender.MeetingInfo; + + TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = + (ushort) (meetingInfo.IsSharingMeeting ? 2 : 1); + } + else + { + + TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = + (ushort) (Codec.IsInCall ? 1 : 0); + } + + uint stageJoin; if (Codec.IsInCall) stageJoin = UIBoolJoin.VCStagingActivePopoverVisible; else @@ -519,14 +535,35 @@ namespace PepperDash.Essentials.UIDrivers.VC TriList.SetSigFalseAction(UIBoolJoin.VCStagingMeetNowPress, MeetNowPress); TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, CallStopSharingPress); + var meetingInfoCodec = Codec as IHasMeetingInfo; + TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () => { if (Codec.ActiveCalls.Count > 1) { Parent.PopupInterlock.ShowInterlocked(Parent.CallListOrMeetingInfoPopoverVisibilityJoin); } + else if (meetingInfoCodec != null && Codec.ActiveCalls.Count == 1) + { + var meetingInfo = meetingInfoCodec.MeetingInfo; + + if (meetingInfo != null && meetingInfo.IsSharingMeeting) + { + var presentationMeetingCodec = Codec as IHasPresentationOnlyMeeting; + if (presentationMeetingCodec != null) + { + presentationMeetingCodec.StartNormalMeetingFromSharingOnlyMeeting(); + } + } + else + { + Codec.EndAllCalls(); + } + } else + { Codec.EndAllCalls(); + } }); TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () => @@ -535,7 +572,7 @@ namespace PepperDash.Essentials.UIDrivers.VC Codec.EndAllCalls(); }); - var meetingInfoCodec = Codec as IHasMeetingInfo; + if (meetingInfoCodec != null) { TriList.SetSigFalseAction(UIBoolJoin.MeetingLeavePress, () => @@ -1801,7 +1838,7 @@ namespace PepperDash.Essentials.UIDrivers.VC /// void PasswordKeypadClear() { - PasswordStringBuilder.Remove(0, SearchStringBuilder.Length); + PasswordStringBuilder.Remove(0, PasswordStringBuilder.Length); PasswordStringFeedback.FireUpdate(); PasswordStringCheckEnables(); @@ -1929,6 +1966,7 @@ namespace PepperDash.Essentials.UIDrivers.VC _passwordPromptDialogVisible = false; Parent.Keyboard.Hide(); TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible); + PasswordKeypadClear(); } } } From 93dfb8780b7753d1255b6ed432b83bf51a020670 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 7 Sep 2021 18:13:18 -0600 Subject: [PATCH 364/480] feat:(Essentials) Add doc info and meeting button text join --- PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs | 5 +++++ PepperDashEssentials/UI/JoinConstants/UIUshortJoin.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs index 38a86fbb..6741be35 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIStringlJoin.cs @@ -48,6 +48,11 @@ namespace PepperDash.Essentials /// public const uint MeetingNameText = 1009; + /// + /// 1240 - Used to determine text for meeting start button + /// + public const uint MeetingStartButtonText = 1240; + diff --git a/PepperDashEssentials/UI/JoinConstants/UIUshortJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIUshortJoin.cs index ffc7f19e..73356bf3 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIUshortJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIUshortJoin.cs @@ -7,7 +7,7 @@ { // Video Codec /// - /// 1234: values 0 = Connect, 1 = End + /// 1234: values 0 = Connect, 1 = End, 2 = Start Meeting /// public const uint VCStagingConnectButtonMode = 1234; From 77134f0a3016f423a75bf69c789236f29fa8d447 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 8 Sep 2021 14:15:52 -0600 Subject: [PATCH 365/480] feat:(Essentials_DM) Update AddInputPortWithDebug Adding an `IVideoAttributesBasic` as a parameter for this method relatively easily allows us to get the reported input resolution when it changes. --- .../Chassis/DmChassisController.cs | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 8c6b2ced..168e51f3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -816,20 +816,47 @@ namespace PepperDash.Essentials.DM /// void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { - AddInputPortWithDebug(cardNum, portName, sigType, portType, null); + //Cast is necessary here to determine the correct overload + AddInputPortWithDebug(cardNum, portName, sigType, portType, null, null); + } + + private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, + eRoutingPortConnectionType portType, ICec cecPort) + { + //Cast is necessary here to determine the correct overload + AddInputPortWithDebug(cardNum, portName, sigType, portType, cecPort, null); } /// - /// Adds InputPort and sets Port as ICec object + /// Adds InputPort and sets Port as ICec object. If videoAttributesBasic is defined, RoutingPort will be RoutingInputPortWithVideoStatuses /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort, IVideoAttributesBasic videoAttributesBasic) { var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this) + + RoutingInputPort inputPort; + + if (videoAttributesBasic != null) { - FeedbackMatchObject = Chassis.Inputs[cardNum] - }; ; + var statusFuncs = new VideoStatusFuncsWrapper + { + VideoResolutionFeedbackFunc = () => videoAttributesBasic.VideoAttributes.GetVideoResolutionString() + }; + inputPort = new RoutingInputPortWithVideoStatuses(portKey, sigType, portType, + Chassis.Inputs[cardNum], this, statusFuncs) + { + FeedbackMatchObject = Chassis.Inputs[cardNum] + }; + } + else + { + inputPort = new RoutingInputPort(portKey, sigType, portType, + Chassis.Inputs[cardNum], this) + { + FeedbackMatchObject = Chassis.Inputs[cardNum] + }; + } if (cecPort != null) inputPort.Port = cecPort; From d00a31e3a62d496464f31ff3b3bca77bfbb5a033 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 8 Sep 2021 14:17:24 -0600 Subject: [PATCH 366/480] feat(Essentials_DM): Add overloads for `AddDmInCardPorts` & `AddHdmiInCardPorts` --- .../Essentials_DM/Chassis/DmChassisController.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 168e51f3..3e66af96 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -672,12 +672,24 @@ namespace PepperDash.Essentials.DM AddInCardHdmiAndAudioLoopPorts(number); } + void AddDmInCardPorts(uint number, ICec cecPort, IVideoAttributesBasic videoAttributes) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort, videoAttributes); + AddInCardHdmiAndAudioLoopPorts(number); + } + void AddHdmiInCardPorts(uint number, ICec cecPort) { AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); AddInCardHdmiAndAudioLoopPorts(number); } + void AddHdmiInCardPorts(uint number, ICec cecPort, IVideoAttributesBasic videoAttributes) + { + AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort, videoAttributes); + AddInCardHdmiAndAudioLoopPorts(number); + } + void AddInCardHdmiAndAudioLoopPorts(uint number) { AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, From a28a078c4f671246e5c0e0264ecb0fe7adeccf53 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 8 Sep 2021 15:25:43 -0600 Subject: [PATCH 367/480] feat(Essentials_DM): Update all card creation methods to pass appropriate input --- .../Chassis/DmChassisController.cs | 203 +++++++++++------- 1 file changed, 127 insertions(+), 76 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 3e66af96..8cd53e33 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -497,166 +497,189 @@ namespace PepperDash.Essentials.DM { case "dmchd": { - var inputCard = new DmcHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + var inputCard = new DmcHd(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); } break; case "dmchddsp": { - var inputCard = new DmcHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + var inputCard = new DmcHdDsp(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); } break; case "dmc4khd": { - var inputCard = new Dmc4kHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + var inputCard = new Dmc4kHd(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); } break; case "dmc4khddsp": { - var inputCard = new Dmc4kHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); + var inputCard = new Dmc4kHdDsp(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); } break; case "dmc4kzhd": { - var inputCard = new Dmc4kzHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } + var inputCard = new Dmc4kzHd(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); break; + } case "dmc4kzhddsp": { - var inputCard = new Dmc4kzHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } + var inputCard = new Dmc4kzHdDsp(number, Chassis); + AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput); break; + } case "dmcc": { - var inputCard = new DmcC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + var inputCard = new DmcC(number, Chassis); + //DmInput doesn't implement ICec...cast was resulting in null anyway + AddDmInCardPorts(number, null, inputCard.DmInput); } break; case "dmccdsp": { - var inputCard = new DmcCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } + var inputCard = new DmcCDsp(number, Chassis); + //DmInput doesn't implement ICec...cast was resulting in null anyway + AddDmInCardPorts(number, null, inputCard.DmInput); break; + } + case "dmc4kc": { - var inputCard = new Dmc4kC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } + var inputCard = new Dmc4kC(number, Chassis); + AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput); break; + } + case "dmc4kcdsp": { - var inputCard = new Dmc4kCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } + var inputCard = new Dmc4kCDsp(number, Chassis); + AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput); break; + } + case "dmc4kzc": { - var inputCard = new Dmc4kzC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } + var inputCard = new Dmc4kzC(number, Chassis); + AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput); break; + } + case "dmc4kzcdsp": { - var inputCard = new Dmc4kzCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); + var inputCard = new Dmc4kzCDsp(number, Chassis); + AddDmInCardPorts(number, inputCard.DmInput, inputCard.DmInput); + break; } - break; + case "dmccat": - new DmcCat(number, this.Chassis); - AddDmInCardPorts(number); + { + var inputCard = new DmcCat(number, Chassis); + AddDmInCardPorts(number, null, inputCard.DmInput); break; + } case "dmccatdsp": - new DmcCatDsp(number, this.Chassis); - AddDmInCardPorts(number); + { + var inputCard = new DmcCatDsp(number, Chassis); + AddDmInCardPorts(number, null, inputCard.DmInput); break; + } case "dmcs": - new DmcS(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + { + var inputCard = new DmcS(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, null, inputCard.DmInput); AddInCardHdmiAndAudioLoopPorts(number); break; + } case "dmcsdsp": - new DmcSDsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + { + var inputCard = new DmcSDsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, null, inputCard.DmInput); AddInCardHdmiAndAudioLoopPorts(number); break; + } case "dmcs2": - new DmcS2(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + { + var inputCard = new DmcS2(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, null, inputCard.DmInput); AddInCardHdmiAndAudioLoopPorts(number); break; + } case "dmcs2dsp": - new DmcS2Dsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + { + var inputCard = new DmcS2Dsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, null, inputCard.DmInput); AddInCardHdmiAndAudioLoopPorts(number); break; + } case "dmcsdi": - new DmcSdi(number, Chassis); - AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); + { + var inputCard = new DmcSdi(number, Chassis); + AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi, null, inputCard.SdiInput); AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi, null); AddInCardHdmiAndAudioLoopPorts(number); break; + } case "dmcdvi": - new DmcDvi(number, Chassis); - AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); + { + var inputCard = new DmcDvi(number, Chassis); + AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi, null, inputCard.DviInput); AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); AddInCardHdmiLoopPort(number); break; + } case "dmcvga": - new DmcVga(number, Chassis); - AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); + { + var inputCard = new DmcVga(number, Chassis); + AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, null, inputCard.VgaInput); AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); AddInCardHdmiLoopPort(number); break; + } case "dmcvidbnc": - new DmcVidBnc(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + { + var inputCard = new DmcVidBnc(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput); AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); AddInCardHdmiLoopPort(number); break; + } case "dmcvidrcaa": - new DmcVidRcaA(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + { + var inputCard = new DmcVidRcaA(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput); AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); AddInCardHdmiLoopPort(number); break; + } case "dmcvidrcad": - new DmcVidRcaD(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + { + var inputCard = new DmcVidRcaD(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput); AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); AddInCardHdmiLoopPort(number); break; + } case "dmcvid4": - new DmcVid4(number, Chassis); + { + var inputCard = new DmcVid4(number, Chassis); AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); AddInCardHdmiLoopPort(number); break; + } case "dmcstr": - new DmcStr(number, Chassis); - AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); + { + var inputCard = new DmcStr(number, Chassis); + AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming, null, inputCard.Source); AddInCardHdmiAndAudioLoopPorts(number); break; + } } } @@ -1089,7 +1112,7 @@ namespace PepperDash.Essentials.DM var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis. Outputs[output].VideoOutFeedback.Number; - Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output); + Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", Name, inputNumber, output); if (VideoOutputFeedbacks.ContainsKey(output)) { @@ -1116,7 +1139,7 @@ namespace PepperDash.Essentials.DM var inputNumber = Chassis.Outputs[output].AudioOutFeedback == null ? 0 : Chassis. Outputs[output].AudioOutFeedback.Number; - Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output); + Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name, inputNumber, output); if (AudioOutputFeedbacks.ContainsKey(output)) { @@ -1427,6 +1450,13 @@ namespace PepperDash.Essentials.DM { trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; } + + var videoStatus = inputPort as RoutingInputPortWithVideoStatuses; + + if (videoStatus != null) + { + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + } } private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) @@ -1467,6 +1497,13 @@ namespace PepperDash.Essentials.DM InputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]); trilist.UShortInput[join].UShortValue = InputStreamCardStateFeedbacks[ioSlot].UShortValue; + + var videoStatus = inputPort as RoutingInputPortWithVideoStatuses; + + if (videoStatus != null) + { + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + } } private void LinkStreamOutputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) @@ -1603,6 +1640,13 @@ namespace PepperDash.Essentials.DM { trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1; } + + var videoStatus = inputPort as RoutingInputPortWithVideoStatuses; + + if (videoStatus != null) + { + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + } } private void LinkAdvancedTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, @@ -1653,6 +1697,13 @@ namespace PepperDash.Essentials.DM trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort) transmitter.HdcpSupportCapability; + + var videoStatus = txRoutingInputs.InputPorts.Cast().FirstOrDefault((ip) => ip.Key == DmPortName.AnyVideoIn); + + if (videoStatus != null) + { + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + } } private void LinkTxOnlineFeedbackToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, @@ -1935,15 +1986,15 @@ namespace PepperDash.Essentials.DM { var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmChassisController. + (dc.Properties.ToString()); + return DmChassisController. GetDmChassisController(dc.Key, dc.Name, type, props); } else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x")) { var props = JsonConvert.DeserializeObject - (dc.Properties.ToString()); - return PepperDash.Essentials.DM.DmBladeChassisController. + (dc.Properties.ToString()); + return DmBladeChassisController. GetDmChassisController(dc.Key, dc.Name, type, props); } From db3d96d44828ec68f999d6867369c1ae2679aa89 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 8 Sep 2021 15:26:16 -0600 Subject: [PATCH 368/480] feat(Essentials_DM): Update DmInputEvent handler for input resolution feedback --- .../Essentials_DM/Chassis/DmChassisController.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 8cd53e33..7356cec3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1051,6 +1051,18 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks"); break; } + case DMInputEventIds.ResolutionEventId: + { + var inputPort = + InputPorts.Cast() + .FirstOrDefault((ip) => ip.Key.Contains(String.Format("inputCard{0}", args.Number))); + + if (inputPort != null) + { + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + } + break; + } default: { Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); From fa6cabe246387cf850d1b34a97191c2b396ee88f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 9 Sep 2021 07:44:05 -0600 Subject: [PATCH 369/480] refactor(Essentials_DM): Add event IDS and some logging to get resolution feedback --- .../Essentials_DM/Chassis/DmChassisController.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 7356cec3..de9a088a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1051,14 +1051,19 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks"); break; } + case DMInputEventIds.HorizontalResolutionFeedbackEventId: + case DMInputEventIds.VerticalResolutionFeedbackEventId: + case DMInputEventIds.FramesPerSecondFeedbackEventId: case DMInputEventIds.ResolutionEventId: { + Debug.Console(1, this, "Input {0} resolution updated", args.Number); var inputPort = InputPorts.Cast() .FirstOrDefault((ip) => ip.Key.Contains(String.Format("inputCard{0}", args.Number))); if (inputPort != null) { + Debug.Console(1, this, "Updating resolution feedback for input {0}", args.Number); inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); } break; From 871894e248105655665d45c79814b798711f7986 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 10 Sep 2021 20:25:21 -0600 Subject: [PATCH 370/480] fix: Fix issue with receiving sharing state In some circumstances, the sharing state can be retrieved prior to participants or meeting info being populated. In those cases, Essentials is now creating an empty meeting object if one doesn't exist, and populating host info with None if no host has been indicated yet. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 130 ++++++++++++------ 1 file changed, 89 insertions(+), 41 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a426193b..ead0a66f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using Crestron.SimplSharp; @@ -464,18 +465,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private void SetUpCallFeedbackActions() { - Status.Call.Sharing.PropertyChanged += (o, a) => - { - if (a.PropertyName == "State") - { - SharingContentIsOnFeedback.FireUpdate(); - ReceivingContent.FireUpdate(); - - // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); - MeetingInfo = meetingInfo; - } - }; + Status.Call.Sharing.PropertyChanged += HandleSharingStateUpdate; Status.Call.PropertyChanged += (o, a) => { @@ -487,6 +477,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom }; } + private void HandleSharingStateUpdate(object sender, PropertyChangedEventArgs a) + { + if (a.PropertyName != "State") + { + return; + } + + SharingContentIsOnFeedback.FireUpdate(); + ReceivingContent.FireUpdate(); + try + { + + // Update the share status of the meeting info + if (MeetingInfo == null) + { + var sharingStatus = GetSharingStatus(); + + MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true); + return; + } + + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host != null ? Participants.Host.Name : "None", + MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); + MeetingInfo = meetingInfo; + } + catch (Exception e) + { + Debug.Console(1, this, "Error processing state property update. {0}", e.Message); + Debug.Console(2, this, e.StackTrace); + MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false); + } + } + /// /// Subscribes to the PropertyChanged events on the state objects and fires the corresponding feedbacks. /// @@ -1614,7 +1637,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } catch (Exception ex) { - Debug.Console(1, this, "Error Deserializing feedback: {0}", ex); + Debug.Console(1, this, "Error Deserializing feedback: {0}", ex.Message); + Debug.Console(2, this, "{0}", ex); + + if (ex.InnerException != null) + { + Debug.Console(1, this,"Error Deserializing feedback inner exception: {0}", ex.InnerException.Message); + Debug.Console(2, this, "{0}", ex.InnerException.StackTrace); + } } } @@ -1822,24 +1852,33 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { string sharingState = "None"; - if (Status.Call.Sharing.State == zEvent.eSharingState.Receiving) + try { - sharingState = "Receiving Content"; - } - if (Status.Sharing.isAirHostClientConnected) - { - sharingState = "Sharing AirPlay"; - } - if (Status.Sharing.isDirectPresentationConnected) - { - sharingState = "Sharing Laptop"; - } - if (Status.Sharing.isSharingBlackMagic) - { - sharingState = "Sharing HDMI Source"; - } + if (Status.Call.Sharing.State == zEvent.eSharingState.Receiving) + { + sharingState = "Receiving Content"; + } + if (Status.Sharing.isAirHostClientConnected) + { + sharingState = "Sharing AirPlay"; + } + if (Status.Sharing.isDirectPresentationConnected) + { + sharingState = "Sharing Laptop"; + } + if (Status.Sharing.isSharingBlackMagic) + { + sharingState = "Sharing HDMI Source"; + } - return sharingState; + return sharingState; + } + catch (Exception e) + { + Debug.Console(1, this, "Exception getting sharing status: {0}", e.Message); + Debug.Console(2, this, "{0}", e.StackTrace); + return sharingState; + } } /// @@ -1848,21 +1887,30 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// private bool GetIsHostMyself() { - if (Participants.CurrentParticipants.Count == 0) + try { - Debug.Console(2, this, "No current participants"); + if (Participants.CurrentParticipants.Count == 0) + { + Debug.Console(2, this, "No current participants"); + return false; + } + + var host = Participants.Host; + + if(host == null) + { + Debug.Console(2, this, "Host is currently null"); + return false; + } + Debug.Console(2, this, "Host is: '{0}' IsMyself?: {1}", host.Name, host.IsMyself); + return host.IsMyself; + } + catch (Exception e) + { + Debug.Console(1, "Exception getting isHost: {0}", e.Message); + Debug.Console(2, "{0}", e.StackTrace); return false; } - - var host = Participants.Host; - - if(host == null) - { - Debug.Console(2, this, "Host is currently null"); - return false; - } - Debug.Console(2, this, "Host is: '{0}' IsMyself?: {1}", host.Name, host.IsMyself); - return host.IsMyself; } public override void StartSharing() From 0ae38dddfcb3938cb2d7c548f88469543e68c9a1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Sat, 11 Sep 2021 14:01:07 -0600 Subject: [PATCH 371/480] ci: Update scripts to remove Newtonsoft.Compact.json --- .github/scripts/ZipBuildOutput.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/ZipBuildOutput.ps1 b/.github/scripts/ZipBuildOutput.ps1 index bf3c9d94..dfc6480d 100644 --- a/.github/scripts/ZipBuildOutput.ps1 +++ b/.github/scripts/ZipBuildOutput.ps1 @@ -8,6 +8,7 @@ $destination = "$($Env:GITHUB_HOME)\output" New-Item -ItemType Directory -Force -Path ($destination) Get-ChildItem ($destination) $exclusions = @(git submodule foreach --quiet 'echo $name') +$exclusions += "Newtonsoft.Compact.Json.dll" # Trying to get any .json schema files (not currently working) # Gets any files with the listed extensions. Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.dll", "*.nuspec" | ForEach-Object { From 73e3b049d83d40018bec52dac1ea7b9d2a6225a7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 13 Sep 2021 08:33:36 -0600 Subject: [PATCH 372/480] build: Update nuspec file for maximum PD Core version --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec index e736dcbf..c2394428 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec @@ -14,7 +14,7 @@ crestron 3series 4series - + From 4ffea1c98fbe25c48353f544db74d04257d8631d Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 13 Sep 2021 08:43:24 -0600 Subject: [PATCH 373/480] fix: Add step to allow meeting number to be sent when entering password --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index ead0a66f..b53b871d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2209,6 +2209,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void Dial(Meeting meeting) { Debug.Console(1, this, "Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title); + _lastDialedMeetingNumber = meeting.Id; SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id)); } From fe01842523e2383f00911954d3e31553987e893e Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 16 Sep 2021 07:15:26 -0600 Subject: [PATCH 374/480] fix: Multiple fixes Update to poll meetings every 60 seconds Add property to allow for adjusting when Join button appears Refactor call connected event handler Adjust text for header for sharing-only meeting Add logic to handle waiting for host state --- .../Essentials/EssentialsHeaderDriver.cs | 43 +++-- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 158 ++++++++++-------- .../VC/EssentialsVideoCodecUiDriver.cs | 40 ++++- .../Codec/iHasScheduleAwareness.cs | 9 + .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 5 +- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 6 + .../VideoCodec/ZoomRoom/ZoomRoom.cs | 102 ++++++++--- .../ZoomRoom/ZoomRoomPropertiesConfig.cs | 2 + 8 files changed, 249 insertions(+), 116 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index f42b9de2..c63af9d5 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -195,22 +195,11 @@ namespace PepperDash.Essentials var meetingInfoCodec = codec as IHasMeetingInfo; // Set mode of header button - if (!codec.IsInCall) - { - HeaderCallButtonIconSig.StringValue = "DND"; - //HeaderCallButton.SetIcon(HeaderListButton.OnHook); - } - else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video)) - HeaderCallButtonIconSig.StringValue = "Misc-06_Dark"; - //HeaderCallButton.SetIcon(HeaderListButton.Camera); - //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2); - else - HeaderCallButtonIconSig.StringValue = "Misc-09_Dark"; - //HeaderCallButton.SetIcon(HeaderListButton.Phone); - //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1); + SetHeaderCallIcon(codec); // Set the call status text Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count); + if (codec.ActiveCalls.Count > 0) { if (codec.ActiveCalls.Count == 1 && meetingInfoCodec == null) @@ -218,8 +207,13 @@ namespace PepperDash.Essentials else if (codec.ActiveCalls.Count == 1 && meetingInfoCodec != null) { var headerCallStatusLabel = meetingInfoCodec.MeetingInfo.IsSharingMeeting - ? "Sharing Active" + ? "Sharing-Only Meeting" : "Active Meeting"; + + headerCallStatusLabel = meetingInfoCodec.MeetingInfo.WaitingForHost + ? "Waiting For Host" + : headerCallStatusLabel; + TriList.SetString(UIStringJoin.HeaderCallStatusLabel, headerCallStatusLabel); } else if (codec.ActiveCalls.Count > 1) @@ -229,6 +223,27 @@ namespace PepperDash.Essentials TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "No Active Calls"); } + private void SetHeaderCallIcon(VideoCodecBase codec) + { + if (!codec.IsInCall) + { + HeaderCallButtonIconSig.StringValue = "DND"; + //HeaderCallButton.SetIcon(HeaderListButton.OnHook); + } + else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video)) + { + HeaderCallButtonIconSig.StringValue = "Misc-06_Dark"; + } + //HeaderCallButton.SetIcon(HeaderListButton.Camera); + //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2); + else + { + HeaderCallButtonIconSig.StringValue = "Misc-09_Dark"; + } + //HeaderCallButton.SetIcon(HeaderListButton.Phone); + //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1); + } + /// /// Sets up Header Buttons for the EssentialsHuddleVtc1Room type /// diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 246573a9..67887078 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -471,85 +471,92 @@ namespace PepperDash.Essentials /// void ShowNextMeetingTimerCallback() { + //Update calendar for Zoom. Zoom doesn't automatically update when meetings are in the past + if (_isZoomRoomWithNoExternalSources) + { + CurrentRoom.ScheduleSource.GetSchedule(); + } + // Every 60 seconds, refresh the calendar RefreshMeetingsList(); // check meetings list for the closest, joinable meeting var ss = CurrentRoom.ScheduleSource; var meetings = ss.CodecSchedule.Meetings; - if (meetings.Count > 0) - { - // If the room is off pester the user - // If the room is on, and the meeting is joinable - // and the LastMeetingDismissed != this meeting + if (meetings.Count <= 0) + { + return; + } + // If the room is off pester the user + // If the room is on, and the meeting is joinable + // and the LastMeetingDismissed != this meeting - var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId); - Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", - CurrentRoom.OnFeedback.BoolValue, - LastMeetingDismissedId, - lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToString("t", Global.Culture) : ""); + var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId); + Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", + CurrentRoom.OnFeedback.BoolValue, + LastMeetingDismissedId, + lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToString("t", Global.Culture) : ""); - var meeting = meetings.LastOrDefault(m => m.Joinable); - if (CurrentRoom.OnFeedback.BoolValue - && lastMeetingDismissed == meeting) - { - // meeting no longer joinable, hide popup - if(meeting == null) - HideNextMeetingPopup(); + var meeting = meetings.LastOrDefault(m => m.Joinable); + if (CurrentRoom.OnFeedback.BoolValue + && lastMeetingDismissed == meeting) + { + // meeting no longer joinable, hide popup + if(meeting == null) + HideNextMeetingPopup(); - return; - } + return; + } - LastMeetingDismissedId = null; - // Clear the popup when we run out of meetings - if (meeting == null) - { - HideNextMeetingPopup(); - } - else - { + LastMeetingDismissedId = null; + // Clear the popup when we run out of meetings + if (meeting == null) + { + HideNextMeetingPopup(); + } + else + { - TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting"); - TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToString("t", Global.Culture)); - TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToString("t", Global.Culture)); - TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title); - TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer); - TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join"); - TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () => - { - HideNextMeetingPopup(); - PopupInterlock.Hide(); - RoomOnAndDialMeeting(meeting); - }); - TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule"); - TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () => - { - HideNextMeetingPopup(); - //CalendarPress(); - RefreshMeetingsList(); - PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible); - }); - var indexOfNext = meetings.IndexOf(meeting) + 1; + TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Upcoming meeting"); + TriList.SetString(UIStringJoin.NextMeetingStartTimeText, meeting.StartTime.ToString("t", Global.Culture)); + TriList.SetString(UIStringJoin.NextMeetingEndTimeText, meeting.EndTime.ToString("t", Global.Culture)); + TriList.SetString(UIStringJoin.NextMeetingTitleText, meeting.Title); + TriList.SetString(UIStringJoin.NextMeetingNameText, meeting.Organizer); + TriList.SetString(UIStringJoin.NextMeetingButtonLabel, "Join"); + TriList.SetSigFalseAction(UIBoolJoin.NextMeetingJoinPress, () => + { + HideNextMeetingPopup(); + PopupInterlock.Hide(); + RoomOnAndDialMeeting(meeting); + }); + TriList.SetString(UIStringJoin.NextMeetingSecondaryButtonLabel, "Show Schedule"); + TriList.SetSigFalseAction(UIBoolJoin.CalendarHeaderButtonPress, () => + { + HideNextMeetingPopup(); + //CalendarPress(); + RefreshMeetingsList(); + PopupInterlock.ShowInterlocked(UIBoolJoin.MeetingsOrContacMethodsListVisible); + }); + var indexOfNext = meetings.IndexOf(meeting) + 1; - // indexOf = 3, 4 meetings : - if (indexOfNext < meetings.Count) - TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, - meetings[indexOfNext].StartTime.ToString("t", Global.Culture)); - else - TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today"); + // indexOf = 3, 4 meetings : + if (indexOfNext < meetings.Count) + TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, + meetings[indexOfNext].StartTime.ToString("t", Global.Culture)); + else + TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today"); - TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () => - { - // Mark the meeting to not re-harass the user - if(CurrentRoom.OnFeedback.BoolValue) - LastMeetingDismissedId = meeting.Id; - HideNextMeetingPopup(); - }); + TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () => + { + // Mark the meeting to not re-harass the user + if(CurrentRoom.OnFeedback.BoolValue) + LastMeetingDismissedId = meeting.Id; + HideNextMeetingPopup(); + }); - TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true); - } - } + TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, true); + } } /// @@ -575,19 +582,26 @@ namespace PepperDash.Essentials /// void RoomOnAndDialMeeting(Meeting meeting) { + Debug.Console(1, "[RoomOnAndDialMeeting] Joining meeting [{0}]", meeting); Action dialAction = () => { var d = CurrentRoom.ScheduleSource as VideoCodecBase; if (d != null) { + Debug.Console(1, + "[RoomOnAndDialMeeting] [dialAction] Sending command to codec to join meeting {0}", meeting); d.Dial(meeting); LastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call } }; - if (CurrentRoom.OnFeedback.BoolValue) - dialAction(); + if (CurrentRoom.OnFeedback.BoolValue) + { + Debug.Console(1, "[RoomOnAndDialMeeting] Room is on."); + dialAction(); + } else - { + { + Debug.Console(1, "RoomOnAndDialMeeting] Room is off or warming. Registering for Warming Feedback"); // Rig a one-time handler to catch when the room is warmed and then dial call EventHandler oneTimeHandler = null; oneTimeHandler = (o, a) => @@ -1086,13 +1100,18 @@ namespace PepperDash.Essentials void meetingInfoCodec_MeetingInfoChanged(object sender, MeetingInfoEventArgs e) { + if (e.Info == null) + { + return; + } + TriList.SetString(UIStringJoin.MeetingIdText, e.Info.Id); TriList.SetString(UIStringJoin.MeetingHostText, e.Info.Host); TriList.SetString(UIStringJoin.MeetingNameText, e.Info.Name); TriList.SetString(UIStringJoin.MeetingPasswordText, e.Info.Password); // Show the password fields if one is present - TriList.SetBool(UIBoolJoin.MeetingPasswordVisible, string.IsNullOrEmpty(e.Info.Password) ? false : true); + TriList.SetBool(UIBoolJoin.MeetingPasswordVisible, !string.IsNullOrEmpty(e.Info.Password)); TriList.SetString(UIStringJoin.CallSharedSourceNameText, e.Info.ShareStatus); @@ -1302,9 +1321,8 @@ namespace PepperDash.Essentials { // See if this is helpful or if the callback response in the codec class maybe doesn't come it time? // Let's build list from event - // CurrentRoom.ScheduleSource.GetSchedule(); - TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Calendar"); + TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Calendar"); TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Today's Meetings"); ushort i = 0; diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index 9bbaad6f..cc5ac265 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -327,20 +327,14 @@ namespace PepperDash.Essentials.UIDrivers.VC { case eCodecCallStatus.Connected: // fire at SRL item - HidePasswordPrompt(); - KeypadMode = eKeypadMode.DTMF; - DialStringBuilder.Remove(0, DialStringBuilder.Length); - DialStringFeedback.FireUpdate(); - DialStringTextCheckEnables(); Parent.ShowNotificationRibbon("Connected", 2000); - StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); - ShowKeypad(); - ((Parent.CurrentRoom as IHasCurrentVolumeControls).CurrentVolumeControls as IBasicVolumeWithFeedback).MuteOff(); + OnCallConnected(); //VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible); break; case eCodecCallStatus.Connecting: // fire at SRL item Parent.ShowNotificationRibbon("Connecting", 0); + OnCallConnected(); break; case eCodecCallStatus.Dialing: Parent.ShowNotificationRibbon("Connecting", 0); @@ -417,6 +411,36 @@ namespace PepperDash.Essentials.UIDrivers.VC UpdateHeaderActiveCallList(); } + private void OnCallConnected() + { + HidePasswordPrompt(); + KeypadMode = eKeypadMode.DTMF; + DialStringBuilder.Remove(0, DialStringBuilder.Length); + DialStringFeedback.FireUpdate(); + DialStringTextCheckEnables(); + + StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); + ShowKeypad(); + + UnmuteRoomOnCallConnect(); + } + + private void UnmuteRoomOnCallConnect() + { + var volControl = Parent.CurrentRoom as IHasCurrentVolumeControls; + + if (volControl == null) + { + return; + } + var currentVolControls = volControl.CurrentVolumeControls as IBasicVolumeWithFeedback; + + if (currentVolControls != null) + { + currentVolControls.MuteOff(); + } + } + /// /// Redraws the calls list on the header /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs index 24f1968b..06edf7bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs @@ -235,6 +235,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec { Calls = new List(); } + + #region Overrides of Object + + public override string ToString() + { + return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime); + } + + #endregion } public class Call diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index cd9e2906..0720b319 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -38,8 +38,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public Boolean IsHost { get; private set; } [JsonProperty("isSharingMeeting")] public Boolean IsSharingMeeting { get; private set; } + [JsonProperty("waitingForHost")] + public Boolean WaitingForHost { get; private set; } - public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting) + public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost) { Id = id; Name = name; @@ -48,6 +50,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces ShareStatus = shareStatus; IsHost = isHost; IsSharingMeeting = isSharingMeeting; + WaitingForHost = waitingForHost; } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 35b6c3b2..e6efd063 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -59,6 +59,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public List AudioOuputs { get; set; } public List Cameras { get; set; } public zEvent.PhoneCallStatus PhoneCall { get; set; } + public zEvent.NeedWaitForHost NeedWaitForHost { get; set; } public ZoomRoomStatus() { @@ -76,6 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom AudioOuputs = new List(); Cameras = new List(); PhoneCall = new zEvent.PhoneCallStatus(); + NeedWaitForHost = new zEvent.NeedWaitForHost(); } } @@ -1475,6 +1477,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public static List GetGenericParticipantListFromParticipantsResult( List participants) { + if (participants.Count == 0) + { + return new List(); + } //return participants.Select(p => new Participant // { // UserId = p.UserId, diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index b53b871d..7096d894 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -112,6 +112,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom CodecSchedule = new CodecScheduleAwareness(MeetingRefreshTimer); + if (_props.MinutesBeforeMeetingStart > 0) + { + CodecSchedule.MeetingWarningMinutes = _props.MinutesBeforeMeetingStart; + } + ReceivingContent = new BoolFeedback(FarEndIsSharingContentFeedbackFunc); SelfviewPipPositionFeedback = new StringFeedback(SelfviewPipPositionFeedbackFunc); @@ -494,19 +499,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var sharingStatus = GetSharingStatus(); - MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true); + MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true, false); return; } var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host != null ? Participants.Host.Name : "None", - MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); + MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); MeetingInfo = meetingInfo; } catch (Exception e) { Debug.Console(1, this, "Error processing state property update. {0}", e.Message); Debug.Console(2, this, e.StackTrace); - MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false); + MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false, false); } } @@ -657,7 +662,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom return; } // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); MeetingInfo = meetingInfo; break; } @@ -1229,7 +1234,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants.CurrentParticipants = participants; // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself(), MeetingInfo.IsSharingMeeting); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); MeetingInfo = meetingInfo; PrintCurrentCallParticipants(); @@ -1424,15 +1429,40 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } case "needwaitforhost": { - var needWait = - JsonConvert.DeserializeObject(responseObj.ToString()); + Status.NeedWaitForHost = JsonConvert.DeserializeObject(responseObj.ToString()); - if (needWait.Wait) - { - // TODO: notify user to wait for host - } + Debug.Console(1, this, "NeedWaitForHost: {0}", Status.NeedWaitForHost.Wait); - break; + if (Status.NeedWaitForHost.Wait) + { + if (MeetingInfo == null) + { + MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", + GetSharingStatus(), false, false, true); + + UpdateCallStatus(); + break; + } + + MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", + GetSharingStatus(), false, false, true); + + UpdateCallStatus(); + + break; + } + + if (MeetingInfo == null) + { + MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", + GetSharingStatus(), false, false, false); + break; + } + + MeetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, + GetSharingStatus(), GetIsHostMyself(), false, false); + + break; } case "openvideofailforhoststop": { @@ -1514,7 +1544,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (result.Success) { - MeetingInfo = new MeetingInfo("", "", "", "", "", true, true); + MeetingInfo = new MeetingInfo("", "", "", "", "", true, true, MeetingInfo.WaitingForHost); break; } @@ -1704,8 +1734,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ///
private void UpdateCallStatus() { - Debug.Console(1, this, "[UpdateCallStatus] Current Call Status: {0}", - Status.Call != null ? Status.Call.Status.ToString() : "no call"); + Debug.Console(1, this, + "[UpdateCallStatus] Current Call Status: {0} Active Call Count: {1} Need Wait For Host: {2}", + Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count, Status.NeedWaitForHost.Wait); if (Status.Call != null) { @@ -1750,17 +1781,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Type = eCodecCallType.Video, }; + if (!String.IsNullOrEmpty(_lastDialedMeetingNumber)) + { + _lastDialedMeetingNumber = String.Empty; + } ActiveCalls.Add(newCall); - //Debug.Console(1, this, "[UpdateCallStatus] IF w/ meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", - //Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); - OnCallStatusChange(newCall); - } - else + } else if (String.IsNullOrEmpty(Status.Call.Info.meeting_id) && Status.NeedWaitForHost.Wait) { - //Debug.Console(1, this, "[UpdateCallStatus] IF w/o meeting_id AcitveCalls.Count == {1} - Current Call Status: {0}", - //Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + var newCall = new CodecActiveCallItem + { + Name = "Waiting For Host", + Number = "Waiting For Host", + Id = "Waiting For Host", + Status = newStatus, + Type = eCodecCallType.Video, + }; + + if (!String.IsNullOrEmpty(_lastDialedMeetingNumber)) + { + _lastDialedMeetingNumber = String.Empty; + } + + ActiveCalls.Add(newCall); + + OnCallStatusChange(newCall); } } } @@ -1771,15 +1817,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom switch (callStatus) { case zStatus.eCallStatus.IN_MEETING: + if (Status.NeedWaitForHost.Wait) + { + Status.NeedWaitForHost.Wait = false; + } existingCall.Status = eCodecCallStatus.Connected; break; case zStatus.eCallStatus.NOT_IN_MEETING: + if (Status.NeedWaitForHost.Wait) + { + Status.NeedWaitForHost.Wait = false; + } existingCall.Status = eCodecCallStatus.Disconnected; break; } Debug.Console(1, this, "[UpdateCallStatus] ELSE ActiveCalls.Count == {1} - Current Call Status: {0}", Status.Call != null ? Status.Call.Status.ToString() : "no call", ActiveCalls.Count); + OnCallStatusChange(existingCall); } @@ -1833,7 +1888,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Call.Info.meeting_password, GetSharingStatus(), GetIsHostMyself(), - !String.Equals(Status.Call.Info.meeting_type,"NORMAL") + !String.Equals(Status.Call.Info.meeting_type,"NORMAL"), + false ); } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomPropertiesConfig.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomPropertiesConfig.cs index 38238023..4c9b08c2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomPropertiesConfig.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomPropertiesConfig.cs @@ -25,5 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //This layout will be selected when a call is connected and no content is being shared public string DefaultCallLayout { get; set; } + + public int MinutesBeforeMeetingStart { get; set; } } } \ No newline at end of file From 9f3a3f64a82a11e4f818044cbc29c11fa3e24c63 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 16 Sep 2021 13:27:09 -0600 Subject: [PATCH 375/480] fix: Update share behavior for Zoom Room --- ...entialsHuddleVtc1PanelAvFunctionsDriver.cs | 22 +++++++++++++++++-- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 10 ++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index 67887078..26bdaee9 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -9,6 +9,7 @@ using Crestron.SimplSharpPro.UI; using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.PageManagers; using PepperDash.Essentials.Room.Config; @@ -730,16 +731,31 @@ namespace PepperDash.Essentials if (_isZoomRoomWithNoExternalSources) { - CurrentRoom.RunDefaultPresentRoute(); + if (!CurrentRoom.OnFeedback.BoolValue) + { + CurrentRoom.RunDefaultPresentRoute(); + } // For now, if this is a Zoom Room and there are no shareable sources just display the informational subpage TriList.SetBool(UIBoolJoin.ZoomRoomContentSharingVisible, true); var presentationMeetingCodec = CurrentRoom.VideoCodec as IHasPresentationOnlyMeeting; + var farEndContentStatusCodec = CurrentRoom.VideoCodec as IHasFarEndContentStatus; + var receivingContent = false; + + if (farEndContentStatusCodec != null) + { + receivingContent = farEndContentStatusCodec.ReceivingContent.BoolValue; + } if (presentationMeetingCodec != null && !CurrentRoom.VideoCodec.IsInCall) { presentationMeetingCodec.StartSharingOnlyMeeting(eSharingMeetingMode.Laptop); } + else if (CurrentRoom.VideoCodec.IsInCall && !CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && + !receivingContent) + { + CurrentRoom.VideoCodec.StartSharing(); + } if (CurrentSourcePageManager != null) CurrentSourcePageManager.Hide(); @@ -755,7 +771,9 @@ namespace PepperDash.Essentials } else // room is on show what's active or select a source if nothing is yet active { - if (CurrentRoom.CurrentSourceInfo == null || (CurrentRoom.VideoCodec != null && CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) + if (CurrentRoom.CurrentSourceInfo == null || + (CurrentRoom.VideoCodec != null && + CurrentRoom.CurrentSourceInfo.SourceDevice.Key == CurrentRoom.VideoCodec.OsdSource.Key)) TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); else if (CurrentSourcePageManager != null) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 7096d894..e4a724a2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -656,6 +656,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Debug.Console(2, this, "Updating sharing status: {0}", a.PropertyName); + SharingContentIsOnFeedback.FireUpdate(); if (MeetingInfo == null) { //Ignoring for now, as the CallInfo return will create the appropriate value @@ -1979,7 +1980,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ///
public override void StopSharing() { - SendText("zCommand Call Sharing Disconnect"); + if (Status.Sharing.isSharingBlackMagic) + { + SendText("zCommand Call Sharing HDMI Stop"); + } + else + { + SendText("zCommand Call Sharing Disconnect"); + } } public override void PrivacyModeOn() From f0942a39327159b088f93fdf98a587df23c064a2 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 17 Sep 2021 09:46:20 -0400 Subject: [PATCH 376/480] Fixes for DM endpoints on DMPS3 non-4k types --- PepperDashEssentials/ControlSystem.cs | 5 ++- .../Chassis/DmpsRoutingController.cs | 10 +++-- .../Endpoints/Receivers/DmRmcHelper.cs | 43 ++++++++++++++++--- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 0717bd80..04f9571c 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -343,7 +343,7 @@ namespace PepperDash.Essentials { var prompt = Global.ControlSystem.ControllerPrompt; - var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) && + var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) || String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase); if (!typeMatch) @@ -361,7 +361,8 @@ namespace PepperDash.Essentials if(propertiesConfig == null) propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig(); - var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig); + bool dmps4kType = this.ControllerPrompt.IndexOf("4k", StringComparison.OrdinalIgnoreCase) > -1; + var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig, dmps4kType); DeviceManager.AddDevice(dmpsRoutingController); } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 484293eb..5cdfee79 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -25,6 +25,9 @@ namespace PepperDash.Essentials.DM public CrestronControlSystem Dmps { get; set; } public ISystemControl SystemControl { get; private set; } + + //Check if DMPS is a DMPS3-4K type for endpoint creation + public bool Dmps4kType { get; private set; } //IroutingNumericEvent public event EventHandler NumericSwitchChange; @@ -73,7 +76,7 @@ namespace PepperDash.Essentials.DM public static DmpsRoutingController GetDmpsRoutingController(string key, string name, - DmpsRoutingPropertiesConfig properties) + DmpsRoutingPropertiesConfig properties, bool dmps4kType) { try { @@ -84,7 +87,7 @@ namespace PepperDash.Essentials.DM return null; } - var controller = new DmpsRoutingController(key, name, systemControl) + var controller = new DmpsRoutingController(key, name, systemControl, dmps4kType) { InputNames = properties.InputNames, OutputNames = properties.OutputNames @@ -110,12 +113,13 @@ namespace PepperDash.Essentials.DM /// /// /// - public DmpsRoutingController(string key, string name, ISystemControl systemControl) + public DmpsRoutingController(string key, string name, ISystemControl systemControl, bool dmps4kType) : base(key, name) { Dmps = Global.ControlSystem; SystemControl = systemControl; + Dmps4kType = dmps4kType; InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); 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 83c386bc..9043d514 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs @@ -329,7 +329,14 @@ namespace PepperDash.Essentials.DM var parentDev = DeviceManager.GetDeviceForKey(pKey); if (parentDev is DmpsRoutingController) { - return GetDmRmcControllerForDmps(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber); + if ((parentDev as DmpsRoutingController).Dmps4kType) + { + return GetDmRmcControllerForDmps4k(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber); + } + else + { + return GetDmRmcControllerForDmps(key, name, typeName, ipid, parentDev as DmpsRoutingController, props.ParentOutputNumber); + } } if (!(parentDev is IDmSwitch)) { @@ -395,25 +402,47 @@ namespace PepperDash.Essentials.DM return null; } - private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName, + private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName, + uint ipid, DmpsRoutingController controller, uint num) + { + Func dmpsHandler; + if (ChassisDict.TryGetValue(typeName.ToLower(), out dmpsHandler)) + { + var output = controller.Dmps.SwitcherOutputs[num] as DMOutput; + + if (output != null) + { + return dmpsHandler(key, name, ipid, output); + } + Debug.Console(0, Debug.ErrorLogLevel.Error, + "Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.", + typeName, num); + return null; + } + + Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num); + return null; + } + + private static CrestronGenericBaseDevice GetDmRmcControllerForDmps4k(string key, string name, string typeName, DmpsRoutingController controller, uint num) { - Func dmpsHandler; - if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmpsHandler)) + Func dmps4kHandler; + if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmps4kHandler)) { var output = controller.Dmps.SwitcherOutputs[num] as DMOutput; if (output != null) { - return dmpsHandler(key, name, output); + return dmps4kHandler(key, name, output); } Debug.Console(0, Debug.ErrorLogLevel.Error, - "Cannot attach DM-RMC of type '{0}' to output {1} on DMPS chassis. Output is not a DM Output.", + "Cannot attach DM-RMC of type '{0}' to output {1} on DMPS-4K chassis. Output is not a DM Output.", typeName, num); return null; } - Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS chassis", typeName, num); + Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS-4K chassis", typeName, num); return null; } From 9c22c4cb5f5c34605711c1049bc9c124c43ac86d Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 17 Sep 2021 09:47:06 -0400 Subject: [PATCH 377/480] Fixes adding a DM-TX to a DMPS system --- .../Endpoints/Transmitters/DmTxHelpers.cs | 207 +++++++++++------- 1 file changed, 122 insertions(+), 85 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs index 4d8e41f6..3ff14dba 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs @@ -65,99 +65,136 @@ namespace PepperDash.Essentials.DM { Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e); } + return null; } - else - { - var parentDev = DeviceManager.GetDeviceForKey(pKey); - if (!(parentDev is IDmSwitch)) - { - Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.", - key, pKey); - return null; - } + var parentDev = DeviceManager.GetDeviceForKey(pKey); + DMInput dmInput; + bool noIpId = false; + + if (parentDev is IDmSwitch) + { // Get the Crestron chassis and link stuff up - var switchDev = (parentDev as IDmSwitch); - var chassis = switchDev.Chassis; + var switchDev = (parentDev as IDmSwitch); + var chassis = switchDev.Chassis; - var num = props.ParentInputNumber; - if (num <= 0 || num > chassis.NumberOfInputs) - { - Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range", - key, num); - return null; - } - else + //Check that the input is within range of this chassis' possible inputs + var num = props.ParentInputNumber; + if (num <= 0 || num > chassis.NumberOfInputs) + { + Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range", + key, num); + return null; + } + + switchDev.TxDictionary.Add(num, key); + dmInput = chassis.Inputs[num]; + + //Determine if IpId is needed for this chassis type + if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 || + chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps || + chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps || + chassis is DmMd128x128 || chassis is DmMd64x64) { - var controller = (parentDev as IDmSwitch); - controller.TxDictionary.Add(num, key); + noIpId = true; } - // Catch constructor failures, mainly dues to IPID - try - { - // Must use different constructor for CPU3 chassis types. No IPID - if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 || - chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps || - chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps|| - chassis is DmMd128x128 || chassis is DmMd64x64) - { - if (typeName.StartsWith("dmtx200")) - return new DmTx200Controller(key, name, new DmTx200C2G(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx201c")) - return new DmTx201CController(key, name, new DmTx201C(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx201s")) - return new DmTx201SController(key, name, new DmTx201S(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k100")) - return new DmTx4k100Controller(key, name, new DmTx4K100C1G(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz100")) - return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k202")) - return new DmTx4k202CController(key, name, new DmTx4k202C(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz202")) - return new DmTx4kz202CController(key, name, new DmTx4kz202C(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k302")) - return new DmTx4k302CController(key, name, new DmTx4k302C(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz302")) - return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num])); - if (typeName.StartsWith("dmtx401")) - return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num])); - if (typeName.StartsWith("hdbasettx")) - return new HDBaseTTxController(key, name, new HDTx3CB(chassis.Inputs[num])); - } - else - { - if (typeName.StartsWith("dmtx200")) - return new DmTx200Controller(key, name, new DmTx200C2G(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx201c")) - return new DmTx201CController(key, name, new DmTx201C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx201s")) - return new DmTx201SController(key, name, new DmTx201S(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k100")) - return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz100")) - return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k202")) - return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz202")) - return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4k302")) - return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx4kz302")) - return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("dmtx401")) - return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num])); - if (typeName.StartsWith("hdbasettx")) - return new HDBaseTTxController(key, name, new HDTx3CB(ipid, chassis.Inputs[num])); - } - } - catch (Exception e) - { - Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e); - } + } + else if(parentDev is DmpsRoutingController) + { + // Get the DMPS chassis and link stuff up + var dmpsDev = (parentDev as DmpsRoutingController); + var chassis = dmpsDev.Dmps; + + //Check that the input is within range of this chassis' possible inputs + var num = props.ParentInputNumber; + if (num <= 0 || num > chassis.SwitcherInputs.Count) + { + Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is out of range", + key, num); + return null; + } + + dmpsDev.TxDictionary.Add(num, key); + noIpId = dmpsDev.Dmps4kType; + + try + { + dmInput = chassis.SwitcherInputs[num] as DMInput; + } + catch + { + Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num); + return null; + } + } + + else + { + Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey); + return null; } - - return null; + + try + { + // Must use different constructor for CPU3 or DMPS3-4K types. No IPID + if (noIpId) + { + if (typeName.StartsWith("dmtx200")) + return new DmTx200Controller(key, name, new DmTx200C2G(dmInput)); + if (typeName.StartsWith("dmtx201c")) + return new DmTx201CController(key, name, new DmTx201C(dmInput)); + if (typeName.StartsWith("dmtx201s")) + return new DmTx201SController(key, name, new DmTx201S(dmInput)); + if (typeName.StartsWith("dmtx4k100")) + return new DmTx4k100Controller(key, name, new DmTx4K100C1G(dmInput)); + if (typeName.StartsWith("dmtx4kz100")) + return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(dmInput)); + if (typeName.StartsWith("dmtx4k202")) + return new DmTx4k202CController(key, name, new DmTx4k202C(dmInput)); + if (typeName.StartsWith("dmtx4kz202")) + return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput)); + if (typeName.StartsWith("dmtx4k302")) + return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput)); + if (typeName.StartsWith("dmtx4kz302")) + return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput)); + if (typeName.StartsWith("dmtx401")) + return new DmTx401CController(key, name, new DmTx401C(dmInput)); + if (typeName.StartsWith("hdbasettx")) + return new HDBaseTTxController(key, name, new HDTx3CB(dmInput)); + } + else + { + if (typeName.StartsWith("dmtx200")) + return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput)); + if (typeName.StartsWith("dmtx201c")) + return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput)); + if (typeName.StartsWith("dmtx201s")) + return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput)); + if (typeName.StartsWith("dmtx4k100")) + return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, dmInput)); + if (typeName.StartsWith("dmtx4kz100")) + return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, dmInput)); + if (typeName.StartsWith("dmtx4k202")) + return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, dmInput)); + if (typeName.StartsWith("dmtx4kz202")) + return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput)); + if (typeName.StartsWith("dmtx4k302")) + return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput)); + if (typeName.StartsWith("dmtx4kz302")) + return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput)); + if (typeName.StartsWith("dmtx401")) + return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput)); + if (typeName.StartsWith("hdbasettx")) + return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput)); + } + } + catch (Exception e) + { + Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e); + } + + return null; } } From 3d543dfd0955be9e223b4a8c2d94c7b05da0006b Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 17 Sep 2021 15:05:59 -0400 Subject: [PATCH 378/480] Fixes odd error where dm event comes in with input xx name even though input xx doesn't exist on the dmps --- .../Chassis/DmpsRoutingController.cs | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 5cdfee79..ca1a9463 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -723,28 +723,36 @@ namespace PepperDash.Essentials.DM void Dmps_DMInputChange(Switch device, DMInputEventArgs args) { - //Debug.Console(2, this, "DMSwitch:{0} Input:{1} Event:{2}'", this.Name, args.Number, args.EventId.ToString()); - - switch (args.EventId) + try { - case (DMInputEventIds.OnlineFeedbackEventId): - { - Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); - InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); - break; - } - case (DMInputEventIds.VideoDetectedEventId): - { - Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); - VideoInputSyncFeedbacks[args.Number].FireUpdate(); - break; - } - case (DMInputEventIds.InputNameEventId): - { - Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); - InputNameFeedbacks[args.Number].FireUpdate(); - break; - } + switch (args.EventId) + { + case (DMInputEventIds.OnlineFeedbackEventId): + { + Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case (DMInputEventIds.VideoDetectedEventId): + { + Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); + VideoInputSyncFeedbacks[args.Number].FireUpdate(); + break; + } + case (DMInputEventIds.InputNameEventId): + { + Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); + if(InputNameFeedbacks.ContainsKey(args.Number)) + { + InputNameFeedbacks[args.Number].FireUpdate(); + } + break; + } + } + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "DMSwitch Input Change:{0} Input:{1} Event:{2}\rException: {3}", this.Name, args.Number, args.EventId.ToString(), e.ToString()); } } void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args) From 9f1c512909ff48279804dcd33f3bf63600281a46 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 29 Jul 2021 17:19:54 -0500 Subject: [PATCH 379/480] Updates to HdMdNxM4kEController.cs to implement regex pattern in place of substring on input definitions. Updated HdMdNxM4kEBridgeableController.cs to handle exception when constructing the device. --- .../Chassis/HdMdNxM4kEBridgeableController.cs | 860 +++++++++--------- .../Chassis/HdMdNxM4kEController.cs | 12 +- 2 files changed, 452 insertions(+), 420 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs index b766ac3c..3eece080 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using Newtonsoft.Json; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; @@ -15,421 +16,446 @@ using PepperDash.Essentials.Core.Config; namespace PepperDash.Essentials.DM.Chassis { - [Description("Wrapper class for all HdMdNxM4E switchers")] - public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback - { - private HdMdNxM _Chassis; - private HdMd4x14kE _Chassis4x1; - - //IroutingNumericEvent - public event EventHandler NumericSwitchChange; - - public Dictionary InputNames { get; set; } - public Dictionary OutputNames { get; set; } - - public RoutingPortCollection InputPorts { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } - - public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } - public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } - public FeedbackCollection InputNameFeedbacks { get; private set; } - public FeedbackCollection OutputNameFeedbacks { get; private set; } - public FeedbackCollection OutputRouteNameFeedbacks { get; private set; } - public FeedbackCollection InputHdcpEnableFeedback { get; private set; } - public FeedbackCollection DeviceNameFeedback { get; private set; } - public FeedbackCollection AutoRouteFeedback { get; private set; } - - #region Constructor - - public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis, - HdMdNxM4kEBridgeablePropertiesConfig props) - : base(key, name, chassis) - { - _Chassis = chassis; - var _props = props; - - InputNames = props.Inputs; - OutputNames = props.Outputs; - - VideoInputSyncFeedbacks = new FeedbackCollection(); - VideoOutputRouteFeedbacks = new FeedbackCollection(); - InputNameFeedbacks = new FeedbackCollection(); - OutputNameFeedbacks = new FeedbackCollection(); - OutputRouteNameFeedbacks = new FeedbackCollection(); - InputHdcpEnableFeedback = new FeedbackCollection(); - DeviceNameFeedback = new FeedbackCollection(); - AutoRouteFeedback = new FeedbackCollection(); - - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - - DeviceNameFeedback.Add(new StringFeedback(this.Name, () => this.Name)); - - if (_Chassis.NumberOfInputs == 1) - { - _Chassis4x1 = _Chassis as HdMd4x14kE; - AutoRouteFeedback.Add(new BoolFeedback(this.Name + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue)); - } - - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - var index = i; - var inputName = InputNames[index]; - _Chassis.Inputs[index].Name.StringValue = inputName; - - InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) - { - FeedbackMatchObject = _Chassis.HdmiInputs[index] - }); - VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue)); - InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue)); - InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); - } - - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - var index = i; - var outputName = OutputNames[index]; - _Chassis.Outputs[i].Name.StringValue = outputName; - - OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) - { - FeedbackMatchObject = _Chassis.HdmiOutputs[index] - }); - VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); - OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue)); - OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); - } - - _Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); - _Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); - - AddPostActivationAction(AddFeedbackCollections); - } - - #endregion - - #region Methods - - /// - /// Raise an event when the status of a switch object changes. - /// - /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType - private void OnSwitchChange(RoutingNumericEventArgs e) - { - var newEvent = NumericSwitchChange; - if (newEvent != null) newEvent(this, e); - } - - public void EnableHdcp(uint port) - { - if (port > _Chassis.NumberOfInputs) return; - if (port <= 0) return; - - _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } - - public void DisableHdcp(uint port) - { - if (port > _Chassis.NumberOfInputs) return; - if (port <= 0) return; - - _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff(); - InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); - } - - public void EnableAutoRoute() - { - if (_Chassis.NumberOfInputs != 1) return; - - if (_Chassis4x1 == null) return; - - _Chassis4x1.AutoModeOn(); - } - - public void DisableAutoRoute() - { - if (_Chassis.NumberOfInputs != 1) return; - - if (_Chassis4x1 == null) return; - - _Chassis4x1.AutoModeOff(); - } - - #region PostActivate - - public void AddFeedbackCollections() - { - AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); - AddCollectionsToList(VideoOutputRouteFeedbacks); - AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback); - } - - #endregion - - #region FeedbackCollection Methods - - //Add arrays of collections - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } - - public void AddCollectionsToList(params FeedbackCollection[] newFbs) - { - foreach (FeedbackCollection fbCollection in newFbs) - { - foreach (var item in newFbs) - { - AddCollectionToList(item); - } - } - } - - //Add Collections - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; - - AddFeedbackToList(f); - } - } - - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; - - AddFeedbackToList(f); - } - } - - public void AddCollectionToList(FeedbackCollection newFbs) - { - foreach (var f in newFbs) - { - if (f == null) continue; - - AddFeedbackToList(f); - } - } - - //Add Individual Feedbacks - public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb) - { - if (newFb == null) return; - - if (!Feedbacks.Contains(newFb)) - { - Feedbacks.Add(newFb); - } - } - - #endregion - - #region IRouting Members - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - // Try to make switch only when necessary. The unit appears to toggle when already selected. - var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut; - if (current != _Chassis.HdmiInputs[(uint)inputSelector]) - _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector]; - } - - #endregion - - #region IRoutingNumeric Members - - public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) - { - ExecuteSwitch(inputSelector, outputSelector, signalType); - } - - #endregion - - #endregion - - #region Bridge Linking - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); - - if (_Chassis4x1 != null) - { - trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn()); - trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff()); - AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); - } - - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - var joinIndex = i - 1; - //Digital - VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); - trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i)); - trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i)); - - //Serial - InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); - } - - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - var joinIndex = i - 1; - //Analog - VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); - trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo)); - - //Serial - OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); - OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); - } - - _Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange); - - trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => - { - if (args.DeviceOnLine) - { - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } - } - }); - } - - - #endregion - - #region Events - - void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) - { - if (!args.DeviceOnLine) return; - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - _Chassis.Inputs[i].Name.StringValue = InputNames[i]; - } - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - _Chassis.Outputs[i].Name.StringValue = OutputNames[i]; - } - - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } - } - - void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) - { - if (args.EventId != DMOutputEventIds.VideoOutEventId) return; - - for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) - { - var index = i; - var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback); - var localOutputPort = - OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]); - - - VideoOutputRouteFeedbacks[i].FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); - } - } - - void Chassis_DMInputChange(Switch device, DMInputEventArgs args) - { - if (args.EventId != DMInputEventIds.VideoDetectedEventId) return; - foreach (var item in VideoInputSyncFeedbacks) - { - item.FireUpdate(); - } - } - - #endregion - - #region Factory - - public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory - { - public HdMdNxM4kEControllerFactory() - { - TypeNames = new List() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" }; - } - - public override EssentialsDevice BuildDevice(DeviceConfig dc) - { - Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device"); - - var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); - - var type = dc.Type.ToLower(); - var control = props.Control; - var ipid = control.IpIdInt; - var address = control.TcpSshProperties.Address; - - switch (type) - { - case ("hdmd4x14ke-bridgeable"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props); - case ("hdmd4x24ke"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props); - case ("hdmd6x24ke"): - return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props); - default: - return null; - } - } - } - - #endregion - - - - } + [Description("Wrapper class for all HdMdNxM4E switchers")] + public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback + { + private HdMdNxM _Chassis; + private HdMd4x14kE _Chassis4x1; + + //IroutingNumericEvent + public event EventHandler NumericSwitchChange; + + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } + + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + public FeedbackCollection VideoInputSyncFeedbacks { get; private set; } + public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; } + public FeedbackCollection InputNameFeedbacks { get; private set; } + public FeedbackCollection OutputNameFeedbacks { get; private set; } + public FeedbackCollection OutputRouteNameFeedbacks { get; private set; } + public FeedbackCollection InputHdcpEnableFeedback { get; private set; } + public FeedbackCollection DeviceNameFeedback { get; private set; } + public FeedbackCollection AutoRouteFeedback { get; private set; } + + #region Constructor + + public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis, + HdMdNxM4kEBridgeablePropertiesConfig props) + : base(key, name, chassis) + { + _Chassis = chassis; + + if (props == null) + { + Debug.Console(1, this, "HdMdNx4keBridgeableController properties are null, failed to build the device"); + return; + } + + + if (props.Inputs != null) + { + foreach (var kvp in props.Inputs) + { + Debug.Console(0, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value); + } + InputNames = props.Inputs; + } + if (props.Outputs != null) + { + foreach (var kvp in props.Outputs) + { + Debug.Console(0, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value); + } + OutputNames = props.Outputs; + } + //else + //{ + // OutputNames.Add(1, "Output"); + //} + + VideoInputSyncFeedbacks = new FeedbackCollection(); + VideoOutputRouteFeedbacks = new FeedbackCollection(); + InputNameFeedbacks = new FeedbackCollection(); + OutputNameFeedbacks = new FeedbackCollection(); + OutputRouteNameFeedbacks = new FeedbackCollection(); + InputHdcpEnableFeedback = new FeedbackCollection(); + DeviceNameFeedback = new FeedbackCollection(); + AutoRouteFeedback = new FeedbackCollection(); + + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + + var deviceName = string.IsNullOrEmpty(this.Name) ? name : this.Name; + DeviceNameFeedback.Add(new StringFeedback(deviceName, () => deviceName)); + + if (_Chassis.NumberOfInputs == 1) + { + _Chassis4x1 = _Chassis as HdMd4x14kE; + AutoRouteFeedback.Add(new BoolFeedback(deviceName + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue)); + } + + for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) + { + var index = i; + var inputName = InputNames[index]; + _Chassis.Inputs[index].Name.StringValue = inputName; + + InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, index, this) + { + FeedbackMatchObject = _Chassis.HdmiInputs[index] + }); + VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue)); + InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue)); + InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); + } + + for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + { + var index = i; + var outputName = OutputNames[index]; + _Chassis.Outputs[i].Name.StringValue = outputName; + + OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, + eRoutingPortConnectionType.Hdmi, index, this) + { + FeedbackMatchObject = _Chassis.HdmiOutputs[index] + }); + VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); + OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue)); + OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); + } + + _Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); + _Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + + AddPostActivationAction(AddFeedbackCollections); + } + + #endregion + + #region Methods + + /// + /// Raise an event when the status of a switch object changes. + /// + /// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType + private void OnSwitchChange(RoutingNumericEventArgs e) + { + var newEvent = NumericSwitchChange; + if (newEvent != null) newEvent(this, e); + } + + public void EnableHdcp(uint port) + { + if (port > _Chassis.NumberOfInputs) return; + if (port <= 0) return; + + _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } + + public void DisableHdcp(uint port) + { + if (port > _Chassis.NumberOfInputs) return; + if (port <= 0) return; + + _Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff(); + InputHdcpEnableFeedback[InputNames[port]].FireUpdate(); + } + + public void EnableAutoRoute() + { + if (_Chassis.NumberOfInputs != 1) return; + + if (_Chassis4x1 == null) return; + + _Chassis4x1.AutoModeOn(); + } + + public void DisableAutoRoute() + { + if (_Chassis.NumberOfInputs != 1) return; + + if (_Chassis4x1 == null) return; + + _Chassis4x1.AutoModeOff(); + } + + #region PostActivate + + public void AddFeedbackCollections() + { + AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); + AddCollectionsToList(VideoOutputRouteFeedbacks); + AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback); + } + + #endregion + + #region FeedbackCollection Methods + + //Add arrays of collections + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } + + public void AddCollectionsToList(params FeedbackCollection[] newFbs) + { + foreach (FeedbackCollection fbCollection in newFbs) + { + foreach (var item in newFbs) + { + AddCollectionToList(item); + } + } + } + + //Add Collections + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; + + AddFeedbackToList(f); + } + } + + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; + + AddFeedbackToList(f); + } + } + + public void AddCollectionToList(FeedbackCollection newFbs) + { + foreach (var f in newFbs) + { + if (f == null) continue; + + AddFeedbackToList(f); + } + } + + //Add Individual Feedbacks + public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb) + { + if (newFb == null) return; + + if (!Feedbacks.Contains(newFb)) + { + Feedbacks.Add(newFb); + } + } + + #endregion + + #region IRouting Members + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + // Try to make switch only when necessary. The unit appears to toggle when already selected. + var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut; + if (current != _Chassis.HdmiInputs[(uint)inputSelector]) + _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector]; + } + + #endregion + + #region IRoutingNumeric Members + + public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) + { + ExecuteSwitch(inputSelector, outputSelector, signalType); + } + + #endregion + + #endregion + + #region Bridge Linking + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); + + if (_Chassis4x1 != null) + { + trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn()); + trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff()); + AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); + } + + for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) + { + var joinIndex = i - 1; + //Digital + VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); + trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i)); + trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i)); + + //Serial + InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); + } + + for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + { + var joinIndex = i - 1; + //Analog + VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); + trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo)); + + //Serial + OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); + OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); + } + + _Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange); + + trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => + { + if (args.DeviceOnLine) + { + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } + } + }); + } + + + #endregion + + #region Events + + void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) + { + if (!args.DeviceOnLine) return; + for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) + { + _Chassis.Inputs[i].Name.StringValue = InputNames[i]; + } + for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + { + _Chassis.Outputs[i].Name.StringValue = OutputNames[i]; + } + + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } + } + + void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) + { + if (args.EventId != DMOutputEventIds.VideoOutEventId) return; + + for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) + { + var index = i; + var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback); + var localOutputPort = + OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]); + + + VideoOutputRouteFeedbacks[i].FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); + } + } + + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { + if (args.EventId != DMInputEventIds.VideoDetectedEventId) return; + foreach (var item in VideoInputSyncFeedbacks) + { + item.FireUpdate(); + } + } + + #endregion + + #region Factory + + public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory + { + public HdMdNxM4kEControllerFactory() + { + TypeNames = new List() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device"); + + var props = JsonConvert.DeserializeObject(dc.Properties.ToString()); + + var type = dc.Type.ToLower(); + var control = props.Control; + var ipid = control.IpIdInt; + var address = control.TcpSshProperties.Address; + + switch (type) + { + case ("hdmd4x14ke-bridgeable"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props); + case ("hdmd4x24ke"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props); + case ("hdmd6x24ke"): + return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props); + default: + return null; + } + } + } + + #endregion + + + + } } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs index 57c52627..d19c9752 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DM; using Newtonsoft.Json; @@ -43,14 +44,19 @@ namespace PepperDash.Essentials.DM.Chassis OutputPorts = new RoutingPortCollection(); OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null, this)); - + // physical settings if (props != null && props.Inputs != null) { + var inputRegex = new Regex(@"(?\d)", RegexOptions.IgnoreCase); foreach (var kvp in props.Inputs) { - // strip "hdmiIn" - var inputNum = Convert.ToUInt32(kvp.Key.Substring(6)); + // get numnbers from key and convert to int + //var inputNum = Convert.ToUInt32(kvp.Key.Substring(6)); + var inputMatch = inputRegex.Match(kvp.Key); + if (inputMatch == null) continue; + + var inputNum = Convert.ToUInt32(inputMatch.Groups["InputNum"].Value); var port = chassis.HdmiInputs[inputNum].HdmiInputPort; // set hdcp disables From 30f63eee03b9f691ace3f699718f6a90877e3d46 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 30 Jul 2021 10:30:32 -0600 Subject: [PATCH 380/480] fix: Remove reference to DMOutput name sig the HD-MD series of switchers appears to not populate the Name sig of the DMOutput, leading to a NullSig exception when attempting to set output names. This is probably because those names can't be set on the device itself, but some experimentation with hardware may be required to determine that completely. --- .../Chassis/HdMdNxM4kEBridgeableController.cs | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs index 3eece080..270e3461 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs @@ -71,10 +71,6 @@ namespace PepperDash.Essentials.DM.Chassis } OutputNames = props.Outputs; } - //else - //{ - // OutputNames.Add(1, "Output"); - //} VideoInputSyncFeedbacks = new FeedbackCollection(); VideoOutputRouteFeedbacks = new FeedbackCollection(); @@ -117,7 +113,7 @@ namespace PepperDash.Essentials.DM.Chassis { var index = i; var outputName = OutputNames[index]; - _Chassis.Outputs[i].Name.StringValue = outputName; + //_Chassis.Outputs[i].Name.StringValue = outputName; OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, index, this) @@ -125,12 +121,12 @@ namespace PepperDash.Essentials.DM.Chassis FeedbackMatchObject = _Chassis.HdmiOutputs[index] }); VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); - OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue)); + OutputNameFeedbacks.Add(new StringFeedback(outputName, () => OutputNames[index])); OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); } - _Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); - _Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + _Chassis.DMInputChange += Chassis_DMInputChange; + _Chassis.DMOutputChange += Chassis_DMOutputChange; AddPostActivationAction(AddFeedbackCollections); } @@ -354,18 +350,18 @@ namespace PepperDash.Essentials.DM.Chassis OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); } - _Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange); + _Chassis.OnlineStatusChange += Chassis_OnlineStatusChange; - trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => + trilist.OnlineStatusChange += (d, args) => { - if (args.DeviceOnLine) - { - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } - } - }); + if (args.DeviceOnLine) + { + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } + } + }; } From 70d63a9f99c5eeb4164284a730b13fa03a61cad0 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 30 Jul 2021 10:44:26 -0600 Subject: [PATCH 381/480] chore: Mark non-bridgeable class obsolete Also add a debug message to give the new type to use. --- .../Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs index d19c9752..b47139e2 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEController.cs @@ -14,6 +14,7 @@ using PepperDash.Essentials.DM.Config; namespace PepperDash.Essentials.DM.Chassis { + [Obsolete("Please use HdMdNxM4kEBridgeable Controller")] public class HdMdNxM4kEController : CrestronGenericBaseDevice, IRoutingInputsOutputs, IRouting { public HdMdNxM Chassis { get; private set; } @@ -32,6 +33,7 @@ namespace PepperDash.Essentials.DM.Chassis HdMdNxM4kEPropertiesConfig props) : base(key, name, chassis) { + Debug.Console(0, this, "Type hdmd4x14ke is obsolete. Please use hdmd4x14ke-bridgeable"); Chassis = chassis; // logical ports From cad45c04cbfae8db2053291b3090fc9b7dd1784f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 20 Sep 2021 16:12:39 -0600 Subject: [PATCH 382/480] fix: Add method to register for the correct event for resolution feedback The resolution feedback change events don't appear to bubble up to the main DMInput change event. It appears to require subscribing to an event on the VideoAttributes class that the input contains. --- .../Chassis/DmChassisController.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index de9a088a..51990f07 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -8,6 +8,7 @@ using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM.Cards; using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpProInternal; using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -482,6 +483,29 @@ namespace PepperDash.Essentials.DM } + private void RegisterForInputResolutionFeedback(IVideoAttributesBasic input, uint number, RoutingInputPortWithVideoStatuses inputPort) + { + if (input == null) + { + return; + } + + input.VideoAttributes.AttributeChange += (sender, args) => + { + var inputAttributes = sender as IVideoAttributesBasic; + + if (inputAttributes == null) + { + return; + } + + Debug.Console(1, this, "Input {0} resolution updated", number); + + Debug.Console(1, this, "Updating resolution feedback for input {0}", number); + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + }; + } + /// /// /// @@ -883,6 +907,8 @@ namespace PepperDash.Essentials.DM { FeedbackMatchObject = Chassis.Inputs[cardNum] }; + + RegisterForInputResolutionFeedback(videoAttributesBasic, cardNum, inputPort as RoutingInputPortWithVideoStatuses); } else { From 2e76b6ba0ae81399458c407c3c45cc118785e0f7 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 21 Sep 2021 09:40:51 -0600 Subject: [PATCH 383/480] fix(DM): Fix issue with bad cast for IVideoAttributesBasic Also updates to use the DM routing input port rather than the tx AnyVideoInput for the DM input resolutions --- .../Chassis/DmChassisController.cs | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 51990f07..c74aea2b 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -490,15 +490,10 @@ namespace PepperDash.Essentials.DM return; } + Debug.Console(1, this, "Registering for resolution feedback for input {0} using Routing Port {1}", number, inputPort.Key); + input.VideoAttributes.AttributeChange += (sender, args) => { - var inputAttributes = sender as IVideoAttributesBasic; - - if (inputAttributes == null) - { - return; - } - Debug.Console(1, this, "Input {0} resolution updated", number); Debug.Console(1, this, "Updating resolution feedback for input {0}", number); @@ -898,9 +893,15 @@ namespace PepperDash.Essentials.DM if (videoAttributesBasic != null) { + Debug.Console(1, this, "card {0} supports IVideoAttributesBasic", cardNum); var statusFuncs = new VideoStatusFuncsWrapper { - VideoResolutionFeedbackFunc = () => videoAttributesBasic.VideoAttributes.GetVideoResolutionString() + VideoResolutionFeedbackFunc = () => + { + var resolution = videoAttributesBasic.VideoAttributes.GetVideoResolutionString(); + Debug.Console(1, this, "Updating resolution for input {0}. New resolution: {1}", cardNum, resolution); + return resolution; + } }; inputPort = new RoutingInputPortWithVideoStatuses(portKey, sigType, portType, Chassis.Inputs[cardNum], this, statusFuncs) @@ -1496,10 +1497,13 @@ namespace PepperDash.Essentials.DM var videoStatus = inputPort as RoutingInputPortWithVideoStatuses; - if (videoStatus != null) + if (videoStatus == null) { - videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + return; } + + Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key, joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin); + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); } private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin) @@ -1686,14 +1690,16 @@ namespace PepperDash.Essentials.DM var videoStatus = inputPort as RoutingInputPortWithVideoStatuses; - if (videoStatus != null) + if (videoStatus == null) { - videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + return; } + Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key, joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin); + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); } private void LinkAdvancedTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap, - uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) + uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter) { var transmitter = basicTransmitter as DmTxControllerBase; if (transmitter == null) return; @@ -1707,7 +1713,9 @@ namespace PepperDash.Essentials.DM if (txRoutingInputs == null) return; - var inputPorts = txRoutingInputs.InputPorts.Where((p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList(); + var inputPorts = + txRoutingInputs.InputPorts.Where( + (p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList(); if (inputPorts.Count == 0) { @@ -1741,12 +1749,18 @@ namespace PepperDash.Essentials.DM trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = (ushort) transmitter.HdcpSupportCapability; - var videoStatus = txRoutingInputs.InputPorts.Cast().FirstOrDefault((ip) => ip.Key == DmPortName.AnyVideoIn); - if (videoStatus != null) + var videoStatus = + InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)] as RoutingInputPortWithVideoStatuses; + + if (videoStatus == null) { - videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); + return; } + Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key, + joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin); + videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig( + trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]); } private void LinkTxOnlineFeedbackToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, From 49e82f107b26e132e25efcc875bdf90b86da12d6 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 21 Sep 2021 12:06:22 -0600 Subject: [PATCH 384/480] fix(Essentials_DM): Updates to try and fix some exceptions --- .../Chassis/HdMdNxM4kEBridgeableController.cs | 82 ++++++++++++++----- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs index 270e3461..1594bbdb 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs @@ -59,7 +59,7 @@ namespace PepperDash.Essentials.DM.Chassis { foreach (var kvp in props.Inputs) { - Debug.Console(0, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value); + Debug.Console(1, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value); } InputNames = props.Inputs; } @@ -67,7 +67,7 @@ namespace PepperDash.Essentials.DM.Chassis { foreach (var kvp in props.Outputs) { - Debug.Console(0, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value); + Debug.Console(1, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value); } OutputNames = props.Outputs; } @@ -100,7 +100,7 @@ namespace PepperDash.Essentials.DM.Chassis _Chassis.Inputs[index].Name.StringValue = inputName; InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) + eRoutingPortConnectionType.Hdmi, _Chassis.HdmiInputs[index], this) { FeedbackMatchObject = _Chassis.HdmiInputs[index] }); @@ -116,7 +116,7 @@ namespace PepperDash.Essentials.DM.Chassis //_Chassis.Outputs[i].Name.StringValue = outputName; OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, - eRoutingPortConnectionType.Hdmi, index, this) + eRoutingPortConnectionType.Hdmi, _Chassis.HdmiOutputs[index], this) { FeedbackMatchObject = _Chassis.HdmiOutputs[index] }); @@ -275,10 +275,19 @@ namespace PepperDash.Essentials.DM.Chassis public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { + var input = inputSelector as HdMdNxM4kzEHdmiInput; + var output = outputSelector as HdMdNxMHdmiOutput; + + if (output == null) + { + Debug.Console(0, this, "Unable to make switch. output selector is not HdMdNxMHdmiOutput"); + return; + } + // Try to make switch only when necessary. The unit appears to toggle when already selected. - var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut; - if (current != _Chassis.HdmiInputs[(uint)inputSelector]) - _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector]; + var current = output.VideoOut; + if (current != input) + output.VideoOut = input; } #endregion @@ -287,7 +296,9 @@ namespace PepperDash.Essentials.DM.Chassis public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) { - ExecuteSwitch(inputSelector, outputSelector, signalType); + var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector]; + var output = _Chassis.HdmiOutputs[outputSelector]; + ExecuteSwitch(input, output, signalType); } #endregion @@ -327,12 +338,13 @@ namespace PepperDash.Essentials.DM.Chassis for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) { var joinIndex = i - 1; + var input = i; //Digital VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); - trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i)); - trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i)); + trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(input)); + trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(input)); //Serial InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); @@ -341,9 +353,10 @@ namespace PepperDash.Essentials.DM.Chassis for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) { var joinIndex = i - 1; + var output = i; //Analog VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); - trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo)); + trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); //Serial OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); @@ -354,12 +367,19 @@ namespace PepperDash.Essentials.DM.Chassis trilist.OnlineStatusChange += (d, args) => { - if (args.DeviceOnLine) + if (!args.DeviceOnLine) { - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } + return; + } + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } + + foreach (var name in InputNames) + { + trilist.SetString(joinMap.InputName.JoinNumber + (name.Key - 1), + InputNameFeedbacks[(int) name.Key].StringValue); } }; } @@ -376,10 +396,11 @@ namespace PepperDash.Essentials.DM.Chassis { _Chassis.Inputs[i].Name.StringValue = InputNames[i]; } - for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) + + /*for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) { _Chassis.Outputs[i].Name.StringValue = OutputNames[i]; - } + }*/ foreach (var feedback in Feedbacks) { @@ -391,7 +412,28 @@ namespace PepperDash.Essentials.DM.Chassis { if (args.EventId != DMOutputEventIds.VideoOutEventId) return; - for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) + var output = args.Number; + + var inputNumber = _Chassis.HdmiOutputs[output].VideoOutFeedback == null + ? 0 + : _Chassis.HdmiOutputs[output].VideoOutFeedback.Number; + + var outputName = OutputNames[output]; + + var feedback = VideoOutputRouteFeedbacks[outputName]; + + if (feedback == null) + { + return; + } + var inPort = + InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output].VideoOutFeedback); + var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output]); + + feedback.FireUpdate(); + OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.AudioVideo)); + + /*for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) { var index = i; var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback); @@ -401,7 +443,7 @@ namespace PepperDash.Essentials.DM.Chassis VideoOutputRouteFeedbacks[i].FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); - } + }*/ } void Chassis_DMInputChange(Switch device, DMInputEventArgs args) From eec4484f7887f9e12e3c22da995ef63ee0fa577d Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 21 Sep 2021 16:11:13 -0500 Subject: [PATCH 385/480] fix: updates to resolve issues with routing and feedbacks in the HdMdNxM4kEBridgeableController class. --- .../Chassis/HdMdNxM4kEBridgeableController.cs | 151 +++++++++--------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs index 1594bbdb..3d41af3a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdMdNxM4kEBridgeableController.cs @@ -37,8 +37,8 @@ namespace PepperDash.Essentials.DM.Chassis public FeedbackCollection OutputNameFeedbacks { get; private set; } public FeedbackCollection OutputRouteNameFeedbacks { get; private set; } public FeedbackCollection InputHdcpEnableFeedback { get; private set; } - public FeedbackCollection DeviceNameFeedback { get; private set; } - public FeedbackCollection AutoRouteFeedback { get; private set; } + public StringFeedback DeviceNameFeedback { get; private set; } + public BoolFeedback AutoRouteFeedback { get; private set; } #region Constructor @@ -47,6 +47,7 @@ namespace PepperDash.Essentials.DM.Chassis : base(key, name, chassis) { _Chassis = chassis; + Name = name; if (props == null) { @@ -72,32 +73,30 @@ namespace PepperDash.Essentials.DM.Chassis OutputNames = props.Outputs; } + DeviceNameFeedback = new StringFeedback(()=>Name); + VideoInputSyncFeedbacks = new FeedbackCollection(); VideoOutputRouteFeedbacks = new FeedbackCollection(); InputNameFeedbacks = new FeedbackCollection(); OutputNameFeedbacks = new FeedbackCollection(); OutputRouteNameFeedbacks = new FeedbackCollection(); InputHdcpEnableFeedback = new FeedbackCollection(); - DeviceNameFeedback = new FeedbackCollection(); - AutoRouteFeedback = new FeedbackCollection(); - + InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); - var deviceName = string.IsNullOrEmpty(this.Name) ? name : this.Name; - DeviceNameFeedback.Add(new StringFeedback(deviceName, () => deviceName)); - if (_Chassis.NumberOfInputs == 1) { _Chassis4x1 = _Chassis as HdMd4x14kE; - AutoRouteFeedback.Add(new BoolFeedback(deviceName + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue)); + AutoRouteFeedback = new BoolFeedback(() => _Chassis4x1.AutoModeOnFeedback.BoolValue); } for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) { var index = i; var inputName = InputNames[index]; - _Chassis.Inputs[index].Name.StringValue = inputName; + //_Chassis.Inputs[index].Name.StringValue = inputName; + _Chassis.HdmiInputs[index].Name.StringValue = inputName; InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, _Chassis.HdmiInputs[index], this) @@ -105,7 +104,8 @@ namespace PepperDash.Essentials.DM.Chassis FeedbackMatchObject = _Chassis.HdmiInputs[index] }); VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue)); - InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue)); + //InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue)); + InputNameFeedbacks.Add(new StringFeedback(inputName, () => InputNames[index])); InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); } @@ -113,14 +113,15 @@ namespace PepperDash.Essentials.DM.Chassis { var index = i; var outputName = OutputNames[index]; - //_Chassis.Outputs[i].Name.StringValue = outputName; + //_Chassis.Outputs[index].Name.StringValue = outputName; + //_Chassis.HdmiOutputs[index].Name.StringValue = outputName; OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, _Chassis.HdmiOutputs[index], this) { FeedbackMatchObject = _Chassis.HdmiOutputs[index] }); - VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); + VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number)); OutputNameFeedbacks.Add(new StringFeedback(outputName, () => OutputNames[index])); OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue)); } @@ -185,9 +186,10 @@ namespace PepperDash.Essentials.DM.Chassis public void AddFeedbackCollections() { + AddFeedbackToList(DeviceNameFeedback); AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback); AddCollectionsToList(VideoOutputRouteFeedbacks); - AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback); + AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks); } #endregion @@ -274,9 +276,10 @@ namespace PepperDash.Essentials.DM.Chassis #region IRouting Members public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - var input = inputSelector as HdMdNxM4kzEHdmiInput; + { + var input = inputSelector as HdMdNxMHdmiInput; //changed from HdMdNxM4kzEHdmiInput; var output = outputSelector as HdMdNxMHdmiOutput; + Debug.Console(2, this, "ExecuteSwitch: input={0} output={1}", input, output); if (output == null) { @@ -286,8 +289,8 @@ namespace PepperDash.Essentials.DM.Chassis // Try to make switch only when necessary. The unit appears to toggle when already selected. var current = output.VideoOut; - if (current != input) - output.VideoOut = input; + if (current != input) + output.VideoOut = input; } #endregion @@ -296,8 +299,11 @@ namespace PepperDash.Essentials.DM.Chassis public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType) { - var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector]; + var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector]; var output = _Chassis.HdmiOutputs[outputSelector]; + + Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output); + ExecuteSwitch(input, output, signalType); } @@ -326,13 +332,13 @@ namespace PepperDash.Essentials.DM.Chassis } IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); + DeviceNameFeedback.LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]); if (_Chassis4x1 != null) { trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn()); trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff()); - AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); + AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]); } for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) @@ -340,14 +346,14 @@ namespace PepperDash.Essentials.DM.Chassis var joinIndex = i - 1; var input = i; //Digital - VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); - InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); + VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]); + InputHdcpEnableFeedback[InputNames[input]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]); trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(input)); trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(input)); - //Serial - InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); + //Serial + InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]); } for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) @@ -355,32 +361,22 @@ namespace PepperDash.Essentials.DM.Chassis var joinIndex = i - 1; var output = i; //Analog - VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); + VideoOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]); trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo)); //Serial - OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); - OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); + OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]); + OutputRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]); } _Chassis.OnlineStatusChange += Chassis_OnlineStatusChange; trilist.OnlineStatusChange += (d, args) => { - if (!args.DeviceOnLine) - { - return; - } - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } + if (!args.DeviceOnLine) return; - foreach (var name in InputNames) - { - trilist.SetString(joinMap.InputName.JoinNumber + (name.Key - 1), - InputNameFeedbacks[(int) name.Key].StringValue); - } + // feedback updates was moved to the Chassis_OnlineStatusChange + // due to the amount of time it takes for the device to come online }; } @@ -391,21 +387,17 @@ namespace PepperDash.Essentials.DM.Chassis void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) { - if (!args.DeviceOnLine) return; - for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) - { - _Chassis.Inputs[i].Name.StringValue = InputNames[i]; - } + IsOnline.FireUpdate(); - /*for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) - { - _Chassis.Outputs[i].Name.StringValue = OutputNames[i]; - }*/ + if (!args.DeviceOnLine) return; + + foreach (var feedback in Feedbacks) + { + feedback.FireUpdate(); + } - foreach (var feedback in Feedbacks) - { - feedback.FireUpdate(); - } + if (_Chassis4x1 != null) + AutoRouteFeedback.FireUpdate(); } void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) @@ -432,27 +424,40 @@ namespace PepperDash.Essentials.DM.Chassis feedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.AudioVideo)); - - /*for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++) - { - var index = i; - var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback); - var localOutputPort = - OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]); - - - VideoOutputRouteFeedbacks[i].FireUpdate(); - OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo)); - }*/ } void Chassis_DMInputChange(Switch device, DMInputEventArgs args) - { - if (args.EventId != DMInputEventIds.VideoDetectedEventId) return; - foreach (var item in VideoInputSyncFeedbacks) - { - item.FireUpdate(); - } + { + switch (args.EventId) + { + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", args.EventId); + foreach (var item in VideoInputSyncFeedbacks) + { + item.FireUpdate(); + } + break; + } + case DMInputEventIds.InputNameFeedbackEventId: + case DMInputEventIds.InputNameEventId: + case DMInputEventIds.NameFeedbackEventId: + { + Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId); + Debug.Console(1, this, "Input {0} Name {1}", args.Number, + _Chassis.HdmiInputs[args.Number].NameFeedback.StringValue); + foreach (var item in InputNameFeedbacks) + { + item.FireUpdate(); + } + break; + } + default: + { + Debug.Console(1, this, "Unhandled DM Input Event ID {0}", args.EventId); + break; + } + } } #endregion From 8d1f1876437079d04900a884c7ce893d752ed926 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 21 Sep 2021 17:59:12 -0600 Subject: [PATCH 386/480] feat(essentials): #830 Adds new Cisco features Adds IHasDoNotDisturbMode, IHasStandbyMode and IHasHalfWakeMode interfaces. Implements all interfaces on CiscoSparkCodec class. Adds CiscoCodecJoinMap to allow for bridging new Cisco specific functions. --- .../Codec/IHasDoNotDisturb.cs | 45 +++++++ .../Essentials Devices Common.csproj | 3 + .../CiscoCodec/CiscoCodecJoinMap.cs | 120 ++++++++++++++++++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 96 +++++++++++++- .../VideoCodec/CiscoCodec/xStatus.cs | 26 +++- .../VideoCodec/Interfaces/IHasStandbyMode.cs | 32 +++++ .../VideoCodec/VideoCodecBase.cs | 2 +- 7 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs new file mode 100644 index 00000000..7bb9b924 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Describes a device that has Do Not Disturb mode capability + /// + public interface IHasDoNotDisturbMode + { + /// + /// Indictes whether Do Not Disturb mode is on (Activated) + /// + BoolFeedback DoNotDisturbModeIsOnFeedback { get; } + + /// + /// Activates Do Not Disturb mode + /// + void ActivateDoNotDisturbMode(); + + /// + /// Deactivates Do Not Disturb mode + /// + void DeactivateDoNotDisturbMode(); + + /// + /// Toggles Do Not Disturb mode + /// + void ToggleDoNotDisturbMode(); + } + + public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode + { + /// + /// Activates Do Not Disturb mode with a timeout + /// + /// + void ActivateDoNotDisturbMode(int timeout); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index fc5f68d4..1fcffff2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -108,6 +108,7 @@ + @@ -117,6 +118,7 @@ + @@ -125,6 +127,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs new file mode 100644 index 00000000..8caeaf3e --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs @@ -0,0 +1,120 @@ +using System; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges.JoinMaps; + + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco +{ + public class CiscoCodecJoinMap : VideoCodecControllerJoinMap + { + #region Digital + + [JoinName("ActivateDoNotDisturbMode")] + public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 221, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Do Not Disturb Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DeactivateDoNotDisturbMode")] + public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 222, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Deactivates Do Not Disturb Mode. FB High if deactivated.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ToggleDoNotDisturbMode")] + public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 223, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Toggles Do Not Disturb Mode.", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ActivateStandby")] + public JoinDataComplete ActivateStandby = new JoinDataComplete( + new JoinData + { + JoinNumber = 226, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Standby Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DeactivateStandby")] + public JoinDataComplete DeactivateStandby = new JoinDataComplete( + new JoinData + { + JoinNumber = 227, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Deactivates Standby Mode. FB High if deactivated.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ActivateHalfWakeMode")] + public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 228, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Half Wake Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + + #region Analog + + + #endregion + + + #region Serials + + + #endregion + + public CiscoCodecJoinMap(uint joinStart) + : base(joinStart, typeof(CiscoCodecJoinMap)) + { + } + + public CiscoCodecJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index f894141c..904482b0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -28,7 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, - ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute + ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, + IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute, IHasDoNotDisturbMode, + IHasHalfWakeMode { private bool _externalSourceChangeRequested; @@ -316,6 +318,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CameraIsMutedFeedback = CameraIsOffFeedback; SupportsCameraOff = true; + DoNotDisturbModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Conference.DoNotDisturb.BoolValue); + HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value == "Halfwake"); + PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); Communication = comm; @@ -413,7 +418,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; - CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate; + CodecStatus.Status.Standby.State.ValueChangedAction = new Action(() => + { + StandbyIsOnFeedback.FireUpdate(); + HalfWakeModeIsOnFeedback.FireUpdate(); + }); CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate; @@ -423,6 +432,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; + CodecStatus.Status.Conference.DoNotDisturb.ValueChangedAction = DoNotDisturbModeIsOnFeedback.FireUpdate; + try { CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; @@ -1495,7 +1506,49 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { + var joinMap = new CiscoCodecJoinMap(joinStart); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge); + + LinkCiscoCodecToApi(trilist, joinMap); + } + + public void LinkCiscoCodecToApi(BasicTriList trilist, CiscoCodecJoinMap joinMap) + { + var dndCodec = this as IHasDoNotDisturbMode; + if (dndCodec != null) + { + dndCodec.DoNotDisturbModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateDoNotDisturbMode.JoinNumber]); + dndCodec.DoNotDisturbModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateDoNotDisturbMode.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.ActivateDoNotDisturbMode.JoinNumber, () => dndCodec.ActivateDoNotDisturbMode()); + trilist.SetSigFalseAction(joinMap.DeactivateDoNotDisturbMode.JoinNumber, () => dndCodec.DeactivateDoNotDisturbMode()); + trilist.SetSigFalseAction(joinMap.ToggleDoNotDisturbMode.JoinNumber, () => dndCodec.ToggleDoNotDisturbMode()); + } + + var halfwakeCodec = this as IHasHalfWakeMode; + if (halfwakeCodec != null) + { + halfwakeCodec.StandbyIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateStandby.JoinNumber]); + halfwakeCodec.StandbyIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateStandby.JoinNumber]); + halfwakeCodec.HalfWakeModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateHalfWakeMode.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.ActivateStandby.JoinNumber, () => halfwakeCodec.StandbyActivate()); + trilist.SetSigFalseAction(joinMap.DeactivateStandby.JoinNumber, () => halfwakeCodec.StandbyDeactivate()); + trilist.SetSigFalseAction(joinMap.ActivateHalfWakeMode.JoinNumber, () => halfwakeCodec.HalfwakeActivate()); + } } /// @@ -2069,6 +2122,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco else CameraMuteOn(); } + + #region IHasDoNotDisturbMode Members + + public BoolFeedback DoNotDisturbModeIsOnFeedback { get; private set; } + + public void ActivateDoNotDisturbMode() + { + SendText("xCommand Conference DoNotDisturb Activate"); + } + + public void DeactivateDoNotDisturbMode() + { + SendText("xCommand Conference DoNotDisturb Deactivate"); + } + + public void ToggleDoNotDisturbMode() + { + if (DoNotDisturbModeIsOnFeedback.BoolValue) + { + DeactivateDoNotDisturbMode(); + } + else + { + ActivateDoNotDisturbMode(); + } + } + + #endregion + + #region IHasHalfWakeMode Members + + public BoolFeedback HalfWakeModeIsOnFeedback { get; private set; } + + public void HalfwakeActivate() + { + SendText("xCommand Standby Halfwake"); + } + + #endregion } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index c1cd92cf..a32ff5bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -440,9 +440,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public CallId CallId { get; set; } } - public class DoNotDisturb + public class DoNotDisturb : ValueProperty { - public string Value { get; set; } + string _Value; + + public bool BoolValue { get; private set; } + + public string Value + { + get + { + return _Value; + } + set + { + _Value = value; + // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false + BoolValue = value == "On" || value == "Active"; + OnValueChanged(); + } + } } public class Mode @@ -600,6 +617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Conference2() { Presentation = new Presentation(); + DoNotDisturb = new DoNotDisturb(); } } @@ -1380,12 +1398,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public class State : ValueProperty { + string _value; + public bool BoolValue { get; private set; } public string Value // Valid values are Standby/EnteringStandby/Halfwake/Off { + get { return _value; } set { + _value = value; // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false BoolValue = value == "On" || value == "Standby"; OnValueChanged(); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs new file mode 100644 index 00000000..55dcd081 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + /// + /// Describes a device that has Standby Mode capability + /// + public interface IHasStandbyMode + { + BoolFeedback StandbyIsOnFeedback { get; } + + void StandbyActivate(); + + void StandbyDeactivate(); + } + + /// + /// Describes a device that has Half Waek Mode capability + /// + public interface IHasHalfWakeMode : IHasStandbyMode + { + BoolFeedback HalfWakeModeIsOnFeedback { get; } + + void HalfwakeActivate(); + } +} \ No newline at end of file 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 d34c9e3b..26ed54bb 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 @@ -25,7 +25,7 @@ using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Devices.Common.VideoCodec { public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, - IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced + IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode { private const int XSigEncoding = 28591; protected const int MaxParticipants = 50; From 16db2663a6f82c60f119248c62eb6ff36c966119 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 22 Sep 2021 11:56:06 -0600 Subject: [PATCH 387/480] feat(essentials): #835 comments out some debug messages to clean up console at startup --- .../PepperDashEssentialsBase/Devices/EssentialsDevice.cs | 6 +++--- .../PepperDashEssentialsBase/Factory/DeviceFactory.cs | 4 ++-- .../PepperDashEssentialsBase/Plugins/PluginLoader.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 46fa819b..a72bd282 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -57,7 +57,7 @@ namespace PepperDash.Essentials.Core public DescriptionAttribute(string description) { - Debug.Console(2, "Setting Description: {0}", description); + //Debug.Console(2, "Setting Description: {0}", description); _Description = description; } @@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core public ConfigSnippetAttribute(string configSnippet) { - Debug.Console(2, "Setting Config Snippet {0}", configSnippet); + //Debug.Console(2, "Setting Config Snippet {0}", configSnippet); _ConfigSnippet = configSnippet; } @@ -103,7 +103,7 @@ namespace PepperDash.Essentials.Core { foreach (var typeName in TypeNames) { - Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); + //Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName); var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[]; string description = descriptionAttribute[0].Description; var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[]; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index a17e0d91..ebdc87b1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -69,13 +69,13 @@ namespace PepperDash.Essentials.Core /// public static void AddFactoryForType(string typeName, Func method) { - Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + //Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method}); } public static void AddFactoryForType(string typeName, string description, CType cType, Func method) { - Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); + //Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName); if(FactoryMethods.ContainsKey(typeName)) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs index 7437d75a..136303e3 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs @@ -123,7 +123,7 @@ namespace PepperDash.Essentials /// static LoadedAssembly LoadAssembly(string filePath) { - Debug.Console(2, "Attempting to load {0}", filePath); + //Debug.Console(2, "Attempting to load {0}", filePath); var assembly = Assembly.LoadFrom(filePath); if (assembly != null) { From a165ba911f87356c9cec67d217cfc05c8b87b26c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 22 Sep 2021 15:31:13 -0600 Subject: [PATCH 388/480] feat(essentials): Minor updates after testing against codec hardware --- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 6 ++++-- .../VideoCodec/CiscoCodec/xStatus.cs | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 904482b0..d625637c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -586,6 +586,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Status/Audio" + Delimiter + prefix + "/Status/Call" + Delimiter + prefix + "/Status/Conference/Presentation" + Delimiter + + prefix + "/Status/Conference/DoNotDisturb" + Delimiter + prefix + "/Status/Cameras/SpeakerTrack" + Delimiter + prefix + "/Status/RoomAnalytics" + Delimiter + prefix + "/Status/RoomPreset" + Delimiter + @@ -594,10 +595,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Status/Video/Layout" + Delimiter + prefix + "/Status/Video/Input/MainVideoMute" + Delimiter + prefix + "/Bookings" + Delimiter + - prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/Bookings" + Delimiter + prefix + "/Event/CameraPresetListUpdated" + Delimiter + - prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; + prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter + + prefix + "/Event/CallDisconnect" + Delimiter; // Keep CallDisconnect last to detect when feedback registration completes correctly + } #endregion diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index a32ff5bf..29b9f260 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -2113,6 +2113,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco Conference = new Conference2(); SystemUnit = new SystemUnit(); Video = new Video(); + Conference = new Conference2(); } } From bead782bd5a78d2bf2959e89a027c1d1f9af2c8b Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 23 Sep 2021 12:01:15 -0400 Subject: [PATCH 389/480] Waits to return InitializeSystem until devices are registered. Adds DMPS system power on/off to device bridge. --- PepperDashEssentials/ControlSystem.cs | 12 +- .../JoinMaps/DmpsRoutingControllerJoinMap.cs | 18 ++- .../Devices/DeviceManager.cs | 3 + .../Chassis/DmpsRoutingController.cs | 110 ++++++++++++++++-- 4 files changed, 124 insertions(+), 19 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 04f9571c..f3674b41 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -46,6 +46,13 @@ namespace PepperDash.Essentials public override void InitializeSystem() { _startTimer = new CTimer(StartSystem,StartupTime); + ushort count = 0; + while (!DeviceManager.AllDevicesActivatedFb && count < 60) + { + //Wait for devices to register before returning, as required by DMPS. Max wait is 60 seconds. + CrestronEnvironment.Sleep(1000); + count++; + } } private void StartSystem(object obj) @@ -361,10 +368,7 @@ namespace PepperDash.Essentials if(propertiesConfig == null) propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig(); - bool dmps4kType = this.ControllerPrompt.IndexOf("4k", StringComparison.OrdinalIgnoreCase) > -1; - var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig, dmps4kType); - - DeviceManager.AddDevice(dmpsRoutingController); + DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig)); } else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs index 11385916..80975338 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -1,9 +1,17 @@ using System; -namespace PepperDash.Essentials.Core.Bridges -{ - public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced - { +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced + { + [JoinName("SystemPowerOn")] + public JoinDataComplete SystemPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata { Description = "DMPS System Power On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("SystemPowerOff")] + public JoinDataComplete SystemPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, + new JoinMetadata { Description = "DMPS System Power Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("VideoSyncStatus")] public JoinDataComplete VideoSyncStatus = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 }, new JoinMetadata { Description = "DM Input Video Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); @@ -61,5 +69,5 @@ namespace PepperDash.Essentials.Core.Bridges protected DmpsRoutingControllerJoinMap(uint joinStart, Type type) : base(joinStart, type) { } - } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index df864550..c5363a00 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -28,9 +28,11 @@ namespace PepperDash.Essentials.Core public static List AllDevices { get { return new List(Devices.Values); } } public static bool AddDeviceEnabled; + public static bool AllDevicesActivatedFb; public static void Initialize(CrestronControlSystem cs) { + AllDevicesActivatedFb = false; AddDeviceEnabled = true; CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices", ConsoleAccessLevelEnum.AccessOperator); @@ -122,6 +124,7 @@ namespace PepperDash.Essentials.Core private static void OnAllDevicesActivated() { + AllDevicesActivatedFb = true; var handler = AllDevicesActivated; if (handler != null) { diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index ca1a9463..9a8742a4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -31,6 +31,10 @@ namespace PepperDash.Essentials.DM //IroutingNumericEvent public event EventHandler NumericSwitchChange; + + //Feedback for DMPS System Power + public BoolFeedback SystemPowerOnFeedback { get; private set; } + public BoolFeedback SystemPowerOffFeedback { get; private set; } // Feedbacks for EssentialDM public Dictionary VideoOutputFeedbacks { get; private set; } @@ -76,7 +80,7 @@ namespace PepperDash.Essentials.DM public static DmpsRoutingController GetDmpsRoutingController(string key, string name, - DmpsRoutingPropertiesConfig properties, bool dmps4kType) + DmpsRoutingPropertiesConfig properties) { try { @@ -87,7 +91,7 @@ namespace PepperDash.Essentials.DM return null; } - var controller = new DmpsRoutingController(key, name, systemControl, dmps4kType) + var controller = new DmpsRoutingController(key, name, systemControl) { InputNames = properties.InputNames, OutputNames = properties.OutputNames @@ -113,13 +117,31 @@ namespace PepperDash.Essentials.DM /// /// /// - public DmpsRoutingController(string key, string name, ISystemControl systemControl, bool dmps4kType) + public DmpsRoutingController(string key, string name, ISystemControl systemControl) : base(key, name) - { - + { Dmps = Global.ControlSystem; - SystemControl = systemControl; - Dmps4kType = dmps4kType; + + switch (name.Replace("-", "").Replace("c", "").Replace("C", "")) + { + case "dmps34k50": + case "dmps34k100": + case "dmps34k150": + SystemControl = systemControl as Dmps34K150CSystemControl; + Dmps4kType = true; + break; + case "dmps34k200": + case "dmps34k250": + case "dmps34k300": + case "dmps34k350": + SystemControl = systemControl as Dmps34K300CSystemControl; + Dmps4kType = true; + break; + default: + SystemControl = systemControl as Dmps3SystemControl; + Dmps4kType = false; + break; + } InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); @@ -127,6 +149,29 @@ namespace PepperDash.Essentials.DM TxDictionary = new Dictionary(); RxDictionary = new Dictionary(); + SystemPowerOnFeedback = new BoolFeedback(() => + { + if (SystemControl is Dmps3SystemControl) + { + return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue; + } + else + { + return false; + } + }); + SystemPowerOffFeedback = new BoolFeedback(() => + { + if (SystemControl is Dmps3SystemControl) + { + return ((Dmps3SystemControl)SystemControl).SystemPowerOffFeedBack.BoolValue; + } + else + { + return false; + } + }); + VideoOutputFeedbacks = new Dictionary(); AudioOutputFeedbacks = new Dictionary(); VideoInputSyncFeedbacks = new Dictionary(); @@ -158,6 +203,7 @@ namespace PepperDash.Essentials.DM // Subscribe to events Dmps.DMInputChange += Dmps_DMInputChange; Dmps.DMOutputChange += Dmps_DMOutputChange; + Dmps.DMSystemChange += Dmps_DMSystemChange; return base.CustomActivate(); } @@ -195,6 +241,22 @@ namespace PepperDash.Essentials.DM } } + public void SetPowerOn(bool a) + { + if (SystemControl is Dmps3SystemControl) + { + ((Dmps3SystemControl)SystemControl).SystemPowerOn(); + } + } + + public void SetPowerOff(bool a) + { + if (SystemControl is Dmps3SystemControl) + { + ((Dmps3SystemControl)SystemControl).SystemPowerOff(); + } + } + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { var joinMap = new DmpsRoutingControllerJoinMap(joinStart); @@ -215,9 +277,22 @@ namespace PepperDash.Essentials.DM Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + //Link up system + trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, SetPowerOn); + trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, SetPowerOff); + if (SystemPowerOnFeedback != null) + { + SystemPowerOnFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.SystemPowerOn.JoinNumber]); + } + if (SystemPowerOffFeedback != null) + { + SystemPowerOffFeedback.LinkInputSig( + trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]); + } + // Link up outputs LinkInputsToApi(trilist, joinMap); - LinkOutputsToApi(trilist, joinMap); } @@ -824,6 +899,23 @@ namespace PepperDash.Essentials.DM } + void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args) + { + switch (args.EventId) + { + case DMSystemEventIds.SystemPowerOnEventId: + { + SystemPowerOnFeedback.FireUpdate(); + break; + } + case DMSystemEventIds.SystemPowerOffEventId: + { + SystemPowerOffFeedback.FireUpdate(); + break; + } + } + } + /// /// /// @@ -891,7 +983,6 @@ namespace PepperDash.Essentials.DM // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) { - output.VideoOut = input; } @@ -915,7 +1006,6 @@ namespace PepperDash.Essentials.DM if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) { - output.USBRoutedTo = input; } From 35edbeacfcf1fda4efdbedc7b43bea76da15b2af Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 23 Sep 2021 16:01:07 -0400 Subject: [PATCH 390/480] Fix join map details for DMPS --- .../Bridges/JoinMaps/DmChassisControllerJoinMap.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index ee04bd45..60973801 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinMetadata { Description = "DM Chassis enable audio breakaway routing", - JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); @@ -20,7 +20,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinMetadata { Description = "DM Chassis enable USB breakaway routing", - JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); From fd232beae1df4b25f5a335b268df940aa5659232 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 24 Sep 2021 15:26:45 -0600 Subject: [PATCH 391/480] feat(essentails): #830 Adds EnteringStandbyModeFeedback to IHasHalfWakeMode --- .../VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs | 14 ++++++++++++++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 7 ++++++- .../VideoCodec/Interfaces/IHasStandbyMode.cs | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs index 8caeaf3e..e4945ce8 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs @@ -93,6 +93,20 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco JoinType = eJoinType.Digital }); + [JoinName("EnteringStandbyMode")] + public JoinDataComplete EnteringStandbyMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 229, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "High to indicate that the codec is entering standby mode", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + #endregion diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index d625637c..020eec7d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -319,7 +319,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco SupportsCameraOff = true; DoNotDisturbModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Conference.DoNotDisturb.BoolValue); - HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value == "Halfwake"); + HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value.ToLower() == "halfwake"); + EnteringStandbyModeFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value.ToLower() == "enteringstandby"); PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); @@ -422,6 +423,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { StandbyIsOnFeedback.FireUpdate(); HalfWakeModeIsOnFeedback.FireUpdate(); + EnteringStandbyModeFeedback.FireUpdate(); }); CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; @@ -1546,6 +1548,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco halfwakeCodec.StandbyIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateStandby.JoinNumber]); halfwakeCodec.StandbyIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateStandby.JoinNumber]); halfwakeCodec.HalfWakeModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateHalfWakeMode.JoinNumber]); + halfwakeCodec.EnteringStandbyModeFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnteringStandbyMode.JoinNumber]); trilist.SetSigFalseAction(joinMap.ActivateStandby.JoinNumber, () => halfwakeCodec.StandbyActivate()); trilist.SetSigFalseAction(joinMap.DeactivateStandby.JoinNumber, () => halfwakeCodec.StandbyDeactivate()); @@ -2157,6 +2160,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public BoolFeedback HalfWakeModeIsOnFeedback { get; private set; } + public BoolFeedback EnteringStandbyModeFeedback { get; private set; } + public void HalfwakeActivate() { SendText("xCommand Standby Halfwake"); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs index 55dcd081..cc9dcd3d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs @@ -27,6 +27,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { BoolFeedback HalfWakeModeIsOnFeedback { get; } + BoolFeedback EnteringStandbyModeFeedback { get; } + void HalfwakeActivate(); } } \ No newline at end of file From 1e9139f38edab12096712dbcaec7fae4f3cd8dbc Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 24 Sep 2021 17:25:14 -0600 Subject: [PATCH 392/480] feat(essentials): Reworks logic in InitializeSystem() to be a bit cleaner using a CEvent and the existing AllDeviceActivated event --- PepperDashEssentials/ControlSystem.cs | 19 ++++++++++++++----- .../Devices/DeviceManager.cs | 3 --- .../PepperDashEssentialsBase/Global/Global.cs | 10 ++++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index f3674b41..51aa1353 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -28,6 +28,7 @@ namespace PepperDash.Essentials HttpLogoServer LogoServer; private CTimer _startTimer; + private CEvent _initializeEvent; private const long StartupTime = 500; public ControlSystem() @@ -46,12 +47,20 @@ namespace PepperDash.Essentials public override void InitializeSystem() { _startTimer = new CTimer(StartSystem,StartupTime); - ushort count = 0; - while (!DeviceManager.AllDevicesActivatedFb && count < 60) + + + // If the control system is a DMPS type, we need to wait to exit this method until all devices have had time to activate + // to allow any HD-BaseT DM endpoints to register first. + if (Global.ControlSystemIsDmpsType) { - //Wait for devices to register before returning, as required by DMPS. Max wait is 60 seconds. - CrestronEnvironment.Sleep(1000); - count++; + _initializeEvent = new CEvent(); + + DeviceManager.AllDevicesActivated += (o, a) => + { + _initializeEvent.Set(); + }; + + _initializeEvent.Wait(20000); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs index c5363a00..df864550 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs @@ -28,11 +28,9 @@ namespace PepperDash.Essentials.Core public static List AllDevices { get { return new List(Devices.Values); } } public static bool AddDeviceEnabled; - public static bool AllDevicesActivatedFb; public static void Initialize(CrestronControlSystem cs) { - AllDevicesActivatedFb = false; AddDeviceEnabled = true; CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices", ConsoleAccessLevelEnum.AccessOperator); @@ -124,7 +122,6 @@ namespace PepperDash.Essentials.Core private static void OnAllDevicesActivated() { - AllDevicesActivatedFb = true; var handler = AllDevicesActivated; if (handler != null) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 121bc9b7..0365b209 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -32,6 +32,16 @@ namespace PepperDash.Essentials.Core // TODO: consider making this configurable later public static IFormatProvider Culture = CultureInfo.CreateSpecificCulture("en-US"); + /// + /// True when the processor type is a DMPS variant + /// + public static bool ControlSystemIsDmpsType + { + get + { + return ControlSystem.ControllerPrompt.ToLower().IndexOf("dmps") > -1; + } + } /// /// The file path prefix to the folder containing configuration files From 5f50f14a71bd0e892749270385e70b4c6dc2d7d5 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 24 Sep 2021 17:26:13 -0600 Subject: [PATCH 393/480] feat(essentials): Updates timeout to 30s --- PepperDashEssentials/ControlSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 51aa1353..9afa210d 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -60,7 +60,7 @@ namespace PepperDash.Essentials _initializeEvent.Set(); }; - _initializeEvent.Wait(20000); + _initializeEvent.Wait(30000); } } From 66ecf435086d3451da113d01718b1bc6e563b12b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 16:53:11 -0600 Subject: [PATCH 394/480] chore: Update PD Core to 1.0.48 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 3876040a..3494f2eb 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From 10445508b20db6a90f44e94f40cfcb72698269e1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 16:53:36 -0600 Subject: [PATCH 395/480] feat: Update `Essentials Device` to call `Initialize` method --- .../Devices/EssentialsDevice.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 781101d4..00624007 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -27,6 +27,27 @@ namespace PepperDash.Essentials.Core { } + + private void SubscribeToActivateComplete() + { + DeviceManager.AllDevicesActivated += DeviceManagerOnAllDevicesActivated; + } + + private void DeviceManagerOnAllDevicesActivated(object sender, EventArgs eventArgs) + { + CrestronInvoke.BeginInvoke((o) => + { + try + { + Initialize(); + } + catch (Exception ex) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Exception initializing device: {0}", ex.Message); + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace); + } + }); + } } [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)] From 5940ec17c27d5bd43f7bca143af2c5e67ab22bc1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 19:44:41 -0600 Subject: [PATCH 396/480] feat: Add method call to constructor for EssentialsDevice --- .../PepperDashEssentialsBase/Devices/EssentialsDevice.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs index 00624007..46fa819b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/EssentialsDevice.cs @@ -19,13 +19,13 @@ namespace PepperDash.Essentials.Core protected EssentialsDevice(string key) : base(key) { - + SubscribeToActivateComplete(); } protected EssentialsDevice(string key, string name) : base(key, name) { - + SubscribeToActivateComplete(); } private void SubscribeToActivateComplete() From b71c83bac093786294bf2bb6b280c8a8d77583ec Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 23 Jul 2021 19:56:29 -0600 Subject: [PATCH 397/480] feat: Update some internal Essentials devices to use Initialize method --- .../MicrophonePrivacyController.cs | 14 +++++++++----- .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 19 +++++++++++++------ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 17 +++++++++++++---- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs index 0f15a02d..55b458a7 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Microphone Privacy/MicrophonePrivacyController.cs @@ -88,11 +88,6 @@ namespace PepperDash.Essentials.Core.Privacy else Debug.Console(0, this, "Unable to add Red LED device"); - DeviceManager.AllDevicesActivated += (o, a) => - { - CheckPrivacyMode(); - }; - AddPostActivationAction(() => { PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange; PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange; @@ -103,6 +98,15 @@ namespace PepperDash.Essentials.Core.Privacy return base.CustomActivate(); } + #region Overrides of Device + + public override void Initialize() + { + CheckPrivacyMode(); + } + + #endregion + public void SetPrivacyDevice(IPrivacy privacyDevice) { PrivacyDevice = privacyDevice; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 4db4084c..f894141c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -551,6 +551,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CrestronConsole.AddNewConsoleCommand(GetPhonebook, "GetCodecPhonebook", "Triggers a refresh of the codec phonebook", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(GetBookings, "GetCodecBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); + return base.CustomActivate(); + } + + #region Overrides of Device + + public override void Initialize() + { var socket = Communication as ISocketStatus; if (socket != null) { @@ -559,9 +566,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco Communication.Connect(); - CommunicationMonitor.Start(); + CommunicationMonitor.Start(); - string prefix = "xFeedback register "; + const string prefix = "xFeedback register "; CliFeedbackRegistrationExpression = prefix + "/Configuration" + Delimiter + @@ -576,14 +583,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco prefix + "/Status/Video/Layout" + Delimiter + prefix + "/Status/Video/Input/MainVideoMute" + Delimiter + prefix + "/Bookings" + Delimiter + - prefix + "/Event/CallDisconnect" + Delimiter + + prefix + "/Event/CallDisconnect" + Delimiter + prefix + "/Event/Bookings" + Delimiter + prefix + "/Event/CameraPresetListUpdated" + Delimiter + - prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; - - return base.CustomActivate(); + prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter; } + #endregion + /// /// Fires when initial codec sync is completed. Used to then send commands to get call history, phonebook, bookings, etc. /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index e4a724a2..32a24a28 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -791,7 +791,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom CrestronConsole.AddNewConsoleCommand(s => GetBookings(), "GetZoomRoomBookings", "Triggers a refresh of the booking data for today", ConsoleAccessLevelEnum.AccessOperator); - var socket = Communication as ISocketStatus; + + + return base.CustomActivate(); + } + + #region Overrides of Device + + public override void Initialize() + { + var socket = Communication as ISocketStatus; if (socket != null) { socket.ConnectionChange += socket_ConnectionChange; @@ -802,11 +811,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Communication.Connect(); CommunicationMonitor.Start(); + } - return base.CustomActivate(); - } + #endregion - public void SetCommDebug(string s) + public void SetCommDebug(string s) { if (s == "1") { From a6430a7bfe0386f309930b6d41339018bbe82d64 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 28 Sep 2021 11:05:05 -0600 Subject: [PATCH 398/480] chore: Update PD Core to 1.1.0 --- packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages.config b/packages.config index 3494f2eb..10124bbd 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From d444b8a7ba459f50f9ec02310416ab4e5832cf4b Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Tue, 28 Sep 2021 15:23:38 -0400 Subject: [PATCH 399/480] Fixes codec fader creation on aux1 and aux2 outputs. Fixes a few join map labels. --- .../Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs | 8 ++++---- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index 247dfd8f..5ce2cd2e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("MasterVolumeDown")] public JoinDataComplete MasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 }, - new JoinMetadata { Description = "Master Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + new JoinMetadata { Description = "Master Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("SourceVolumeLevel")] public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, @@ -43,7 +43,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("SourceVolumeDown")] public JoinDataComplete SourceVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, - new JoinMetadata { Description = "Source Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + new JoinMetadata { Description = "Source Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("Codec1VolumeLevel")] public JoinDataComplete Codec1VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, @@ -63,7 +63,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("Codec1VolumeDown")] public JoinDataComplete Codec1VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec1 Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + new JoinMetadata { Description = "Codec1 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("Codec2VolumeLevel")] public JoinDataComplete Codec2VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, @@ -83,7 +83,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("Codec2VolumeDown")] public JoinDataComplete Codec2VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec2 Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + new JoinMetadata { Description = "Codec2 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 484293eb..0b08500d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -586,7 +586,7 @@ namespace PepperDash.Essentials.DM { AddAudioOnlyOutputPort(number, "Program"); - var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3ProgramOutput); DeviceManager.AddDevice(programOutput); } @@ -598,7 +598,7 @@ namespace PepperDash.Essentials.DM { AddAudioOnlyOutputPort(number, "Aux1"); - var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux1Output); DeviceManager.AddDevice(aux1Output); } @@ -607,7 +607,7 @@ namespace PepperDash.Essentials.DM { AddAudioOnlyOutputPort(number, "Aux2"); - var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); + var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux2Output); DeviceManager.AddDevice(aux2Output); } From 5442a1db48f8c141a7f46eeb8286d3a287df784f Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 29 Sep 2021 15:14:07 -0600 Subject: [PATCH 400/480] fix(essentials): #842 Adds back in code to register Crestron devices under normal circumstances --- PepperDashEssentials/ControlSystem.cs | 3 +++ .../Crestron/CrestronGenericBaseDevice.cs | 27 ++++++++++++------- .../PepperDashEssentialsBase/Global/Global.cs | 11 ++++++++ .../Endpoints/Transmitters/DmTxHelpers.cs | 20 +++++++------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 9afa210d..b454cec9 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -53,11 +53,14 @@ namespace PepperDash.Essentials // to allow any HD-BaseT DM endpoints to register first. if (Global.ControlSystemIsDmpsType) { + Debug.Console(2, "******************* InitializeSystem() Entering **********************"); + _initializeEvent = new CEvent(); DeviceManager.AllDevicesActivated += (o, a) => { _initializeEvent.Set(); + Debug.Console(2, "******************* InitializeSystem() Exiting **********************"); }; _initializeEvent.Wait(30000); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs index df2c3c56..b7534087 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron/CrestronGenericBaseDevice.cs @@ -69,19 +69,28 @@ namespace PepperDash.Essentials.Core public override bool CustomActivate() { Debug.Console(0, this, "Activating"); - if (!PreventRegistration) - { + if (!PreventRegistration) + { //Debug.Console(1, this, " Does not require registration. Skipping"); - var response = Hardware.RegisterWithLogging(Key); - if (response != eDeviceRegistrationUnRegistrationResponse.Success) - { - //Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response); - return false; - } + var response = Hardware.RegisterWithLogging(Key); + if (response != eDeviceRegistrationUnRegistrationResponse.Success) + { + //Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response); + return false; + } IsRegistered.FireUpdate(); - } + } + else + { + AddPostActivationAction(() => + { + var response = Hardware.RegisterWithLogging(Key); + + IsRegistered.FireUpdate(); + }); + } foreach (var f in Feedbacks) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 0365b209..9d792437 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -43,6 +43,17 @@ namespace PepperDash.Essentials.Core } } + /// + /// True when the processor type is a DMPS 4K variant + /// + public static bool ControlSystemIsDmps4kType + { + get + { + return ControlSystemIsDmpsType && ControlSystem.ControllerPrompt.ToLower().IndexOf("4k") > -1; + } + } + /// /// The file path prefix to the folder containing configuration files /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs index 3ff14dba..fcec7fa4 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs @@ -36,7 +36,7 @@ namespace PepperDash.Essentials.DM var ipid = props.Control.IpIdInt; var pKey = props.ParentDeviceKey.ToLower(); - if (pKey == "processor") + if (pKey == "processor") { // Catch constructor failures, mainly dues to IPID try @@ -70,7 +70,7 @@ namespace PepperDash.Essentials.DM var parentDev = DeviceManager.GetDeviceForKey(pKey); DMInput dmInput; - bool noIpId = false; + bool isCpu3 = false; if (parentDev is IDmSwitch) { @@ -96,7 +96,7 @@ namespace PepperDash.Essentials.DM chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps || chassis is DmMd128x128 || chassis is DmMd64x64) { - noIpId = true; + isCpu3 = true; } } @@ -116,7 +116,6 @@ namespace PepperDash.Essentials.DM } dmpsDev.TxDictionary.Add(num, key); - noIpId = dmpsDev.Dmps4kType; try { @@ -138,7 +137,7 @@ namespace PepperDash.Essentials.DM try { // Must use different constructor for CPU3 or DMPS3-4K types. No IPID - if (noIpId) + if (isCpu3 || Global.ControlSystemIsDmps4kType) { if (typeName.StartsWith("dmtx200")) return new DmTx200Controller(key, name, new DmTx200C2G(dmInput)); @@ -222,11 +221,12 @@ namespace PepperDash.Essentials.DM protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware) : base(key, name, hardware) { - // if wired to a chassis, skip registration step in base class - if (hardware.DMInput != null) - { - this.PreventRegistration = true; - } + // if wired to a chassis or DMPS, skip registration step in base class + if (hardware.DMInput != null || (Global.ControlSystemIsDmpsType && hardware.DMInput != null)) + { + this.PreventRegistration = true; + } + AddToFeedbackList(ActiveVideoInputFeedback); } From c296ef9e2148c09dc9ebe70fe8ae0938ad7f173d Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 1 Oct 2021 18:10:57 -0400 Subject: [PATCH 401/480] Adds mics master level. Adds set/get to bridge for scaled volume (0-65535) which accounts for min/max settings on DMPS. --- .../DmpsAudioOutputControllerJoinMap.cs | 39 +++++++++ .../Chassis/DmpsAudioOutputController.cs | 82 +++++++++++++++---- 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index 5ce2cd2e..85843b04 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -9,6 +9,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete MasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "Master Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("MasterVolumeLevelScaled")] + public JoinDataComplete MasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata { Description = "Master Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("MasterVolumeMuteOn")] public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); @@ -29,6 +33,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata { Description = "Source Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("SourceVolumeLevelScaled")] + public JoinDataComplete SourceVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, + new JoinMetadata { Description = "Source Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("SourceVolumeMuteOn")] public JoinDataComplete SourceVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata { Description = "Source Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); @@ -49,6 +57,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete Codec1VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata { Description = "Codec1 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Codec1VolumeLevelScaled")] + public JoinDataComplete Codec1VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, + new JoinMetadata { Description = "Codec1 Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Codec1VolumeMuteOn")] public JoinDataComplete Codec1VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata { Description = "Codec1 Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); @@ -69,6 +81,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete Codec2VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, new JoinMetadata { Description = "Codec2 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Codec2VolumeLevelScaled")] + public JoinDataComplete Codec2VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 32, JoinSpan = 1 }, + new JoinMetadata { Description = "Codec2 Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Codec2VolumeMuteOn")] public JoinDataComplete Codec2VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, new JoinMetadata { Description = "Codec2 Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); @@ -85,6 +101,29 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete Codec2VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 }, new JoinMetadata { Description = "Codec2 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("MicsMasterVolumeLevel")] + public JoinDataComplete MicsMasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("MicsMasterVolumeLevelScaled")] + public JoinDataComplete MicsMasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("MicsMasterVolumeMuteOn")] + public JoinDataComplete MicsMasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicsMasterVolumeMuteOff")] + public JoinDataComplete MicsMasterVolumeMuteOff = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Mute Off Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicsMasterVolumeUp")] + public JoinDataComplete MicsMasterVolumeUp = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Level Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicsMasterVolumeDown")] + public JoinDataComplete MicsMasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 44, JoinSpan = 1 }, + new JoinMetadata { Description = "MicsMaster Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); /// /// Constructor to use when instantiating this Join Map without inheriting from it diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 9f839c89..18e35999 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -24,7 +24,8 @@ namespace PepperDash.Essentials.DM Card.Dmps3OutputBase OutputCard; public DmpsAudioOutput MasterVolumeLevel { get; private set; } - public DmpsAudioOutput SourceVolumeLevel { get; private set; } + public DmpsAudioOutput SourceVolumeLevel { get; private set; } + public DmpsAudioOutput MicsMasterVolumeLevel { get; private set; } public DmpsAudioOutput Codec1VolumeLevel { get; private set; } public DmpsAudioOutput Codec2VolumeLevel { get; private set; } @@ -37,12 +38,11 @@ namespace PepperDash.Essentials.DM OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange); MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); 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); } @@ -74,6 +74,16 @@ namespace PepperDash.Essentials.DM { SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); break; + } + case DMOutputEventIds.MicMasterLevelFeedBackEventId: + { + MicsMasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.MicMasterMuteOnFeedBackEventId: + { + MicsMasterVolumeLevel.MuteFeedback.FireUpdate(); + break; } case DMOutputEventIds.Codec1LevelFeedBackEventId: { @@ -130,6 +140,11 @@ namespace PepperDash.Essentials.DM if (SourceVolumeLevel != null) { SetUpDmpsAudioOutputJoins(trilist, SourceVolumeLevel, joinMap.SourceVolumeLevel.JoinNumber); + } + + if (MicsMasterVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, MicsMasterVolumeLevel, joinMap.MicsMasterVolumeLevel.JoinNumber); } if (Codec1VolumeLevel != null) @@ -146,15 +161,18 @@ namespace PepperDash.Essentials.DM static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart) { - var volumeLevelJoin = joinStart; + var volumeLevelJoin = joinStart; + var volumeLevelScaledJoin = joinStart + 1; var muteOnJoin = joinStart; var muteOffJoin = joinStart + 1; var volumeUpJoin = joinStart + 2; var volumeDownJoin = joinStart + 3; - - + trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); - output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); + output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); + + trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); + output.VolumeLevelScaledFeedback.LinkInputSig(trilist.UShortInput[volumeLevelScaledJoin]); trilist.SetSigTrueAction(muteOnJoin, output.MuteOn); output.MuteFeedback.LinkInputSig(trilist.BooleanInput[muteOnJoin]); @@ -170,12 +188,15 @@ namespace PepperDash.Essentials.DM { Card.Dmps3OutputBase Output; - UShortInputSig Level; + UShortInputSig Level; + UShortOutputSig MinLevel; + UShortOutputSig MaxLevel; eDmpsLevelType Type; public BoolFeedback MuteFeedback { get; private set; } - public IntFeedback VolumeLevelFeedback { get; private set; } + public IntFeedback VolumeLevelFeedback { get; private set; } + public IntFeedback VolumeLevelScaledFeedback { get; private set; } Action MuteOnAction; Action MuteOffAction; @@ -186,7 +207,10 @@ namespace PepperDash.Essentials.DM { Output = output; - Type = type; + Type = type; + + MinLevel = (output as Card.Dmps3ProgramOutput).OutputMixer.MinVolumeFeedback; + MaxLevel = (output as Card.Dmps3ProgramOutput).OutputMixer.MaxVolumeFeedback; switch (type) { @@ -200,7 +224,6 @@ namespace PepperDash.Essentials.DM MuteOffAction = new Action(Output.MasterMuteOff); VolumeUpAction = new Action((b) => Output.MasterVolumeUp.BoolValue = b); VolumeDownAction = new Action((b) => Output.MasterVolumeDown.BoolValue = b); - break; } @@ -291,14 +314,43 @@ namespace PepperDash.Essentials.DM } break; } - } - + } + + VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + } + + public void SetVolumeScaled(ushort level) + { + //Master fader scaling depends on min and max settings on DMPS + if (Type == eDmpsLevelType.Master) + { + Level.UShortValue = (ushort)(level * (MaxLevel.UShortValue - MinLevel.UShortValue) / 65535 + MinLevel.UShortValue); + } + // Other faders have min = -800 and max = 100 + else + { + Level.UShortValue = (ushort)(level * 900 / 65535 - 800); + } + } + + public ushort ScaleVolumeFeedback(ushort level) + { + //Master fader scaling depends on min and max settings on DMPS + if (Type == eDmpsLevelType.Master) + { + return (ushort)((level - MinLevel.UShortValue) * 65535 / (MaxLevel.UShortValue - MinLevel.UShortValue)); + } + // Other faders have min = -800 and max = 100 + else + { + return (ushort)((level + 800) * 65535 / 900); + } } #region IBasicVolumeWithFeedback Members public void SetVolume(ushort level) - { + { Level.UShortValue = level; } From 32443a2102bbe6e4362b85e150a2e12697a504bb Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Mon, 4 Oct 2021 16:52:07 -0400 Subject: [PATCH 402/480] Improvements for min/max scaling on dmps audio --- .../DmpsAudioOutputControllerJoinMap.cs | 20 +-- .../Chassis/DmpsAudioOutputController.cs | 160 ++++++++++++------ 2 files changed, 121 insertions(+), 59 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index 85843b04..30904638 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -7,11 +7,11 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("MasterVolumeLevel")] public JoinDataComplete MasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata { Description = "Master Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Master Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("MasterVolumeLevelScaled")] public JoinDataComplete MasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, - new JoinMetadata { Description = "Master Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Master Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("MasterVolumeMuteOn")] public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, @@ -31,11 +31,11 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("SourceVolumeLevel")] public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, - new JoinMetadata { Description = "Source Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Source Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("SourceVolumeLevelScaled")] public JoinDataComplete SourceVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, - new JoinMetadata { Description = "Source Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Source Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("SourceVolumeMuteOn")] public JoinDataComplete SourceVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, @@ -55,11 +55,11 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("Codec1VolumeLevel")] public JoinDataComplete Codec1VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec1 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Codec1 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("Codec1VolumeLevelScaled")] public JoinDataComplete Codec1VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec1 Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Codec1 Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("Codec1VolumeMuteOn")] public JoinDataComplete Codec1VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, @@ -79,11 +79,11 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("Codec2VolumeLevel")] public JoinDataComplete Codec2VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec2 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Codec2 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("Codec2VolumeLevelScaled")] public JoinDataComplete Codec2VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 32, JoinSpan = 1 }, - new JoinMetadata { Description = "Codec2 Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "Codec2 Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("Codec2VolumeMuteOn")] public JoinDataComplete Codec2VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, @@ -103,11 +103,11 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("MicsMasterVolumeLevel")] public JoinDataComplete MicsMasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, - new JoinMetadata { Description = "MicsMaster Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "MicsMaster Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("MicsMasterVolumeLevelScaled")] public JoinDataComplete MicsMasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 }, - new JoinMetadata { Description = "MicsMaster Volume Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "MicsMaster Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); [JoinName("MicsMasterVolumeMuteOn")] public JoinDataComplete MicsMasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 18e35999..6530f9de 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -29,7 +29,6 @@ namespace PepperDash.Essentials.DM public DmpsAudioOutput Codec1VolumeLevel { get; private set; } public DmpsAudioOutput Codec2VolumeLevel { get; private set; } - public DmpsAudioOutputController(string key, string name, Card.Dmps3OutputBase card) : base(key, name) { @@ -37,22 +36,42 @@ namespace PepperDash.Essentials.DM OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange); - MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); - MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); - if (card is Card.Dmps3ProgramOutput) - { + { + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) + { + Mixer = (card as Card.Dmps3ProgramOutput).OutputMixer + }; + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); } else if (card is Card.Dmps3Aux1Output) - { + { + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) + { + Mixer = (card as Card.Dmps3Aux1Output).OutputMixer + }; + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); - } - else if (card is Card.Dmps3Aux2Output) - { - Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); + } + else if (card is Card.Dmps3Aux2Output) + { + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) + { + Mixer = (card as Card.Dmps3Aux2Output).OutputMixer + }; + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); + Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); + } + else //Digital Outputs + { + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); } } @@ -62,7 +81,8 @@ namespace PepperDash.Essentials.DM { case DMOutputEventIds.MasterVolumeFeedBackEventId: { - MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + MasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); break; } case DMOutputEventIds.MasterMuteOnFeedBackEventId: @@ -72,12 +92,19 @@ namespace PepperDash.Essentials.DM } case DMOutputEventIds.SourceLevelFeedBackEventId: { - SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); + SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); + SourceVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); break; } + case DMOutputEventIds.SourceMuteOnFeedBackEventId: + { + SourceVolumeLevel.MuteFeedback.FireUpdate(); + break; + } case DMOutputEventIds.MicMasterLevelFeedBackEventId: { MicsMasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + MicsMasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); break; } case DMOutputEventIds.MicMasterMuteOnFeedBackEventId: @@ -86,9 +113,12 @@ namespace PepperDash.Essentials.DM break; } case DMOutputEventIds.Codec1LevelFeedBackEventId: - { - if(Codec1VolumeLevel != null) - Codec1VolumeLevel.VolumeLevelFeedback.FireUpdate(); + { + if (Codec1VolumeLevel != null) + { + Codec1VolumeLevel.VolumeLevelFeedback.FireUpdate(); + Codec1VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + } break; } case DMOutputEventIds.Codec1MuteOnFeedBackEventId: @@ -98,9 +128,12 @@ namespace PepperDash.Essentials.DM break; } case DMOutputEventIds.Codec2LevelFeedBackEventId: - { - if (Codec2VolumeLevel != null) - Codec2VolumeLevel.VolumeLevelFeedback.FireUpdate(); + { + if (Codec2VolumeLevel != null) + { + Codec2VolumeLevel.VolumeLevelFeedback.FireUpdate(); + Codec2VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + } break; } case DMOutputEventIds.Codec2MuteOnFeedBackEventId: @@ -109,6 +142,24 @@ namespace PepperDash.Essentials.DM Codec2VolumeLevel.MuteFeedback.FireUpdate(); break; } + case DMOutputEventIds.MinVolumeFeedBackEventId: + { + Debug.Console(2, this, "MinVolumeFeedBackEventId: {0}", args.Index); + if (MasterVolumeLevel != null) + { + MasterVolumeLevel.GetVolumeMin(); + } + break; + } + case DMOutputEventIds.MaxVolumeFeedBackEventId: + { + Debug.Console(2, this, "MaxVolumeFeedBackEventId: {0}", args.Index); + if (MasterVolumeLevel != null) + { + MasterVolumeLevel.GetVolumeMax(); + } + break; + } } } @@ -186,14 +237,14 @@ namespace PepperDash.Essentials.DM public class DmpsAudioOutput : IBasicVolumeWithFeedback { - Card.Dmps3OutputBase Output; - + Card.Dmps3OutputBase Output; + eDmpsLevelType Type; UShortInputSig Level; - UShortOutputSig MinLevel; - UShortOutputSig MaxLevel; - - eDmpsLevelType Type; - + + public short MinLevel { get; private set; } + public short MaxLevel { get; private set; } + + public CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer { get; set; } public BoolFeedback MuteFeedback { get; private set; } public IntFeedback VolumeLevelFeedback { get; private set; } public IntFeedback VolumeLevelScaledFeedback { get; private set; } @@ -206,11 +257,9 @@ namespace PepperDash.Essentials.DM public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) { Output = output; - Type = type; - - MinLevel = (output as Card.Dmps3ProgramOutput).OutputMixer.MinVolumeFeedback; - MaxLevel = (output as Card.Dmps3ProgramOutput).OutputMixer.MaxVolumeFeedback; + MinLevel = -800; + MaxLevel = 100; switch (type) { @@ -224,7 +273,7 @@ namespace PepperDash.Essentials.DM 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: @@ -315,35 +364,48 @@ namespace PepperDash.Essentials.DM break; } } - - VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + if (VolumeLevelFeedback != null) + { + VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + } } public void SetVolumeScaled(ushort level) { - //Master fader scaling depends on min and max settings on DMPS - if (Type == eDmpsLevelType.Master) - { - Level.UShortValue = (ushort)(level * (MaxLevel.UShortValue - MinLevel.UShortValue) / 65535 + MinLevel.UShortValue); - } - // Other faders have min = -800 and max = 100 - else - { - Level.UShortValue = (ushort)(level * 900 / 65535 - 800); - } + Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); + Level.UShortValue = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); } public ushort ScaleVolumeFeedback(ushort level) { - //Master fader scaling depends on min and max settings on DMPS - if (Type == eDmpsLevelType.Master) + short signedLevel = (short)level; + Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString()); + return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); + } + + public void GetVolumeMin() + { + if (Mixer != null) { - return (ushort)((level - MinLevel.UShortValue) * 65535 / (MaxLevel.UShortValue - MinLevel.UShortValue)); + MinLevel = (short)Mixer.MinVolumeFeedback.UShortValue; + Debug.Console(2, Debug.ErrorLogLevel.None, "DMPS set {0} min level:{1}", Output.Name, MinLevel); + if (VolumeLevelScaledFeedback != null) + { + VolumeLevelScaledFeedback.FireUpdate(); + } } - // Other faders have min = -800 and max = 100 - else + } + + public void GetVolumeMax() + { + if (Mixer != null) { - return (ushort)((level + 800) * 65535 / 900); + MaxLevel = (short)Mixer.MaxVolumeFeedback.UShortValue; + Debug.Console(2, Debug.ErrorLogLevel.None, "DMPS set {0} max level:{1}", Output.Name, MaxLevel); + if (VolumeLevelScaledFeedback != null) + { + VolumeLevelScaledFeedback.FireUpdate(); + } } } From f7bf728263e1061a2001adee9e956d7e7d517219 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 7 Oct 2021 09:48:02 -0600 Subject: [PATCH 403/480] fix(Devices_Common): Clear meeting list and fire event if no meetings are scheduled --- .../VideoCodec/VideoCodecBase.cs | 17 +++++++++++++++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 15 ++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) 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 d34c9e3b..79b05046 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 @@ -298,6 +298,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } LinkVideoCodecToApi(codec, trilist, joinMap); + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + }; } /// @@ -785,6 +792,16 @@ ScreenIndexIsPinnedTo: {8} (a{17}) _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); + if (_currentMeetings.Count == 0) + { + var emptyXSigByteArray = XSigHelpers.ClearOutputs(); + var emptyXSigString = Encoding.GetEncoding(XSigEncoding) + .GetString(emptyXSigByteArray, 0, emptyXSigByteArray.Length); + + trilist.SetString(joinMap.Schedule.JoinNumber, emptyXSigString); + return; + } + var meetingsData = UpdateMeetingsListXSig(_currentMeetings); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 32a24a28..a43ea79c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1306,11 +1306,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var codecBookings = JsonConvert.DeserializeObject>( responseObj.ToString()); - if (codecBookings != null && codecBookings.Count > 0) - { - CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( - codecBookings, CodecSchedule.MeetingWarningMinutes); - } + if (codecBookings != null && codecBookings.Count > 0) + { + CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( + codecBookings, CodecSchedule.MeetingWarningMinutes); + } + else + { + //need to clear the list if it's empty + CodecSchedule.Meetings = new List(); + } break; } From 25423f0caa6fddef7d552175d8050c47bd3365f4 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Tue, 19 Oct 2021 09:32:28 -0400 Subject: [PATCH 404/480] Adds dm endpoint names to bridge at serial join 1 --- .../Bridges/JoinMaps/DmRmcControllerJoinMap.cs | 4 ++++ .../Bridges/JoinMaps/DmTxControllerJoinMap.cs | 6 +++++- .../Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs | 1 + .../Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs index c995e8c8..18706bb0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs @@ -32,6 +32,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete AudioVideoSource = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "DM RMC Audio Video Source Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "DM RMC Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + /// /// Constructor to use when instantiating this Join Map without inheriting from it /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs index 06953467..1cb0b347 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs @@ -42,7 +42,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("HdcpSupportCapability")] public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, - new JoinMetadata { Description = "DM TX HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + new JoinMetadata { Description = "DM TX HDCP Support Capability", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog }); [JoinName("Port1HdcpState")] public JoinDataComplete Port1HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 }, @@ -60,6 +60,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete VgaContrast = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata { Description = "DM TX Online", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "DM TX Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + /// /// Constructor to use when instantiating this Join Map without inheriting from it /// 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 9043d514..a9282693 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs @@ -61,6 +61,7 @@ namespace PepperDash.Essentials.DM Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = rmc.Name; if (rmc.VideoOutputResolutionFeedback != null) rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution.JoinNumber]); if (rmc.EdidManufacturerFeedback != null) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs index fcec7fa4..5eb2d7b5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs @@ -263,6 +263,7 @@ namespace PepperDash.Essentials.DM tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber]); tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution.JoinNumber]); trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability; + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = tx.Name; bool hdcpTypeSimple; From 6fcb47e0ef0fe505cabae53bd8ae1cf2e3b79fb0 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 25 Oct 2021 13:09:42 -0500 Subject: [PATCH 405/480] feat: Add configuraiton values for setting ultrasonic (US) and PIR sensor sensitivity from configuration. --- .../GlsOccupancySensorPropertiesConfig.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs index 1f21b2a8..1725909c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs @@ -47,5 +47,35 @@ namespace PepperDash.Essentials.Core [JsonProperty("andWhenVacatedState")] public bool? AndWhenVacatedState { get; set; } + + // PoE Sensors: CenOdtCPoe + + /// + /// Sets the sensitivity level for US while sensor is in occupied state + /// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow + /// + [JsonProperty("usSensitivityOccupied")] + public ushort? UsSensitivityOccupied { get; set; } + + /// + /// Sets the sensitivity level for US while sensor is in vacant state + /// 1 = low; 2 = medium; 3 = high; 4 = xlow; 5 = 2xlow; 6 = 3xlow + /// + [JsonProperty("usSensitivityVacant")] + public ushort? UsSensitivityVacant { get; set; } + + /// + /// Sets the sensitivity level for PIR while sensor is in occupied state + /// 1 = low; 2 = medium; 3 = high + /// + [JsonProperty("pirSensitivityOccupied")] + public ushort? PirSensitivityOccupied { get; set; } + + /// + /// Sets the sensitivity level for PIR while sensor is in vacant state + /// 1 = low; 2 = medium; 3 = high + /// + [JsonProperty("PirSensitivityVacant")] + public ushort? PirSensitivityVacant { get; set; } } } \ No newline at end of file From 38959414ffa40dbc0679cb8012f696cd900f2204 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 11 May 2021 10:16:03 -0600 Subject: [PATCH 406/480] Fix USB Routing issue --- .../Essentials_DM/Chassis/DmChassisController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index c74aea2b..30056082 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1349,8 +1349,10 @@ namespace PepperDash.Essentials.DM DMInputOutputBase dmCard; + //Routing Input to Input or Output to Input if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) { + Debug.Console(2, this, "Executing USB Input switch.\r\n in:{0} output: {1}", inputSelector, outputSelector); if (outputSelector > chassisSize) { uint outputIndex; @@ -1370,13 +1372,14 @@ namespace PepperDash.Essentials.DM dmCard = Chassis.Inputs[inputSelector]; } - ExecuteSwitch(dmCard, Chassis.Outputs[outputSelector], sigType); + ExecuteSwitch(dmCard, Chassis.Inputs[outputSelector], sigType); return; } if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) { Debug.Console(2, this, "Executing USB Output switch.\r\n in:{0} output: {1}", inputSelector, outputSelector); + //routing Output to Output or Input to Output if (inputSelector > chassisSize) { //wanting to route an output to an output. Subtract chassis size and get output, unless it's 8x8 From 16369e31cf7a514f8610aff41599fa4f6693083f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Tue, 11 May 2021 12:05:28 -0600 Subject: [PATCH 407/480] fix USB routing --- .../Chassis/DmChassisController.cs | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 30056082..016bb15d 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1285,7 +1285,10 @@ namespace PepperDash.Essentials.DM var output = outputSelector as DMOutput; - if (output == null) + var isUsbInput = (sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput; + var isUsbOutput = (sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput; + + if (output == null && !(isUsbOutput || isUsbInput)) { Debug.Console(0, this, Debug.ErrorLogLevel.Warning, "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, @@ -1330,13 +1333,31 @@ namespace PepperDash.Essentials.DM //Chassis.Outputs[output].AudioOut = inCard; } - if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput || (sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + if ((sigType & eRoutingSignalType.UsbOutput) != eRoutingSignalType.UsbOutput && + (sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput) { - Chassis.USBEnter.BoolValue = true; - output.USBRoutedTo = input; + return; } + Chassis.USBEnter.BoolValue = true; + if (output != null) + { + output.USBRoutedTo = input; + return; + } + var tempOutput = outputSelector as DMInput; + + if (tempOutput == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Warning, + "Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector, + outputSelector); + return; + } + + tempOutput.USBRoutedTo = input; } + #endregion #region IRoutingNumeric Members From cef9e0a9a66cdbcc9b825d1fd9e6d22fb9d3d3ac Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 12 May 2021 09:16:54 -0600 Subject: [PATCH 408/480] Update UsbOutput routing --- .../Chassis/DmChassisController.cs | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 016bb15d..030536df 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1319,7 +1319,10 @@ namespace PepperDash.Essentials.DM if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) { Chassis.VideoEnter.BoolValue = true; - output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard; + if (output != null) + { + output.VideoOut = input; //Chassis.Outputs[output].VideoOut = inCard; + } } if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) @@ -1329,12 +1332,43 @@ namespace PepperDash.Essentials.DM { dmMdMnxn.AudioEnter.BoolValue = true; } - output.AudioOut = input; - //Chassis.Outputs[output].AudioOut = inCard; + if (output != null) + { + output.AudioOut = input; + } } - if ((sigType & eRoutingSignalType.UsbOutput) != eRoutingSignalType.UsbOutput && - (sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput) + if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) + + { + Chassis.USBEnter.BoolValue = true; + if (inputSelector == null && output != null) + { + //clearing the route is intended + output.USBRoutedTo = null; + return; + } + + if (inputSelector != null && input == null) + { + //input selector is DMOutput...we're doing a out to out route + var tempInput = inputSelector as DMOutput; + + if (tempInput == null || output == null) + { + return; + } + output.USBRoutedTo = tempInput; + return; + } + + if (input != null & output != null) + { + output.USBRoutedTo = input; + } + } + + if((sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput) { return; } From 0ecf593e44806eff1d9cc52851126fc399c01e59 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 27 Oct 2021 10:18:54 -0400 Subject: [PATCH 409/480] Refactor some of the dmps audio changes --- .../Chassis/DmpsAudioOutputController.cs | 363 +++++++++--------- 1 file changed, 183 insertions(+), 180 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 6530f9de..612ea45a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -24,7 +24,7 @@ namespace PepperDash.Essentials.DM Card.Dmps3OutputBase OutputCard; public DmpsAudioOutput MasterVolumeLevel { get; private set; } - public DmpsAudioOutput SourceVolumeLevel { get; private set; } + public DmpsAudioOutput SourceVolumeLevel { get; private set; } public DmpsAudioOutput MicsMasterVolumeLevel { get; private set; } public DmpsAudioOutput Codec1VolumeLevel { get; private set; } public DmpsAudioOutput Codec2VolumeLevel { get; private set; } @@ -37,41 +37,38 @@ namespace PepperDash.Essentials.DM OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange); if (card is Card.Dmps3ProgramOutput) - { - MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) - { - Mixer = (card as Card.Dmps3ProgramOutput).OutputMixer - }; - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + { + MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3ProgramOutput).OutputMixer); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); } else if (card is Card.Dmps3Aux1Output) - { - MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) - { - Mixer = (card as Card.Dmps3Aux1Output).OutputMixer - }; - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + { + MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux1Output).OutputMixer); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); - } - else if (card is Card.Dmps3Aux2Output) - { - MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master) - { - Mixer = (card as Card.Dmps3Aux2Output).OutputMixer - }; - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); - MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); - Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); - } - else //Digital Outputs - { - MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); - SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); - MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); + } + else if (card is Card.Dmps3Aux2Output) + { + MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux2Output).OutputMixer); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); + Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); + ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); + } + else //Digital Outputs + { + MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); + SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); + MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); } } @@ -80,105 +77,107 @@ namespace PepperDash.Essentials.DM switch (args.EventId) { case DMOutputEventIds.MasterVolumeFeedBackEventId: - { - MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); - MasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); - break; - } + { + MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + MasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + break; + } case DMOutputEventIds.MasterMuteOnFeedBackEventId: - { - MasterVolumeLevel.MuteFeedback.FireUpdate(); - break; - } + { + MasterVolumeLevel.MuteFeedback.FireUpdate(); + break; + } case DMOutputEventIds.SourceLevelFeedBackEventId: - { - SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); - SourceVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); - break; - } - case DMOutputEventIds.SourceMuteOnFeedBackEventId: - { - SourceVolumeLevel.MuteFeedback.FireUpdate(); - break; - } - case DMOutputEventIds.MicMasterLevelFeedBackEventId: - { - MicsMasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); - MicsMasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); - break; - } - case DMOutputEventIds.MicMasterMuteOnFeedBackEventId: - { - MicsMasterVolumeLevel.MuteFeedback.FireUpdate(); - break; - } + { + SourceVolumeLevel.VolumeLevelFeedback.FireUpdate(); + SourceVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.SourceMuteOnFeedBackEventId: + { + SourceVolumeLevel.MuteFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.MicMasterLevelFeedBackEventId: + { + MicsMasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); + MicsMasterVolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.MicMasterMuteOnFeedBackEventId: + { + MicsMasterVolumeLevel.MuteFeedback.FireUpdate(); + break; + } case DMOutputEventIds.Codec1LevelFeedBackEventId: - { - if (Codec1VolumeLevel != null) - { - Codec1VolumeLevel.VolumeLevelFeedback.FireUpdate(); - Codec1VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + { + if (Codec1VolumeLevel != null) + { + Codec1VolumeLevel.VolumeLevelFeedback.FireUpdate(); + Codec1VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + } + break; } - break; - } case DMOutputEventIds.Codec1MuteOnFeedBackEventId: - { - if (Codec1VolumeLevel != null) - Codec1VolumeLevel.MuteFeedback.FireUpdate(); - break; - } - case DMOutputEventIds.Codec2LevelFeedBackEventId: - { - if (Codec2VolumeLevel != null) - { - Codec2VolumeLevel.VolumeLevelFeedback.FireUpdate(); - Codec2VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + { + if (Codec1VolumeLevel != null) + Codec1VolumeLevel.MuteFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.Codec2LevelFeedBackEventId: + { + if (Codec2VolumeLevel != null) + { + Codec2VolumeLevel.VolumeLevelFeedback.FireUpdate(); + Codec2VolumeLevel.VolumeLevelScaledFeedback.FireUpdate(); + } + break; } - break; - } case DMOutputEventIds.Codec2MuteOnFeedBackEventId: - { - if (Codec2VolumeLevel != null) - Codec2VolumeLevel.MuteFeedback.FireUpdate(); - break; - } - case DMOutputEventIds.MinVolumeFeedBackEventId: - { - Debug.Console(2, this, "MinVolumeFeedBackEventId: {0}", args.Index); - if (MasterVolumeLevel != null) - { - MasterVolumeLevel.GetVolumeMin(); - } - break; - } - case DMOutputEventIds.MaxVolumeFeedBackEventId: - { - Debug.Console(2, this, "MaxVolumeFeedBackEventId: {0}", args.Index); - if (MasterVolumeLevel != null) - { - MasterVolumeLevel.GetVolumeMax(); - } - break; - } + { + if (Codec2VolumeLevel != null) + Codec2VolumeLevel.MuteFeedback.FireUpdate(); + break; + } + case DMOutputEventIds.MinVolumeFeedBackEventId: + { + Debug.Console(2, this, "MinVolumeFeedBackEventId: {0}", args.Index); + var level = MasterVolumeLevel as DmpsAudioOutputWithMixer; + if (level != null) + { + level.GetVolumeMin(); + } + break; + } + case DMOutputEventIds.MaxVolumeFeedBackEventId: + { + Debug.Console(2, this, "MaxVolumeFeedBackEventId: {0}", args.Index); + var level = MasterVolumeLevel as DmpsAudioOutputWithMixer; + if (level != null) + { + level.GetVolumeMax(); + } + break; + } } } public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { + { var joinMap = new DmpsAudioOutputControllerJoinMap(joinStart); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - else - { - Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); } Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); @@ -191,11 +190,11 @@ namespace PepperDash.Essentials.DM if (SourceVolumeLevel != null) { SetUpDmpsAudioOutputJoins(trilist, SourceVolumeLevel, joinMap.SourceVolumeLevel.JoinNumber); - } - - if (MicsMasterVolumeLevel != null) - { - SetUpDmpsAudioOutputJoins(trilist, MicsMasterVolumeLevel, joinMap.MicsMasterVolumeLevel.JoinNumber); + } + + if (MicsMasterVolumeLevel != null) + { + SetUpDmpsAudioOutputJoins(trilist, MicsMasterVolumeLevel, joinMap.MicsMasterVolumeLevel.JoinNumber); } if (Codec1VolumeLevel != null) @@ -212,17 +211,17 @@ namespace PepperDash.Essentials.DM static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart) { - var volumeLevelJoin = joinStart; + var volumeLevelJoin = joinStart; var volumeLevelScaledJoin = joinStart + 1; var muteOnJoin = joinStart; var muteOffJoin = joinStart + 1; var volumeUpJoin = joinStart + 2; var volumeDownJoin = joinStart + 3; - + trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); - output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); - - trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); + output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); + + trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); output.VolumeLevelScaledFeedback.LinkInputSig(trilist.UShortInput[volumeLevelScaledJoin]); trilist.SetSigTrueAction(muteOnJoin, output.MuteOn); @@ -232,33 +231,64 @@ namespace PepperDash.Essentials.DM trilist.SetBoolSigAction(volumeUpJoin, output.VolumeUp); trilist.SetBoolSigAction(volumeDownJoin, output.VolumeDown); + + trilist.OnlineStatusChange += (a, b) => output.VolumeLevelFeedback.FireUpdate(); + trilist.OnlineStatusChange += (a, b) => output.VolumeLevelScaledFeedback.FireUpdate(); + } + } + + public class DmpsAudioOutputWithMixer : DmpsAudioOutput + { + CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer; + + public DmpsAudioOutputWithMixer(Card.Dmps3OutputBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo mixer) + : base(output, type) + { + Mixer = mixer; + } + + public void GetVolumeMin() + { + MinLevel = (short)Mixer.MinVolumeFeedback.UShortValue; + if (VolumeLevelScaledFeedback != null) + { + VolumeLevelScaledFeedback.FireUpdate(); + } + } + + public void GetVolumeMax() + { + MaxLevel = (short)Mixer.MaxVolumeFeedback.UShortValue; + if (VolumeLevelScaledFeedback != null) + { + VolumeLevelScaledFeedback.FireUpdate(); + } } } public class DmpsAudioOutput : IBasicVolumeWithFeedback { - Card.Dmps3OutputBase Output; - eDmpsLevelType Type; - UShortInputSig Level; - - public short MinLevel { get; private set; } - public short MaxLevel { get; private set; } - - public CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer { get; set; } + Card.Dmps3OutputBase Output; + eDmpsLevelType Type; + UShortInputSig Level; + + protected short MinLevel { get; set; } + protected short MaxLevel { get; set; } + public BoolFeedback MuteFeedback { get; private set; } - public IntFeedback VolumeLevelFeedback { get; private set; } + public IntFeedback VolumeLevelFeedback { get; private set; } public IntFeedback VolumeLevelScaledFeedback { get; private set; } Action MuteOnAction; Action MuteOffAction; Action VolumeUpAction; Action VolumeDownAction; - + public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) { Output = output; - Type = type; - MinLevel = -800; + Type = type; + MinLevel = -800; MaxLevel = 100; switch (type) @@ -267,13 +297,12 @@ namespace PepperDash.Essentials.DM { Level = output.MasterVolume; - MuteFeedback = new BoolFeedback( new Func (() => Output.MasterMuteOnFeedBack.BoolValue)); + 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: @@ -363,56 +392,30 @@ namespace PepperDash.Essentials.DM } break; } - } - if (VolumeLevelFeedback != null) - { - VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); } - } - - public void SetVolumeScaled(ushort level) - { - Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); - Level.UShortValue = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); - } - - public ushort ScaleVolumeFeedback(ushort level) - { - short signedLevel = (short)level; - Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString()); - return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); - } - - public void GetVolumeMin() - { - if (Mixer != null) - { - MinLevel = (short)Mixer.MinVolumeFeedback.UShortValue; - Debug.Console(2, Debug.ErrorLogLevel.None, "DMPS set {0} min level:{1}", Output.Name, MinLevel); - if (VolumeLevelScaledFeedback != null) - { - VolumeLevelScaledFeedback.FireUpdate(); - } - } - } - - public void GetVolumeMax() - { - if (Mixer != null) - { - MaxLevel = (short)Mixer.MaxVolumeFeedback.UShortValue; - Debug.Console(2, Debug.ErrorLogLevel.None, "DMPS set {0} max level:{1}", Output.Name, MaxLevel); - if (VolumeLevelScaledFeedback != null) - { - VolumeLevelScaledFeedback.FireUpdate(); - } - } + if (VolumeLevelFeedback != null) + { + VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + } + } + + public void SetVolumeScaled(ushort level) + { + Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); + Level.UShortValue = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); + } + + public ushort ScaleVolumeFeedback(ushort level) + { + short signedLevel = (short)level; + Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString()); + return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); } #region IBasicVolumeWithFeedback Members public void SetVolume(ushort level) - { + { Level.UShortValue = level; } From 313b336d56eb92bd78c3f254b5f8368b0189d473 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Thu, 7 Oct 2021 09:48:02 -0600 Subject: [PATCH 410/480] fix(Devices_Common): Clear meeting list and fire event if no meetings are scheduled --- .../VideoCodec/VideoCodecBase.cs | 17 +++++++++++++++++ .../VideoCodec/ZoomRoom/ZoomRoom.cs | 15 ++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) 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 26ed54bb..2549bea0 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 @@ -298,6 +298,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } LinkVideoCodecToApi(codec, trilist, joinMap); + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + }; } /// @@ -785,6 +792,16 @@ ScreenIndexIsPinnedTo: {8} (a{17}) _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); + if (_currentMeetings.Count == 0) + { + var emptyXSigByteArray = XSigHelpers.ClearOutputs(); + var emptyXSigString = Encoding.GetEncoding(XSigEncoding) + .GetString(emptyXSigByteArray, 0, emptyXSigByteArray.Length); + + trilist.SetString(joinMap.Schedule.JoinNumber, emptyXSigString); + return; + } + var meetingsData = UpdateMeetingsListXSig(_currentMeetings); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 32a24a28..a43ea79c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1306,11 +1306,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var codecBookings = JsonConvert.DeserializeObject>( responseObj.ToString()); - if (codecBookings != null && codecBookings.Count > 0) - { - CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( - codecBookings, CodecSchedule.MeetingWarningMinutes); - } + if (codecBookings != null && codecBookings.Count > 0) + { + CodecSchedule.Meetings = zCommand.GetGenericMeetingsFromBookingResult( + codecBookings, CodecSchedule.MeetingWarningMinutes); + } + else + { + //need to clear the list if it's empty + CodecSchedule.Meetings = new List(); + } break; } From 369bdf5c66302c928d1ab0089e552fc691539414 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 27 Oct 2021 12:25:29 -0400 Subject: [PATCH 411/480] Update video sync outputs at boot --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index f6f6be22..181bd621 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -205,6 +205,11 @@ namespace PepperDash.Essentials.DM Dmps.DMOutputChange += Dmps_DMOutputChange; Dmps.DMSystemChange += Dmps_DMSystemChange; + foreach (var input in VideoInputSyncFeedbacks) + { + input.Value.FireUpdate(); + } + return base.CustomActivate(); } @@ -832,18 +837,13 @@ namespace PepperDash.Essentials.DM } void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args) { - Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); + //Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); var output = args.Number; DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput; - if (args.EventId == DMOutputEventIds.VolumeEventId && - VolumeControls.ContainsKey(output)) - { - VolumeControls[args.Number].VolumeEventFromChassis(); - } - else if (args.EventId == DMOutputEventIds.OnlineFeedbackEventId + if (args.EventId == DMOutputEventIds.OnlineFeedbackEventId && OutputEndpointOnlineFeedbacks.ContainsKey(output)) { OutputEndpointOnlineFeedbacks[output].FireUpdate(); From e593f1c281f07135563e4c467598978db744bdae Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 27 Oct 2021 12:33:47 -0400 Subject: [PATCH 412/480] Forces video sync outputs to update at boot --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 9a8742a4..9c16bc1a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -205,6 +205,11 @@ namespace PepperDash.Essentials.DM Dmps.DMOutputChange += Dmps_DMOutputChange; Dmps.DMSystemChange += Dmps_DMSystemChange; + foreach (var input in VideoInputSyncFeedbacks) + { + input.Value.FireUpdate(); + } + return base.CustomActivate(); } @@ -832,7 +837,7 @@ namespace PepperDash.Essentials.DM } void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args) { - Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); + //Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); var output = args.Number; From 62bdddf4c1aed86a285e67ffae235240c5abcfbc Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 27 Oct 2021 16:53:37 -0400 Subject: [PATCH 413/480] More dmps work --- .../DmpsAudioOutputControllerJoinMap.cs | 4 ++ .../JoinMaps/DmpsRoutingControllerJoinMap.cs | 4 ++ .../Chassis/DmpsAudioOutputController.cs | 47 +++++++++++-------- .../Chassis/DmpsRoutingController.cs | 43 +++++++++++++++-- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index 30904638..adb06b24 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -29,6 +29,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete MasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata { Description = "Master Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("MasterVolumeLevelScaledSend")] + public JoinDataComplete MasterVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 }, + new JoinMetadata { Description = "Master Volume Scaled Send", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SourceVolumeLevel")] public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata { Description = "Source Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs index 80975338..7ed99c61 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -4,6 +4,10 @@ namespace PepperDash.Essentials.Core.Bridges { public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced { + [JoinName("EnableRouting")] + public JoinDataComplete EnableRouting = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "DMPS Enable Audio and Video Routing", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SystemPowerOn")] public JoinDataComplete SystemPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata { Description = "DMPS System Power On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 612ea45a..2dd0b423 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -43,8 +43,6 @@ namespace PepperDash.Essentials.DM MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); } else if (card is Card.Dmps3Aux1Output) { @@ -52,8 +50,6 @@ namespace PepperDash.Essentials.DM SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); } else if (card is Card.Dmps3Aux2Output) { @@ -61,8 +57,6 @@ namespace PepperDash.Essentials.DM SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMax(); - ((DmpsAudioOutputWithMixer)MasterVolumeLevel).GetVolumeMin(); } else //Digital Outputs { @@ -166,11 +160,6 @@ namespace PepperDash.Essentials.DM { var joinMap = new DmpsAudioOutputControllerJoinMap(joinStart); - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - if (bridge != null) { bridge.AddJoinMap(Key, joinMap); @@ -206,22 +195,19 @@ namespace PepperDash.Essentials.DM { SetUpDmpsAudioOutputJoins(trilist, Codec2VolumeLevel, joinMap.Codec2VolumeLevel.JoinNumber); } - } static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart) { var volumeLevelJoin = joinStart; - var volumeLevelScaledJoin = joinStart + 1; + var volumeLevelScaledJoin = joinStart + 1; var muteOnJoin = joinStart; var muteOffJoin = joinStart + 1; var volumeUpJoin = joinStart + 2; var volumeDownJoin = joinStart + 3; + var volumeLevelScaledSendJoin = joinStart + 4; - trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); - - trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); output.VolumeLevelScaledFeedback.LinkInputSig(trilist.UShortInput[volumeLevelScaledJoin]); trilist.SetSigTrueAction(muteOnJoin, output.MuteOn); @@ -231,9 +217,9 @@ namespace PepperDash.Essentials.DM trilist.SetBoolSigAction(volumeUpJoin, output.VolumeUp); trilist.SetBoolSigAction(volumeDownJoin, output.VolumeDown); - - trilist.OnlineStatusChange += (a, b) => output.VolumeLevelFeedback.FireUpdate(); - trilist.OnlineStatusChange += (a, b) => output.VolumeLevelScaledFeedback.FireUpdate(); + trilist.SetBoolSigAction(volumeLevelScaledJoin, output.SendScaledVolume); + trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); + trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); } } @@ -245,6 +231,8 @@ namespace PepperDash.Essentials.DM : base(output, type) { Mixer = mixer; + GetVolumeMax(); + GetVolumeMin(); } public void GetVolumeMin() @@ -272,6 +260,8 @@ namespace PepperDash.Essentials.DM eDmpsLevelType Type; UShortInputSig Level; + private bool VolumeLevelScaledSend; + private ushort VolumeLevelScaled; protected short MinLevel { get; set; } protected short MaxLevel { get; set; } @@ -287,6 +277,8 @@ namespace PepperDash.Essentials.DM public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) { Output = output; + VolumeLevelScaled = 0; + VolumeLevelScaledSend = false; Type = type; MinLevel = -800; MaxLevel = 100; @@ -396,13 +388,19 @@ namespace PepperDash.Essentials.DM if (VolumeLevelFeedback != null) { VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + VolumeLevelFeedback.FireUpdate(); + VolumeLevelScaledFeedback.FireUpdate(); } } public void SetVolumeScaled(ushort level) { Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); - Level.UShortValue = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); + VolumeLevelScaled = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); + if (VolumeLevelScaledSend == true) + { + Level.UShortValue = VolumeLevelScaled; + } } public ushort ScaleVolumeFeedback(ushort level) @@ -412,6 +410,15 @@ namespace PepperDash.Essentials.DM return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); } + public void SendScaledVolume(bool pressRelease) + { + VolumeLevelScaledSend = pressRelease; + if(pressRelease == false) + { + Level.UShortValue = VolumeLevelScaled; + } + } + #region IBasicVolumeWithFeedback Members public void SetVolume(ushort level) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 181bd621..35c83f2c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -25,6 +25,7 @@ namespace PepperDash.Essentials.DM public CrestronControlSystem Dmps { get; set; } public ISystemControl SystemControl { get; private set; } + public bool? EnableRouting { get; private set; } //Check if DMPS is a DMPS3-4K type for endpoint creation public bool Dmps4kType { get; private set; } @@ -204,10 +205,26 @@ namespace PepperDash.Essentials.DM Dmps.DMInputChange += Dmps_DMInputChange; Dmps.DMOutputChange += Dmps_DMOutputChange; Dmps.DMSystemChange += Dmps_DMSystemChange; - - foreach (var input in VideoInputSyncFeedbacks) + + foreach (var x in VideoOutputFeedbacks) { - input.Value.FireUpdate(); + x.Value.FireUpdate(); + } + foreach (var x in AudioOutputFeedbacks) + { + x.Value.FireUpdate(); + } + foreach (var x in VideoInputSyncFeedbacks) + { + x.Value.FireUpdate(); + } + foreach (var x in InputEndpointOnlineFeedbacks) + { + x.Value.FireUpdate(); + } + foreach (var x in OutputEndpointOnlineFeedbacks) + { + x.Value.FireUpdate(); } return base.CustomActivate(); @@ -246,6 +263,12 @@ namespace PepperDash.Essentials.DM } } + public void SetRoutingEnable(bool enable) + { + CrestronEnvironment.Sleep(1000); + EnableRouting = enable; + } + public void SetPowerOn(bool a) { if (SystemControl is Dmps3SystemControl) @@ -296,6 +319,8 @@ namespace PepperDash.Essentials.DM trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]); } + trilist.SetBoolSigAction(joinMap.EnableRouting.JoinNumber, SetRoutingEnable); + // Link up outputs LinkInputsToApi(trilist, joinMap); LinkOutputsToApi(trilist, joinMap); @@ -837,13 +862,17 @@ namespace PepperDash.Essentials.DM } void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args) { - //Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); + Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); var output = args.Number; DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput; - if (args.EventId == DMOutputEventIds.OnlineFeedbackEventId + if (args.EventId == DMOutputEventIds.VolumeEventId && VolumeControls.ContainsKey(output)) + { + VolumeControls[args.Number].VolumeEventFromChassis(); + } + else if (args.EventId == DMOutputEventIds.OnlineFeedbackEventId && OutputEndpointOnlineFeedbacks.ContainsKey(output)) { OutputEndpointOnlineFeedbacks[output].FireUpdate(); @@ -933,6 +962,10 @@ namespace PepperDash.Essentials.DM { try { + if (EnableRouting == false) + { + return; + } Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType); From 39e85d53114ac39524d6043d6671183d83c2c442 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 28 Oct 2021 08:56:44 -0400 Subject: [PATCH 414/480] Builds out the rest of the dmps scaled volume inputs --- .../DmpsAudioOutputControllerJoinMap.cs | 18 +++++++++++- .../Chassis/DmpsAudioOutputController.cs | 28 +++++++++---------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index adb06b24..2da94bb0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core.Bridges [JoinName("MasterVolumeLevelScaledSend")] public JoinDataComplete MasterVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 }, - new JoinMetadata { Description = "Master Volume Scaled Send", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + new JoinMetadata { Description = "Master Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); [JoinName("SourceVolumeLevel")] public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, @@ -57,6 +57,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete SourceVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, new JoinMetadata { Description = "Source Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("SourceVolumeLevelScaledSend")] + public JoinDataComplete SourceVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata { Description = "Source Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("Codec1VolumeLevel")] public JoinDataComplete Codec1VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata { Description = "Codec1 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); @@ -81,6 +85,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete Codec1VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 }, new JoinMetadata { Description = "Codec1 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("Codec1VolumeLevelScaledSend")] + public JoinDataComplete Codec1VolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 25, JoinSpan = 1 }, + new JoinMetadata { Description = "Codec1 Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("Codec2VolumeLevel")] public JoinDataComplete Codec2VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 }, new JoinMetadata { Description = "Codec2 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); @@ -105,6 +113,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete Codec2VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 }, new JoinMetadata { Description = "Codec2 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("Codec2VolumeLevelScaledSend")] + public JoinDataComplete Codec2VolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 35, JoinSpan = 1 }, + new JoinMetadata { Description = "Codec2 Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("MicsMasterVolumeLevel")] public JoinDataComplete MicsMasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 }, new JoinMetadata { Description = "MicsMaster Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); @@ -129,6 +141,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete MicsMasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 44, JoinSpan = 1 }, new JoinMetadata { Description = "MicsMaster Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("MicsMasterVolumeLevelScaledSend")] + public JoinDataComplete MicsMasterVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 45, JoinSpan = 1 }, + new JoinMetadata { Description = "Mics Master Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + /// /// Constructor to use when instantiating this Join Map without inheriting from it /// diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 2dd0b423..c2cd741f 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -68,6 +68,7 @@ namespace PepperDash.Essentials.DM void BaseDevice_DMOutputChange(Switch device, DMOutputEventArgs args) { + Debug.Console(2, this, "Dmps Audio Controller Event Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); switch (args.EventId) { case DMOutputEventIds.MasterVolumeFeedBackEventId: @@ -205,7 +206,7 @@ namespace PepperDash.Essentials.DM var muteOffJoin = joinStart + 1; var volumeUpJoin = joinStart + 2; var volumeDownJoin = joinStart + 3; - var volumeLevelScaledSendJoin = joinStart + 4; + var sendScaledVolumeJoin = joinStart + 4; output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]); output.VolumeLevelScaledFeedback.LinkInputSig(trilist.UShortInput[volumeLevelScaledJoin]); @@ -217,7 +218,7 @@ namespace PepperDash.Essentials.DM trilist.SetBoolSigAction(volumeUpJoin, output.VolumeUp); trilist.SetBoolSigAction(volumeDownJoin, output.VolumeDown); - trilist.SetBoolSigAction(volumeLevelScaledJoin, output.SendScaledVolume); + trilist.SetBoolSigAction(sendScaledVolumeJoin, output.SendScaledVolume); trilist.SetUShortSigAction(volumeLevelJoin, output.SetVolume); trilist.SetUShortSigAction(volumeLevelScaledJoin, output.SetVolumeScaled); } @@ -260,8 +261,8 @@ namespace PepperDash.Essentials.DM eDmpsLevelType Type; UShortInputSig Level; - private bool VolumeLevelScaledSend; - private ushort VolumeLevelScaled; + private bool EnableVolumeSend; + private ushort VolumeLevelInput; protected short MinLevel { get; set; } protected short MaxLevel { get; set; } @@ -277,8 +278,8 @@ namespace PepperDash.Essentials.DM public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) { Output = output; - VolumeLevelScaled = 0; - VolumeLevelScaledSend = false; + VolumeLevelInput = 0; + EnableVolumeSend = false; Type = type; MinLevel = -800; MaxLevel = 100; @@ -307,7 +308,6 @@ namespace PepperDash.Essentials.DM 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: @@ -336,7 +336,6 @@ namespace PepperDash.Essentials.DM MuteOffAction = new Action(programOutput.Codec1MuteOff); VolumeUpAction = new Action((b) => programOutput.Codec1LevelUp.BoolValue = b); VolumeDownAction = new Action((b) => programOutput.Codec1LevelDown.BoolValue = b); - } else { @@ -367,7 +366,6 @@ namespace PepperDash.Essentials.DM MuteOffAction = new Action(programOutput.Codec2MuteOff); VolumeUpAction = new Action((b) => programOutput.Codec2LevelUp.BoolValue = b); VolumeDownAction = new Action((b) => programOutput.Codec2LevelDown.BoolValue = b); - } else { @@ -396,10 +394,10 @@ namespace PepperDash.Essentials.DM public void SetVolumeScaled(ushort level) { Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); - VolumeLevelScaled = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); - if (VolumeLevelScaledSend == true) + VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); + if (EnableVolumeSend == true) { - Level.UShortValue = VolumeLevelScaled; + Level.UShortValue = VolumeLevelInput; } } @@ -412,10 +410,10 @@ namespace PepperDash.Essentials.DM public void SendScaledVolume(bool pressRelease) { - VolumeLevelScaledSend = pressRelease; - if(pressRelease == false) + EnableVolumeSend = pressRelease; + if (pressRelease == false) { - Level.UShortValue = VolumeLevelScaled; + SetVolumeScaled(VolumeLevelInput); } } From 3de2ba03c1b75a7e02978f11a8828480f76a3b55 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 29 Oct 2021 17:05:36 -0500 Subject: [PATCH 415/480] feat: Added configuration for US and PIR sensitivity values from configuration. Add public method to set identity mode on/off for debugging and identifying remotely. --- .../CenOdtOccupancySensorBaseController.cs | 89 ++++++++++++++++++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index dcf0b193..cee156bc 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Resources; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.DeviceSupport; @@ -199,6 +200,27 @@ namespace PepperDash.Essentials.Core { SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState); } + + // TODO [ ] feature/cenoodtcpoe-sensor-sensitivity-configuration + if (PropertiesConfig.UsSensitivityOccupied != null) + { + SetUsSensitivityOccupied((ushort)PropertiesConfig.UsSensitivityOccupied); + } + + if (PropertiesConfig.UsSensitivityVacant != null) + { + SetUsSensitivityVacant((ushort)PropertiesConfig.UsSensitivityVacant); + } + + if (PropertiesConfig.PirSensitivityOccupied != null) + { + SetPirSensitivityOccupied((ushort)PropertiesConfig.PirSensitivityOccupied); + } + + if (PropertiesConfig.PirSensitivityVacant != null) + { + SetPirSensitivityVacant((ushort)PropertiesConfig.PirSensitivityVacant); + } } /// @@ -279,7 +301,21 @@ namespace PepperDash.Essentials.Core } } - /// + /// + /// Sets the identity mode on or off + /// + /// + public void SetIdentityMode(bool state) + { + if (state) + OccSensor.IdentityModeOn(); + else + OccSensor.IdentityModeOff(); + + Debug.Console(1, this, "Identity Mode: {0}", OccSensor.IdentityModeOnFeedback.BoolValue ? "On" : "Off"); + } + + /// /// Enables or disables the PIR sensor /// /// @@ -506,6 +542,54 @@ namespace PepperDash.Essentials.Core } } + /// + /// Sets the US sensor sensitivity for occupied state + /// + /// + public void SetUsSensitivityOccupied(ushort sensitivity) + { + var level = (eSensitivityLevel) sensitivity; + if (level == 0) return; + + OccSensor.UltrasonicSensorSensitivityInOccupiedState = level; + } + + /// + /// Sets the US sensor sensitivity for vacant state + /// + /// + public void SetUsSensitivityVacant(ushort sensitivity) + { + var level = (eSensitivityLevel)sensitivity; + if (level == 0) return; + + OccSensor.UltrasonicSensorSensitivityInVacantState = level; + } + + /// + /// Sets the PIR sensor sensitivity for occupied state + /// + /// + public void SetPirSensitivityOccupied(ushort sensitivity) + { + var level = (eSensitivityLevel)sensitivity; + if (level == 0) return; + + OccSensor.PassiveInfraredSensorSensitivityInOccupiedState = level; + } + + /// + /// Sets the PIR sensor sensitivity for vacant state + /// + /// + public void SetPirSensitivityVacant(ushort sensitivity) + { + var level = (eSensitivityLevel)sensitivity; + if (level == 0) return; + + OccSensor.PassiveInfraredSensorSensitivityInVacantState = level; + } + /// /// Method to print current settings to console /// @@ -647,8 +731,7 @@ namespace PepperDash.Essentials.Core //Sensor Raw States occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); - occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); - + occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); } public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory From 7dabe161a7007c9c219312ea416ffc0d3167e010 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Fri, 29 Oct 2021 17:22:41 -0500 Subject: [PATCH 416/480] feat: Updated CenOdtOccupancySensorBaseJoinMap.cs with joins for IdentityMode and IdentityModeFeedback. feat: Updated CentOdtOccupancySensorBaseController.cs to bridge SetIdentityMode method and feedback. --- .../JoinMaps/CenOdtOccupancySensorBaseJoinMap.cs | 8 ++++++++ .../Occupancy/CenOdtOccupancySensorBaseController.cs | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CenOdtOccupancySensorBaseJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CenOdtOccupancySensorBaseJoinMap.cs index 4e731f41..63684837 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CenOdtOccupancySensorBaseJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/CenOdtOccupancySensorBaseJoinMap.cs @@ -46,6 +46,14 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete RawOccupancyUsFeedback = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata { Description = "Raw Occupancy Us Feedback", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("IdentityModeOn")] + public JoinDataComplete IdentityMode = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 }, + new JoinMetadata { Description = "Enable Identity Mode", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("IdentityModeFeedback")] + public JoinDataComplete IdentityModeFeedback = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 }, + new JoinMetadata { Description = "Identity Mode Feedback", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); + [JoinName("EnableLedFlash")] public JoinDataComplete EnableLedFlash = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata { Description = "Enable Led Flash", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs index cee156bc..eae2f993 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/CenOdtOccupancySensorBaseController.cs @@ -62,6 +62,8 @@ namespace PepperDash.Essentials.Core public BoolFeedback RawOccupancyUsFeedback { get; private set; } + public BoolFeedback IdentityModeFeedback { get; private set; } + // Debug properties public bool InTestMode { get; private set; } @@ -118,6 +120,8 @@ namespace PepperDash.Essentials.Core RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyDetectedByUltrasonicSensorFeedback.BoolValue); + IdentityModeFeedback = new BoolFeedback(()=>OccSensor.IdentityModeOnFeedback.BoolValue); + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInVacantStateFeedback); UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => (int)OccSensor.UltrasonicSensorSensitivityInOccupiedStateFeedback); @@ -731,7 +735,11 @@ namespace PepperDash.Essentials.Core //Sensor Raw States occController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]); - occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); + occController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]); + + // Identity mode + trilist.SetBoolSigAction(joinMap.IdentityMode.JoinNumber, occController.SetIdentityMode); + occController.IdentityModeFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IdentityModeFeedback.JoinNumber]); } public class CenOdtOccupancySensorBaseControllerFactory : EssentialsDeviceFactory From b34310188653d3606ad096b133516f02feba4122 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 1 Nov 2021 10:05:30 -0500 Subject: [PATCH 417/480] fix: Updated spelling error in occupancy sensor properties config for new sensitivity properties. --- .../Occupancy/GlsOccupancySensorPropertiesConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs index 1725909c..392c05b0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Occupancy/GlsOccupancySensorPropertiesConfig.cs @@ -75,7 +75,7 @@ namespace PepperDash.Essentials.Core /// Sets the sensitivity level for PIR while sensor is in vacant state /// 1 = low; 2 = medium; 3 = high /// - [JsonProperty("PirSensitivityVacant")] + [JsonProperty("pirSensitivityVacant")] public ushort? PirSensitivityVacant { get; set; } } } \ No newline at end of file From cd186aa3a30d1d81dceec54f32151604186ba8f3 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 2 Nov 2021 09:16:34 -0500 Subject: [PATCH 418/480] feat: Added GlsPartitionSensorConfig.cs. feat: Updated GlsParitionSensorController.cs to addd the ability to set sensitivity via config. chore: Updated GlsPartitionSensorJoinMap.cs to organize signals by type for readability. --- .../JoinMaps/GlsPartitionSensorJoinMap.cs | 46 ++++--- .../GlsPartitionSensorController.cs | 113 ++++++++++++++---- .../GlsPartitionSensorPropertiesConfig.cs | 21 ++++ .../PepperDash_Essentials_Core.csproj | 1 + 4 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs index 3854a4fb..5a583d69 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GlsPartitionSensorJoinMap.cs @@ -5,6 +5,9 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps { public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced { + + #region Digital + [JoinName("IsOnline")] public JoinDataComplete IsOnline = new JoinDataComplete( new JoinData @@ -19,20 +22,7 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Digital }); - [JoinName("Name")] - public JoinDataComplete Name = new JoinDataComplete( - new JoinData - { - JoinNumber = 1, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sensor Name", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Serial - }); - + [JoinName("Enable")] public JoinDataComplete Enable = new JoinDataComplete( new JoinData @@ -101,7 +91,11 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps Description = "Sensor Decrease Sensitivity", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital - }); + }); + + #endregion + + #region Analog [JoinName("Sensitivity")] public JoinDataComplete Sensitivity = new JoinDataComplete( @@ -117,6 +111,28 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps JoinType = eJoinType.Analog }); + #endregion + + + #region Serial + + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete( + new JoinData + { + JoinNumber = 1, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sensor Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + #endregion + + /// /// Constructor to use when instantiating this Join Map without inheriting from it /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs index 5f40bf7e..16b2f265 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs @@ -1,4 +1,5 @@ -using Crestron.SimplSharpPro; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.GeneralIO; using Newtonsoft.Json; @@ -9,15 +10,18 @@ using PepperDash.Essentials.Core.Bridges.JoinMaps; using System; using System.Collections.Generic; using PepperDash.Essentials.Core.Config; +using PepperDash_Essentials_Core.PartitionSensor; namespace PepperDash.Essentials.Core { [Description("Wrapper class for GLS Cresnet Partition Sensor")] public class GlsPartitionSensorController : CrestronGenericBridgeableBaseDevice, IPartitionStateProvider { - private GlsPartCn _partitionSensor; - public StringFeedback NameFeedback { get; private set; } + public GlsPartitionSensorPropertiesConfig PropertiesConfig { get; private set; } + + private GlsPartCn _partitionSensor; + public BoolFeedback EnableFeedback { get; private set; } public BoolFeedback PartitionPresentFeedback { get; private set; } public BoolFeedback PartitionNotSensedFeedback { get; private set; } @@ -32,23 +36,71 @@ namespace PepperDash.Essentials.Core public GlsPartitionSensorController(string key, Func preActivationFunc, DeviceConfig config) : base(key, config.Name) { + + var props = config.Properties.ToObject(); + if (props != null) + { + PropertiesConfig = props; + } + else + { + Debug.Console(1, this, "props are null. Unable to deserialize into GlsPartSensorPropertiesConfig"); + } + AddPreActivationAction(() => { _partitionSensor = preActivationFunc(config); - + RegisterCrestronGenericBase(_partitionSensor); - - NameFeedback = new StringFeedback(() => Name); + EnableFeedback = new BoolFeedback(() => InTestMode ? TestEnableFeedback : _partitionSensor.EnableFeedback.BoolValue); PartitionPresentFeedback = new BoolFeedback(() => InTestMode ? TestPartitionSensedFeedback : _partitionSensor.PartitionSensedFeedback.BoolValue); PartitionNotSensedFeedback = new BoolFeedback(() => InTestMode ? !TestPartitionSensedFeedback : _partitionSensor.PartitionNotSensedFeedback.BoolValue); SensitivityFeedback = new IntFeedback(() => InTestMode ? TestSensitivityFeedback : _partitionSensor.SensitivityFeedback.UShortValue); - if (_partitionSensor != null) _partitionSensor.BaseEvent += PartitionSensor_BaseEvent; + if (_partitionSensor != null) + { + _partitionSensor.BaseEvent += PartitionSensor_BaseEvent; + } }); - } - private void PartitionSensor_BaseEvent(GenericBase device, BaseEventArgs args) + AddPostActivationAction(() => + { + _partitionSensor.OnlineStatusChange += (o, a) => + { + if (a.DeviceOnLine) + { + ApplySettingsToSensorFromConfig(); + } + }; + + if (_partitionSensor.IsOnline) + { + ApplySettingsToSensorFromConfig(); + } + }); + } + + private void ApplySettingsToSensorFromConfig() + { + if (_partitionSensor.IsOnline == false) return; + + Debug.Console(1, this, "Attempting to apply settings to sensor from config"); + + if (PropertiesConfig.Sensitivity != null) + { + Debug.Console(1, this, "Sensitivity found, attempting to set value '{0}' from config", + PropertiesConfig.Sensitivity); + _partitionSensor.Sensitivity.UShortValue = (ushort) PropertiesConfig.Sensitivity; + } + else + { + Debug.Console(1, this, "Sensitivity null, no value specified in config"); + } + + } + + private void PartitionSensor_BaseEvent(GenericBase device, BaseEventArgs args) { Debug.Console(2, this, "EventId: {0}, Index: {1}", args.EventId, args.Index); @@ -61,11 +113,13 @@ namespace PepperDash.Essentials.Core } case (GlsPartCn.PartitionSensedFeedbackEventId): { + Debug.Console(1, this, "Partition Sensed State: {0}", _partitionSensor.PartitionSensedFeedback.BoolValue); PartitionPresentFeedback.FireUpdate(); break; } case (GlsPartCn.PartitionNotSensedFeedbackEventId): { + Debug.Console(1, this, "Partition Not Sensed State: {0}", _partitionSensor.PartitionNotSensedFeedback.BoolValue); PartitionNotSensedFeedback.FireUpdate(); break; } @@ -73,7 +127,7 @@ namespace PepperDash.Essentials.Core { SensitivityFeedback.FireUpdate(); break; - } + } default: { Debug.Console(2, this, "Unhandled args.EventId: {0}", args.EventId); @@ -133,7 +187,22 @@ namespace PepperDash.Essentials.Core Debug.Console(1, this, "InTestMode: {0}, unable to set sensitivity value: {1}", InTestMode.ToString(), value); } - public void SetEnableState(bool state) + public void GetSettings() + { + var dash = new string('*', 50); + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + + Debug.Console(0, this, "Enabled State: {0}", _partitionSensor.EnableFeedback.BoolValue); + + Debug.Console(0, this, "Partition Sensed State: {0}", _partitionSensor.PartitionSensedFeedback.BoolValue); + Debug.Console(0, this, "Partition Not Sensed State: {0}", _partitionSensor.PartitionNotSensedFeedback.BoolValue); + + Debug.Console(0, this, "Sensitivity Value: {0}", _partitionSensor.SensitivityFeedback.UShortValue); + + CrestronConsole.PrintLine(string.Format("{0}\n", dash)); + } + + public void SetEnableState(bool state) { Debug.Console(2, this, "Sensor is {0}, SetEnableState: {1}", _partitionSensor == null ? "null" : "not null", state); if (_partitionSensor == null) @@ -189,18 +258,20 @@ namespace PepperDash.Essentials.Core Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); Debug.Console(0, this, "Linking to Bridge Type {0}", GetType().Name); - // link input from simpl + IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = _partitionSensor.Name; + trilist.SetBoolSigAction(joinMap.Enable.JoinNumber, SetEnableState); + EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]); + + PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]); + PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]); + trilist.SetSigTrueAction(joinMap.IncreaseSensitivity.JoinNumber, IncreaseSensitivity); trilist.SetSigTrueAction(joinMap.DecreaseSensitivity.JoinNumber, DecreaseSensitivity); - trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity); - // link output to simpl - IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - EnableFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Enable.JoinNumber]); - PartitionPresentFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionSensed.JoinNumber]); - PartitionNotSensedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PartitionNotSensed.JoinNumber]); - SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]); + SensitivityFeedback.LinkInputSig(trilist.UShortInput[joinMap.Sensitivity.JoinNumber]); + trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity); FeedbacksFireUpdates(); @@ -218,6 +289,7 @@ namespace PepperDash.Essentials.Core { if (a.DeviceOnLine) { + trilist.StringInput[joinMap.Name.JoinNumber].StringValue = _partitionSensor.Name; FeedbacksFireUpdates(); } }; @@ -225,8 +297,7 @@ namespace PepperDash.Essentials.Core private void FeedbacksFireUpdates() { - IsOnline.FireUpdate(); - NameFeedback.FireUpdate(); + IsOnline.FireUpdate(); EnableFeedback.FireUpdate(); PartitionPresentFeedback.FireUpdate(); PartitionNotSensedFeedback.FireUpdate(); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs new file mode 100644 index 00000000..8a303662 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Newtonsoft.Json; + +namespace PepperDash_Essentials_Core.PartitionSensor +{ + public class GlsPartitionSensorPropertiesConfig + { + /// + /// Sets the sensor sensitivity + /// + /// + /// The sensitivity range shall be between 1(lowest) to 10 (highest). + /// + [JsonProperty("sensitivity")] + public ushort? Sensitivity { get; set; } + } +} \ 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 abd7c498..752466d4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -236,6 +236,7 @@ + From 8087aa7a755aaf70702e9cfcdd518789d3d4b4b7 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 3 Nov 2021 14:48:10 -0600 Subject: [PATCH 419/480] Adds more deliberate exception and logging for missing defaultAudioKey property value --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index f2b17526..42a4a353 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -214,17 +214,25 @@ namespace PepperDash.Essentials VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase; - + if (VideoCodec == null) - throw new ArgumentNullException("codec cannot be null"); - + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "No Video Codec set. Please check 'videoCodecKey' property in room config"); + throw new ArgumentNullException("VideoCodec cannot be null"); + } + AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase; if (AudioCodec == null) Debug.Console(0, this, "No Audio Codec Found"); DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls; + if (DefaultAudioDevice == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "No Default Audio Device set. Please check 'defaultAudioKey' property in room config"); + throw new ArgumentNullException("DefaultAudioDevice cannot be null"); + } InitializeRoom(); } From 536e82ef22060bcd1175108569c64bb4a484141e Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Nov 2021 16:11:26 -0600 Subject: [PATCH 420/480] feat(essentials): adds new features for ZoomRoom Adds IHasMeetingLock and adds new methods to IHasParticipants --- .../Essentials Devices Common.csproj | 1 + .../VideoCodec/Interfaces/IHasMeetingLock.cs | 18 +++ .../VideoCodec/Interfaces/IHasParticipants.cs | 17 +++ .../VideoCodec/ZoomRoom/ResponseObjects.cs | 20 +++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 107 +++++++++++++++++- 5 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingLock.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index fc5f68d4..a874838f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -121,6 +121,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingLock.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingLock.cs new file mode 100644 index 00000000..97fcb725 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingLock.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + public interface IHasMeetingLock + { + BoolFeedback MeetingIsLockedFeedback { get; } + + void LockMeeting(); + void UnLockMeeting(); + void ToggleMeetingLock(); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index 409ccd89..776c91d3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -12,6 +12,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public interface IHasParticipants { CodecParticipants Participants { get; } + + /// + /// Removes the participant from the meeting + /// + /// + void RemoveParticipant(Participant participant); + + /// + /// Sets the participant as the new host + /// + /// + void SetParticipantAsHost(Participant participant); } /// @@ -29,6 +41,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public interface IHasParticipantAudioMute : IHasParticipantVideoMute { + /// + /// Mute audio of all participants + /// + void MuteAudioForAllParticipants(); + void MuteAudioForParticipant(int userId); void UnmuteAudioForParticipant(int userId); void ToggleAudioForParticipant(int userId); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index e6efd063..870b5faf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -1123,9 +1123,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } - public class Lock + public class Lock : NotifiableObject { - public bool Enable { get; set; } + private bool _enable; + + public bool Enable + { + get + { + return _enable; + } + set + { + if (value != _enable) + { + _enable = value; + NotifyPropertyChanged("Enable"); + } + } + } } public class ClosedCaption diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a43ea79c..3b1d294d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -26,7 +26,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting, IHasMeetingLock { private const long MeetingRefreshTimer = 60000; public uint DefaultMeetingDurationMin { get; private set; } @@ -147,6 +147,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc); NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); + + MeetingIsLockedFeedback = new BoolFeedback(() => Configuration.Call.Lock.Enable ); } public CommunicationGather PortGather { get; private set; } @@ -597,6 +599,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }; + Configuration.Call.Lock.PropertyChanged += (o, a) => + { + if (a.PropertyName == "Enable") + { + MeetingIsLockedFeedback.FireUpdate(); + } + }; + // This is to deal with incorrect object structure coming back from the Zoom Room on v 5.6.3 Configuration.Client.Call.Layout.PropertyChanged += (o, a) => { @@ -2334,6 +2344,56 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } + /// + /// Invites contacts to a new meeting for a specified duration + /// + /// + /// + public void InviteContactsToNewMeeting(InvitableDirectoryContact[] contacts, uint duration) + { + if(duration == 0) + { + duration = DefaultMeetingDurationMin; + } + + StringBuilder message = new StringBuilder(); + + // Add the prefix + message.Append(string.Format("zCommand Invite Duration: {0}", duration)); + + // Add each invitee + foreach (var contact in contacts) + { + var invitee = string.Format(" user: {0}", contact.ContactId); + + message.Append(invitee); + } + + SendText(message.ToString()); + } + + /// + /// Invites contacts to an existing meeting + /// + /// + public void InviteContactsToExistingMeeting(InvitableDirectoryContact[] contacts) + { + StringBuilder message = new StringBuilder(); + + // Add the prefix + message.Append(string.Format("zCommand Call Invite")); + + // Add each invitee + foreach (var contact in contacts) + { + var invitee = string.Format(" user: {0}", contact.ContactId); + + message.Append(invitee); + } + + SendText(message.ToString()); + } + /// /// Starts a PMI Meeting for the specified duration (or default meeting duration if 0 is specified) @@ -2469,10 +2529,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public CodecParticipants Participants { get; private set; } + public void RemoveParticipant(Participant participant) + { + SendText(string.Format("zCommand Call Expel Id: {0}", participant.UserId)); + } + + public void SetParticipantAsHost(Participant participant) + { + SendText(string.Format("zCommand Call HostChange Id: {0}", participant.UserId)); + } + #endregion #region IHasParticipantAudioMute Members + public void MuteAudioForAllParticipants() + { + SendText(string.Format("zCommand Call MuteAll Mute: on")); + } + public void MuteAudioForParticipant(int userId) { SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId)); @@ -3034,7 +3109,35 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion - } + + #region IHasMeetingLock Members + + public BoolFeedback MeetingIsLockedFeedback { get; private set; } + + public void LockMeeting() + { + SendText(string.Format("zConfiguration Call Lock Enable: on")); + } + + public void UnLockMeeting() + { + SendText(string.Format("zConfiguration Call Lock Enable: off")); + } + + public void ToggleMeetingLock() + { + if (MeetingIsLockedFeedback.BoolValue) + { + UnLockMeeting(); + } + else + { + LockMeeting(); + } + } + + #endregion + } /// /// Zoom Room specific info object From 59bfa354e4fc3224fc69d7cf3bc1410c82029ca4 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Nov 2021 16:15:59 -0600 Subject: [PATCH 421/480] feat(essentials): switches to userId argument --- .../VideoCodec/Interfaces/IHasParticipants.cs | 4 ++-- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs index 776c91d3..11c5f147 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasParticipants.cs @@ -17,13 +17,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// Removes the participant from the meeting /// /// - void RemoveParticipant(Participant participant); + void RemoveParticipant(int userId); /// /// Sets the participant as the new host /// /// - void SetParticipantAsHost(Participant participant); + void SetParticipantAsHost(int userId); } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 3b1d294d..5cfb4f0e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2529,14 +2529,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public CodecParticipants Participants { get; private set; } - public void RemoveParticipant(Participant participant) + public void RemoveParticipant(int userId) { - SendText(string.Format("zCommand Call Expel Id: {0}", participant.UserId)); + SendText(string.Format("zCommand Call Expel Id: {0}", userId)); } - public void SetParticipantAsHost(Participant participant) + public void SetParticipantAsHost(int userId) { - SendText(string.Format("zCommand Call HostChange Id: {0}", participant.UserId)); + SendText(string.Format("zCommand Call HostChange Id: {0}", userId)); } #endregion From 11ffc5130f1d39e7af3ed37651770f7713b0714a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Nov 2021 16:47:05 -0600 Subject: [PATCH 422/480] feat(essentials): switches from array to list type in arguments --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 5cfb4f0e..a988d8c0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2349,7 +2349,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// /// /// - public void InviteContactsToNewMeeting(InvitableDirectoryContact[] contacts, uint duration) + public void InviteContactsToNewMeeting(List contacts, uint duration) { if(duration == 0) { @@ -2376,7 +2376,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom /// Invites contacts to an existing meeting /// /// - public void InviteContactsToExistingMeeting(InvitableDirectoryContact[] contacts) + public void InviteContactsToExistingMeeting(List contacts) { StringBuilder message = new StringBuilder(); From 31f976d7197d0844259dbc2fcd2a79ab73596101 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 4 Nov 2021 17:08:51 -0600 Subject: [PATCH 423/480] feat(essentials): adds IHasMeetingRecording and implements on ZoomRoom --- .../Essentials Devices Common.csproj | 1 + .../Interfaces/IHasMeetingRecording.cs | 18 ++++++++ .../VideoCodec/ZoomRoom/ResponseObjects.cs | 21 +++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 41 ++++++++++++++++++- 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingRecording.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index a874838f..5a1a501b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -122,6 +122,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingRecording.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingRecording.cs new file mode 100644 index 00000000..771a0865 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingRecording.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces +{ + public interface IHasMeetingRecording + { + BoolFeedback MeetingIsRecordingFeedback { get; } + + void StartRecording(); + void StopRecording(); + void ToggleRecording(); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 870b5faf..3b6066d1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -744,12 +744,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } } - public class CallRecordInfo + public class CallRecordInfo : NotifiableObject { + private bool _meetingIsBeingRecorded; + public bool canRecord { get; set; } public bool emailRequired { get; set; } public bool amIRecording { get; set; } - public bool meetingIsBeingRecorded { get; set; } + + public bool meetingIsBeingRecorded + { + get + { + return _meetingIsBeingRecorded; + } + set + { + if (value != _meetingIsBeingRecorded) + { + _meetingIsBeingRecorded = value; + NotifyPropertyChanged("meetingIsBeingRecorded"); + } + } + } } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index a988d8c0..f556fa94 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -26,7 +26,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom IRouting, IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode, IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts, IHasParticipantPinUnpin, - IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting, IHasMeetingLock + IHasParticipantAudioMute, IHasSelfviewSize, IPasswordPrompt, IHasStartMeeting, IHasMeetingInfo, IHasPresentationOnlyMeeting, + IHasMeetingLock, IHasMeetingRecording { private const long MeetingRefreshTimer = 60000; public uint DefaultMeetingDurationMin { get; private set; } @@ -149,6 +150,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc); MeetingIsLockedFeedback = new BoolFeedback(() => Configuration.Call.Lock.Enable ); + + MeetingIsRecordingFeedback = new BoolFeedback(() => Status.Call.CallRecordInfo.meetingIsBeingRecorded ); } public CommunicationGather PortGather { get; private set; } @@ -651,6 +654,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } }; + Status.Call.CallRecordInfo.PropertyChanged += (o, a) => + { + if (a.PropertyName == "meetingIsBeingRecorded") + { + MeetingIsRecordingFeedback.FireUpdate(); + } + }; + Status.Sharing.PropertyChanged += (o, a) => { switch (a.PropertyName) @@ -3137,6 +3148,34 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom } #endregion + + #region IHasMeetingRecording Members + + public BoolFeedback MeetingIsRecordingFeedback { get; private set; } + + public void StartRecording() + { + SendText(string.Format("Command Call Record Enable: on")); + } + + public void StopRecording() + { + SendText(string.Format("Command Call Record Enable: off")); + } + + public void ToggleRecording() + { + if (MeetingIsRecordingFeedback.BoolValue) + { + StopRecording(); + } + else + { + StartRecording(); + } + } + + #endregion } /// From 949a04647b2f813ccdd34af530f5a3180330db19 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Nov 2021 12:36:04 -0600 Subject: [PATCH 424/480] feat(essentials): improves functionality of LayoutInfoChanged event --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 7 ++- .../VideoCodec/ZoomRoom/ResponseObjects.cs | 20 ++++++++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 43 +++++++++++++------ 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index a8805a21..c2014b67 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public interface IHasZoomRoomLayouts : IHasCodecLayouts { - event EventHandler AvailableLayoutsChanged; + event EventHandler LayoutInfoChanged; BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 [*] Consider modifying to report button visibility in func @@ -46,5 +46,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public class LayoutInfoChangedEventArgs : EventArgs { public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; } + public ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; set; } + public bool CanSwapContentWithThumbnail { get; set; } + public bool ContentSwappedWithThumbnail { get; set; } + public bool LayoutViewIsOnFirstPage { get; set; } + public bool LayoutViewIsOnLastPage { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs index 3b6066d1..f6355d63 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs @@ -618,13 +618,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom private bool _can_Switch_Speaker_View; private bool _can_Switch_Wall_View; private bool _can_Switch_Share_On_All_Screens; + private bool _can_Switch_Floating_Share_Content; private bool _is_In_First_Page; private bool _is_In_Last_Page; private string _video_type; public bool can_Adjust_Floating_Video { get; set; } - public bool can_Switch_Floating_Share_Content { get; set; } + + + public bool can_Switch_Floating_Share_Content + { + get + { + return _can_Switch_Floating_Share_Content; + } + set + { + if (value != _can_Switch_Floating_Share_Content) + { + _can_Switch_Floating_Share_Content = value; + NotifyPropertyChanged("can_Switch_Floating_Share_Content"); + } + } + } + /// /// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors. diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index f556fa94..7c21e6dd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -583,11 +583,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "ShareThumb": { ContentSwappedWithThumbnailFeedback.FireUpdate(); + OnLayoutInfoChanged(); break; } case "Style": { LocalLayoutFeedback.FireUpdate(); + OnLayoutInfoChanged(); break; } case "Size": @@ -626,11 +628,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom case "ShareThumb": { ContentSwappedWithThumbnailFeedback.FireUpdate(); + OnLayoutInfoChanged(); break; } case "Style": { LocalLayoutFeedback.FireUpdate(); + OnLayoutInfoChanged(); break; } } @@ -735,13 +739,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom LayoutViewIsOnLastPageFeedback.FireUpdate(); break; } - //case "video_type": - // { - // It appears as though the actual value we want to watch is Configuration.Call.Layout.Style - // LocalLayoutFeedback.FireUpdate(); - // break; - // } + case "can_Switch_Floating_Share_Content": + { + CanSwapContentWithThumbnailFeedback.FireUpdate(); + break; + } } + OnLayoutInfoChanged(); }; Status.NumberOfScreens.PropertyChanged += (o, a) => @@ -2153,7 +2157,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom var layoutsCodec = this as IHasZoomRoomLayouts; if (layoutsCodec != null) { - layoutsCodec.AvailableLayoutsChanged += (o, a) => + layoutsCodec.LayoutInfoChanged += (o, a) => { trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery == @@ -2856,7 +2860,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #region IHasZoomRoomLayouts Members - public event EventHandler AvailableLayoutsChanged; + public event EventHandler LayoutInfoChanged; private Func LayoutViewIsOnFirstPageFeedbackFunc { @@ -2922,15 +2926,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Debug.Console(1, this, "availablelayouts: {0}", availableLayouts); - var handler = AvailableLayoutsChanged; - if (handler != null) - { - handler(this, new LayoutInfoChangedEventArgs() {AvailableLayouts = availableLayouts}); - } - AvailableLayouts = availableLayouts; } + private void OnLayoutInfoChanged() + { + var handler = LayoutInfoChanged; + if (handler != null) + { + handler(this, new LayoutInfoChangedEventArgs() + { + AvailableLayouts = AvailableLayouts, + LastSelectedLayout = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle),LocalLayoutFeedback.StringValue, true), + LayoutViewIsOnFirstPage = LayoutViewIsOnFirstPageFeedback.BoolValue, + LayoutViewIsOnLastPage = LayoutViewIsOnLastPageFeedback.BoolValue, + CanSwapContentWithThumbnail = CanSwapContentWithThumbnailFeedback.BoolValue, + ContentSwappedWithThumbnail = ContentSwappedWithThumbnailFeedback.BoolValue, + }); + } + } + public void GetAvailableLayouts() { SendText("zStatus Call Layout"); From 3ee44bcf6e4fd9f8a6bd11e573be821e6f81d813 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Nov 2021 12:40:07 -0600 Subject: [PATCH 425/480] refactor(essentials): better name for current layout property in eventargs --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 2 +- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index c2014b67..4603be77 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -46,7 +46,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public class LayoutInfoChangedEventArgs : EventArgs { public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; } - public ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; set; } + public ZoomRoom.zConfiguration.eLayoutStyle CurrentSelectedLayout { get; set; } public bool CanSwapContentWithThumbnail { get; set; } public bool ContentSwappedWithThumbnail { get; set; } public bool LayoutViewIsOnFirstPage { get; set; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 7c21e6dd..da6e74b3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2937,7 +2937,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = AvailableLayouts, - LastSelectedLayout = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle),LocalLayoutFeedback.StringValue, true), + CurrentSelectedLayout = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle),LocalLayoutFeedback.StringValue, true), LayoutViewIsOnFirstPage = LayoutViewIsOnFirstPageFeedback.BoolValue, LayoutViewIsOnLastPage = LayoutViewIsOnLastPageFeedback.BoolValue, CanSwapContentWithThumbnail = CanSwapContentWithThumbnailFeedback.BoolValue, From 5171385b5bd5ffbf465dbe8677f4d4e8eeb93184 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Nov 2021 15:58:10 -0600 Subject: [PATCH 426/480] feat(essentials): adds JSON property attributes as needed --- .../VideoCodec/Interfaces/IHasCodecLayouts.cs | 8 ++++++++ .../VideoCodec/Interfaces/iVideoCodecInfo.cs | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs index 4603be77..ef0bf2bd 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasCodecLayouts.cs @@ -6,6 +6,8 @@ using Crestron.SimplSharp; using PepperDash.Essentials.Core; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Devices.Common.VideoCodec { /// @@ -45,11 +47,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public class LayoutInfoChangedEventArgs : EventArgs { + [JsonProperty("availableLayouts", NullValueHandling = NullValueHandling.Ignore)] public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; } + [JsonProperty("currentSelectedLayout", NullValueHandling = NullValueHandling.Ignore)] public ZoomRoom.zConfiguration.eLayoutStyle CurrentSelectedLayout { get; set; } + [JsonProperty("canSwapContentWithThumbnail", NullValueHandling = NullValueHandling.Ignore)] public bool CanSwapContentWithThumbnail { get; set; } + [JsonProperty("contentSwappedWithThumbnail", NullValueHandling = NullValueHandling.Ignore)] public bool ContentSwappedWithThumbnail { get; set; } + [JsonProperty("layoutViewIsOnFirstPage", NullValueHandling = NullValueHandling.Ignore)] public bool LayoutViewIsOnFirstPage { get; set; } + [JsonProperty("layoutViewIsOnLastPage", NullValueHandling = NullValueHandling.Ignore)] public bool LayoutViewIsOnLastPage { get; set; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/iVideoCodecInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/iVideoCodecInfo.cs index 902dd68f..6eee454f 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/iVideoCodecInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/iVideoCodecInfo.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Devices.Common.Codec { /// @@ -19,12 +21,19 @@ namespace PepperDash.Essentials.Devices.Common.Codec /// public abstract class VideoCodecInfo { + [JsonProperty("multiSiteOptionIsEnabled", NullValueHandling = NullValueHandling.Ignore)] public abstract bool MultiSiteOptionIsEnabled { get; } + [JsonProperty("ipAddress", NullValueHandling = NullValueHandling.Ignore)] public abstract string IpAddress { get; } + [JsonProperty("sipPhoneNumber", NullValueHandling = NullValueHandling.Ignore)] public abstract string SipPhoneNumber { get; } + [JsonProperty("e164Alias", NullValueHandling = NullValueHandling.Ignore)] public abstract string E164Alias { get; } + [JsonProperty("h323Id", NullValueHandling = NullValueHandling.Ignore)] public abstract string H323Id { get; } + [JsonProperty("sipUri", NullValueHandling = NullValueHandling.Ignore)] public abstract string SipUri { get; } + [JsonProperty("autoAnswerEnabled", NullValueHandling = NullValueHandling.Ignore)] public abstract bool AutoAnswerEnabled { get; } } } \ No newline at end of file From 2e5b7cad648dfcae182fa7729ed3bf6fa30ab7be Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 5 Nov 2021 17:46:48 -0600 Subject: [PATCH 427/480] feat(essentials): adds null value handling to MeetingInfo props --- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index 0720b319..c0550e7b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -24,21 +24,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// public class MeetingInfo { - [JsonProperty("id")] + [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] public string Id { get; private set; } - [JsonProperty("name")] + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; private set; } - [JsonProperty("host")] + [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)] public string Host { get; private set; } - [JsonProperty("password")] + [JsonProperty("password", NullValueHandling = NullValueHandling.Ignore)] public string Password { get; private set; } - [JsonProperty("shareStatus")] + [JsonProperty("shareStatus", NullValueHandling = NullValueHandling.Ignore)] public string ShareStatus { get; private set; } - [JsonProperty("isHost")] + [JsonProperty("isHost", NullValueHandling = NullValueHandling.Ignore)] public Boolean IsHost { get; private set; } - [JsonProperty("isSharingMeeting")] + [JsonProperty("isSharingMeeting", NullValueHandling = NullValueHandling.Ignore)] public Boolean IsSharingMeeting { get; private set; } - [JsonProperty("waitingForHost")] + [JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)] public Boolean WaitingForHost { get; private set; } public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost) From d3f30d8b7126a30128d572144af63c6d864e9512 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 9 Nov 2021 10:09:06 -0700 Subject: [PATCH 428/480] adds solution paths to workflows --- .github/workflows/docker.yml | 4 ++-- .github/workflows/main.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 94c45937..cd815802 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,8 +12,8 @@ on: env: # solution path doesn't need slashes unless it is multiple folders deep # solution name does not include extension. .sln is assumed - SOLUTION_PATH: PepperDashEssentials - SOLUTION_FILE: PepperDashEssentials + SOLUTION_PATH: epi-utilit-io-action + SOLUTION_FILE: epi-utilit-io-action # Do not edit this, we're just creating it here VERSION: 0.0.0-buildtype-buildnumber # Defaults to debug for build type diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc219ce3..78bf8396 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,8 +9,8 @@ on: env: # solution path doesn't need slashes unless there it is multiple folders deep # solution name does not include extension. .sln is assumed - SOLUTION_PATH: PepperDashEssentials - SOLUTION_FILE: PepperDashEssentials + SOLUTION_PATH: epi-utilit-io-action + SOLUTION_FILE: epi-utilit-io-action # Do not edit this, we're just creating it here VERSION: 0.0.0-buildtype-buildnumber # Defaults to debug for build type From e7d1d560ee0be18d81a290b5e3e214310033ff6b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 9 Nov 2021 10:10:28 -0700 Subject: [PATCH 429/480] Revert "adds solution paths to workflows" This reverts commit d3f30d8b7126a30128d572144af63c6d864e9512. --- .github/workflows/docker.yml | 4 ++-- .github/workflows/main.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index cd815802..94c45937 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,8 +12,8 @@ on: env: # solution path doesn't need slashes unless it is multiple folders deep # solution name does not include extension. .sln is assumed - SOLUTION_PATH: epi-utilit-io-action - SOLUTION_FILE: epi-utilit-io-action + SOLUTION_PATH: PepperDashEssentials + SOLUTION_FILE: PepperDashEssentials # Do not edit this, we're just creating it here VERSION: 0.0.0-buildtype-buildnumber # Defaults to debug for build type diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 78bf8396..dc219ce3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,8 +9,8 @@ on: env: # solution path doesn't need slashes unless there it is multiple folders deep # solution name does not include extension. .sln is assumed - SOLUTION_PATH: epi-utilit-io-action - SOLUTION_FILE: epi-utilit-io-action + SOLUTION_PATH: PepperDashEssentials + SOLUTION_FILE: PepperDashEssentials # Do not edit this, we're just creating it here VERSION: 0.0.0-buildtype-buildnumber # Defaults to debug for build type From 446bae4dd3ea08d612af263d889da74fc694c99e Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Wed, 10 Nov 2021 11:21:19 -0500 Subject: [PATCH 430/480] hotfix(Essentials_DM): fixed invalid cast exception in dm blade chassis --- .../Essentials_DM/Chassis/DmBladeChassisController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs index 3a4f55c0..22e792b5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs @@ -304,7 +304,7 @@ namespace PepperDash.Essentials.DM { { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } + } void AddHdmiInBladePorts(uint number, ICec cecPort) { @@ -425,7 +425,7 @@ namespace PepperDash.Essentials.DM { Debug.Console(2, this, "Adding output port '{0}'", portKey); OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this) { - FeedbackMatchObject = Chassis.Outputs[(uint)selector] + FeedbackMatchObject = selector }); } From fa89a73c4b1b96974657551aeee43bf2620a8099 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 11 Nov 2021 16:47:15 -0600 Subject: [PATCH 431/480] feat: added support for Crestron CEN-IO-RY-104 relay module. --- .../Crestron IO/Relay/CenIoRy104Controller.cs | 77 +++++++++++++++++++ .../PepperDash_Essentials_Core.csproj | 1 + 2 files changed, 78 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/CenIoRy104Controller.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/CenIoRy104Controller.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/CenIoRy104Controller.cs new file mode 100644 index 00000000..19ca8438 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/CenIoRy104Controller.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.GeneralIO; +using PepperDash.Core; +using PepperDash.Essentials.Core.Config; + +namespace PepperDash.Essentials.Core +{ + /// + /// Wrapper class for CEN-IO-RY-104 relay module + /// + [Description("Wrapper class for the CEN-IO-RY-104 relay module")] + public class CenIoRy104Controller : EssentialsDevice, IRelayPorts + { + private readonly CenIoRy104 _ry104; + + /// + /// Constructor + /// + /// + /// + /// + public CenIoRy104Controller(string key, string name, CenIoRy104 ry104) + : base(key, name) + { + _ry104 = ry104; + } + + /// + /// Relay port collection + /// + public CrestronCollection RelayPorts + { + get { return _ry104.RelayPorts; } + } + + /// + /// Number of relay ports property + /// + public int NumberOfRelayPorts + { + get { return _ry104.NumberOfRelayPorts; } + } + } + + /// + /// CEN-IO-RY Controller factory + /// + public class CenIoRy104ControllerFactory : EssentialsDeviceFactory + { + /// + /// Constructor + /// + public CenIoRy104ControllerFactory() + { + TypeNames = new List() { "ceniory104" }; + } + + public override EssentialsDevice BuildDevice(DeviceConfig dc) + { + Debug.Console(1, "Factory Attempting to create a new CEN-IO-RY-104 Device"); + + var controlPropertiesConfig = CommFactory.GetControlPropertiesConfig(dc); + if (controlPropertiesConfig == null) + { + Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device"); + return null; + } + + var ipid = controlPropertiesConfig.IpIdInt; + if (ipid != 0) return new CenIoRy104Controller(dc.Key, dc.Name, new CenIoRy104(ipid, Global.ControlSystem)); + + Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device using IP-ID-{0}", ipid); + 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 752466d4..3c7a6c31 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -182,6 +182,7 @@ + From 2dbc3aa8db96938a06a4d3f5e4adc051668e94ca Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Fri, 12 Nov 2021 15:39:01 -0500 Subject: [PATCH 432/480] Change join numbers due to conflicting join with existing serial joins --- .../Bridges/JoinMaps/DmRmcControllerJoinMap.cs | 8 ++++---- .../Bridges/JoinMaps/DmTxControllerJoinMap.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs index 18706bb0..ec4661a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs @@ -28,14 +28,14 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete EdidSerialNumber = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata { Description = "DM RMC EDID Serial Number", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 }, + new JoinMetadata { Description = "DM RMC Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("AudioVideoSource")] public JoinDataComplete AudioVideoSource = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "DM RMC Audio Video Source Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); - [JoinName("Name")] - public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata { Description = "DM RMC Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); - /// /// Constructor to use when instantiating this Join Map without inheriting from it /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs index 1cb0b347..6d783639 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs @@ -32,6 +32,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete CurrentInputResolution = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "DM TX Current Input Resolution", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("Name")] + public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata { Description = "DM TX Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("VideoInput")] public JoinDataComplete VideoInput = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "DM TX Video Input Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); @@ -60,10 +64,6 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete VgaContrast = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata { Description = "DM TX Online", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); - [JoinName("Name")] - public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, - new JoinMetadata { Description = "DM TX Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); - /// /// Constructor to use when instantiating this Join Map without inheriting from it /// From fffaa1e5e6693f4cc4f449d37ca1b89045a287a9 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 16 Nov 2021 17:16:11 -0700 Subject: [PATCH 433/480] feat(essentials): Ignores Status and Configuration properties for serialization --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index da6e74b3..5ea4ef82 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -3204,8 +3204,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Configuration = configuration; } + [JsonIgnore] public ZoomRoomStatus Status { get; private set; } - public ZoomRoomConfiguration Configuration { get; private set; } + [JsonIgnore] + public ZoomRoomConfiguration Configuration { get; private set; } public override bool AutoAnswerEnabled { From 37a7886ec23a0aa4308be74b29880e26fb35e41d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Nov 2021 15:06:49 -0700 Subject: [PATCH 434/480] feat(essentials): Adds IsLocked property to MeetingInfo --- .../VideoCodec/Interfaces/IHasMeetingInfo.cs | 6 ++- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 40 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs index c0550e7b..0d304028 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasMeetingInfo.cs @@ -40,8 +40,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces public Boolean IsSharingMeeting { get; private set; } [JsonProperty("waitingForHost", NullValueHandling = NullValueHandling.Ignore)] public Boolean WaitingForHost { get; private set; } + [JsonProperty("isLocked", NullValueHandling = NullValueHandling.Ignore)] + public Boolean IsLocked { get; private set; } - public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost) + + public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost, bool isLocked) { Id = id; Name = name; @@ -51,6 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces IsHost = isHost; IsSharingMeeting = isSharingMeeting; WaitingForHost = waitingForHost; + IsLocked = isLocked; } } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 5ea4ef82..82c8960c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -504,19 +504,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { var sharingStatus = GetSharingStatus(); - MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true, false); + MeetingInfo = new MeetingInfo("", "", "", "", sharingStatus, GetIsHostMyself(), true, false, MeetingIsLockedFeedback.BoolValue); return; } var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host != null ? Participants.Host.Name : "None", - MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); + MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost, MeetingIsLockedFeedback.BoolValue); MeetingInfo = meetingInfo; } catch (Exception e) { Debug.Console(1, this, "Error processing state property update. {0}", e.Message); Debug.Console(2, this, e.StackTrace); - MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false, false); + MeetingInfo = new MeetingInfo("", "", "", "", "None", false, false, false, MeetingIsLockedFeedback.BoolValue); } } @@ -688,7 +688,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom return; } // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, GetSharingStatus(), GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); + var meetingInfo = new MeetingInfo(MeetingInfo.Id, + MeetingInfo.Name, + MeetingInfo.Host, + MeetingInfo.Password, + GetSharingStatus(), + GetIsHostMyself(), + MeetingInfo.IsSharingMeeting, + MeetingInfo.WaitingForHost, + MeetingIsLockedFeedback.BoolValue); MeetingInfo = meetingInfo; break; } @@ -1269,7 +1277,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Participants.CurrentParticipants = participants; // Update the share status of the meeting info - var meetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, Participants.Host.Name, MeetingInfo.Password, MeetingInfo.ShareStatus, GetIsHostMyself(), MeetingInfo.IsSharingMeeting, MeetingInfo.WaitingForHost); + var meetingInfo = new MeetingInfo( + MeetingInfo.Id, + MeetingInfo.Name, + Participants.Host.Name, + MeetingInfo.Password, + MeetingInfo.ShareStatus, + GetIsHostMyself(), + MeetingInfo.IsSharingMeeting, + MeetingInfo.WaitingForHost, + MeetingIsLockedFeedback.BoolValue); MeetingInfo = meetingInfo; PrintCurrentCallParticipants(); @@ -1478,14 +1495,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (MeetingInfo == null) { MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", - GetSharingStatus(), false, false, true); + GetSharingStatus(), false, false, true, MeetingIsLockedFeedback.BoolValue); UpdateCallStatus(); break; } MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", - GetSharingStatus(), false, false, true); + GetSharingStatus(), false, false, true, MeetingIsLockedFeedback.BoolValue); UpdateCallStatus(); @@ -1495,12 +1512,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (MeetingInfo == null) { MeetingInfo = new MeetingInfo("Waiting For Host", "Waiting For Host", "Waiting For Host", "", - GetSharingStatus(), false, false, false); + GetSharingStatus(), false, false, false, MeetingIsLockedFeedback.BoolValue); break; } MeetingInfo = new MeetingInfo(MeetingInfo.Id, MeetingInfo.Name, MeetingInfo.Host, MeetingInfo.Password, - GetSharingStatus(), GetIsHostMyself(), false, false); + GetSharingStatus(), GetIsHostMyself(), false, false, MeetingIsLockedFeedback.BoolValue); break; } @@ -1584,7 +1601,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (result.Success) { - MeetingInfo = new MeetingInfo("", "", "", "", "", true, true, MeetingInfo.WaitingForHost); + MeetingInfo = new MeetingInfo("", "", "", "", "", true, true, MeetingInfo.WaitingForHost, MeetingIsLockedFeedback.BoolValue); break; } @@ -1929,7 +1946,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom GetSharingStatus(), GetIsHostMyself(), !String.Equals(Status.Call.Info.meeting_type,"NORMAL"), - false + false, + MeetingIsLockedFeedback.BoolValue ); } From 8945398cd7b6419a4a32746845c6acd9e1ebce9d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 17 Nov 2021 17:58:50 -0700 Subject: [PATCH 435/480] feat(essentials): update when meeting lock changes and detect call status on sync --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 82c8960c..44514770 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -609,6 +609,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom if (a.PropertyName == "Enable") { MeetingIsLockedFeedback.FireUpdate(); + MeetingInfo = new MeetingInfo + ( + MeetingInfo.Id, + MeetingInfo.Name, + MeetingInfo.Host, + MeetingInfo.Password, + GetSharingStatus(), + MeetingInfo.IsHost, + MeetingInfo.IsSharingMeeting, + MeetingInfo.WaitingForHost, + MeetingIsLockedFeedback.BoolValue + ); } }; @@ -651,11 +663,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Status.Call.PropertyChanged += (o, a) => { - if (a.PropertyName == "Info") + switch(a.PropertyName) + { + case "Info": { Debug.Console(1, this, "Updating Call Status"); UpdateCallStatus(); + break; } + + case "Status": + { + UpdateCallStatus(); + break; + } + } }; Status.Call.CallRecordInfo.PropertyChanged += (o, a) => From e152250363b665e62bd1cc1025c9c0342b9cc5ab Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 1 Dec 2021 12:40:17 -0700 Subject: [PATCH 436/480] feat(essentials): Adds IEnvironmentalControls interface and updates some room config properties --- .../Room/Config/EssentialsRoomConfig.cs | 18 ++++++++++++++++++ .../Room/EssentialsRoomBase.cs | 17 +++++++++++++++++ .../Room/IEssentialsRoom.cs | 2 +- .../Room/Interfaces.cs | 10 ++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index 5ec0565d..a20b8e25 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -147,6 +147,24 @@ namespace PepperDash.Essentials.Room.Config [JsonProperty("helpMessage")] public string HelpMessage { get; set; } + /// + /// Read this value to get the help message. It checks for the old and new config format. + /// + public string HelpMessageForDisplay + { + get + { + if(Help != null && !string.IsNullOrEmpty(Help.Message)) + { + return Help.Message; + } + else + { + return HelpMessage; + } + } + } + [JsonProperty("environment")] public EssentialsEnvironmentPropertiesConfig Environment { get; set; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index 0d8e9803..de75318c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -11,6 +11,8 @@ using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices; using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using Newtonsoft.Json; + namespace PepperDash.Essentials.Core { /// @@ -18,6 +20,8 @@ namespace PepperDash.Essentials.Core /// public abstract class EssentialsRoomBase : ReconfigurableDevice, IEssentialsRoom { + + /// /// /// @@ -35,6 +39,16 @@ namespace PepperDash.Essentials.Core public bool OccupancyStatusProviderIsRemote { get; private set; } + public List EnvironmentalControlDevices { get; protected set; } + + public bool HasEnvironmentalControlDevices + { + get + { + return EnvironmentalControlDevices != null && EnvironmentalControlDevices.Count > 0; + } + } + protected abstract Func IsWarmingFeedbackFunc { get; } protected abstract Func IsCoolingFeedbackFunc { get; } @@ -119,6 +133,9 @@ namespace PepperDash.Essentials.Core public EssentialsRoomBase(DeviceConfig config) : base(config) { + + + // Setup the ShutdownPromptTimer ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer"); ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) => diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs index 5f94a5cd..2273690f 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core /// /// Describes the basic functionality of an EssentialsRoom /// - public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute + public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute, IEnvironmentalControls { BoolFeedback OnFeedback { get; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs index 592b0bd9..b5121e9c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using Crestron.SimplSharp; +using PepperDash.Core; + namespace PepperDash.Essentials.Core { @@ -66,6 +68,14 @@ namespace PepperDash.Essentials.Core bool RunDefaultCallRoute(); } + /// + /// Describes environmental controls available on a room such as lighting, shades, temperature, etc. + /// + public interface IEnvironmentalControls + { + List EnvironmentalControlDevices { get; } + bool HasEnvironmentalControlDevices { get; } + } } \ No newline at end of file From ae10e560f0a64bd0b91f0743a736862b40d43194 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 2 Dec 2021 13:43:30 -0700 Subject: [PATCH 437/480] No significant change. Attempting to retrigger successful build --- PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs index a20b8e25..9824ec67 100644 --- a/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs +++ b/PepperDashEssentials/Room/Config/EssentialsRoomConfig.cs @@ -160,7 +160,7 @@ namespace PepperDash.Essentials.Room.Config } else { - return HelpMessage; + return HelpMessage; } } } From 176d4675dadb542506eb34ac076fd7db5b98c95a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 2 Dec 2021 17:53:39 -0700 Subject: [PATCH 438/480] feat(essentials): Populates EnvironmentatlControlDevices on huddle and vtc room types --- .../Room/Types/EssentialsHuddleSpaceRoom.cs | 17 +++++++++++++++++ .../Room/Types/EssentialsHuddleVtc1Room.cs | 17 +++++++++++++++++ .../Room/EssentialsRoomBase.cs | 3 +-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs index 3123f20f..5dbe7600 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs @@ -202,11 +202,28 @@ namespace PepperDash.Essentials }; } + SetupEnvironmentalControlDevices(); + SetSourceListKey(); EnablePowerOnToLastSource = true; } + private void SetupEnvironmentalControlDevices() + { + if (PropertiesConfig.Environment != null) + { + if (PropertiesConfig.Environment.Enabled) + { + foreach (var d in PropertiesConfig.Environment.DeviceKeys) + { + var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice; + EnvironmentalControlDevices.Add(envDevice); + } + } + } + } + private void SetSourceListKey() { if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey)) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 42a4a353..884ed9a0 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -334,6 +334,8 @@ namespace PepperDash.Essentials CallTypeFeedback = new IntFeedback(() => 0); + SetupEnvironmentalControlDevices(); + SetSourceListKey(); EnablePowerOnToLastSource = true; @@ -344,6 +346,21 @@ namespace PepperDash.Essentials } } + private void SetupEnvironmentalControlDevices() + { + if (PropertiesConfig.Environment != null) + { + if (PropertiesConfig.Environment.Enabled) + { + foreach (var d in PropertiesConfig.Environment.DeviceKeys) + { + var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice; + EnvironmentalControlDevices.Add(envDevice); + } + } + } + } + private void SetSourceListKey() { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs index de75318c..352cbfcd 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs @@ -133,8 +133,7 @@ namespace PepperDash.Essentials.Core public EssentialsRoomBase(DeviceConfig config) : base(config) { - - + EnvironmentalControlDevices = new List(); // Setup the ShutdownPromptTimer ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer"); From 1d2eb42c46f89f22ac34f38eb70b1674b5250007 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 3 Dec 2021 14:15:58 -0700 Subject: [PATCH 439/480] feat(essentials): Adds label property to shade interface --- .../PepperDashEssentialsBase/Shades/Shade Interfaces.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs index b4d7c88d..ce36d7a4 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs @@ -31,6 +31,7 @@ namespace PepperDash.Essentials.Core.Shades public interface IShadesOpenCloseStop : IShadesOpenClose { void StopOrPreset(); + string StopOrPresetButtonLabel; } /// From bceb7115ed075c4385f2ef071ba3c570cf766d87 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 3 Dec 2021 14:37:45 -0700 Subject: [PATCH 440/480] fixes new interface property --- .../Lighting/LightingBase.cs | 248 +++++++++--------- .../Shades/Shade Interfaces.cs | 2 +- 2 files changed, 125 insertions(+), 125 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs index 1bf8aee8..eeb25531 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs @@ -1,83 +1,83 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DeviceSupport; -using Newtonsoft.Json; -using PepperDash.Core; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.Core.Lighting -{ - public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes - { - #region ILightingScenes Members - - public event EventHandler LightingSceneChange; - - public List LightingScenes { get; protected set; } - - public LightingScene CurrentLightingScene { get; protected set; } - - public IntFeedback CurrentLightingSceneFeedback { get; protected set; } - - #endregion - - protected LightingBase(string key, string name) - : base(key, name) - { - LightingScenes = new List(); - - CurrentLightingScene = new LightingScene(); - //CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); }); - } - - public abstract void SelectScene(LightingScene scene); - - public void SimulateSceneSelect(string sceneName) - { - Debug.Console(1, this, "Simulating selection of scene '{0}'", sceneName); - - var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName)); - - if (scene != null) - { - CurrentLightingScene = scene; - OnLightingSceneChange(); - } - } - - /// - /// Sets the IsActive property on each scene and fires the LightingSceneChange event - /// - protected void OnLightingSceneChange() - { - foreach (var scene in LightingScenes) - { - if (scene == CurrentLightingScene) - scene.IsActive = true; - - else - scene.IsActive = false; - } - - var handler = LightingSceneChange; - if (handler != null) - { - handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene)); - } - } - - protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, - string joinMapKey, EiscApiAdvanced bridge) +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Newtonsoft.Json; +using PepperDash.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.Core.Lighting +{ + public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes + { + #region ILightingScenes Members + + public event EventHandler LightingSceneChange; + + public List LightingScenes { get; protected set; } + + public LightingScene CurrentLightingScene { get; protected set; } + + public IntFeedback CurrentLightingSceneFeedback { get; protected set; } + + #endregion + + protected LightingBase(string key, string name) + : base(key, name) { - var joinMap = new GenericLightingJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) + LightingScenes = new List(); + + CurrentLightingScene = new LightingScene(); + //CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); }); + } + + public abstract void SelectScene(LightingScene scene); + + public void SimulateSceneSelect(string sceneName) + { + Debug.Console(1, this, "Simulating selection of scene '{0}'", sceneName); + + var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName)); + + if (scene != null) + { + CurrentLightingScene = scene; + OnLightingSceneChange(); + } + } + + /// + /// Sets the IsActive property on each scene and fires the LightingSceneChange event + /// + protected void OnLightingSceneChange() + { + foreach (var scene in LightingScenes) + { + if (scene == CurrentLightingScene) + scene.IsActive = true; + + else + scene.IsActive = false; + } + + var handler = LightingSceneChange; + if (handler != null) + { + handler(this, new LightingSceneChangeEventArgs(CurrentLightingScene)); + } + } + + protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart, + string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new GenericLightingJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); if (bridge != null) @@ -87,52 +87,52 @@ namespace PepperDash.Essentials.Core.Lighting else { Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); - + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); + // GenericLighitng Actions & FeedBack - trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u])); - - var sceneIndex = 0; - foreach (var scene in lightingDevice.LightingScenes) + trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u])); + + var sceneIndex = 0; + foreach (var scene in lightingDevice.LightingScenes) { - trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[sceneIndex])); + trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[sceneIndex])); scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)]); - trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name; - trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true; - sceneIndex++; - } - - return joinMap; - } - - } - - public class LightingScene - { - public string Name { get; set; } - public string ID { get; set; } - bool _IsActive; - public bool IsActive - { - get - { - return _IsActive; - } - set - { - _IsActive = value; - IsActiveFeedback.FireUpdate(); - } - } - public BoolFeedback IsActiveFeedback { get; set; } - - public LightingScene() - { - IsActiveFeedback = new BoolFeedback(new Func(() => IsActive)); - } - } + trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name; + trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true; + sceneIndex++; + } + + return joinMap; + } + + } + + public class LightingScene + { + public string Name { get; set; } + public string ID { get; set; } + bool _IsActive; + public bool IsActive + { + get + { + return _IsActive; + } + set + { + _IsActive = value; + IsActiveFeedback.FireUpdate(); + } + } + public BoolFeedback IsActiveFeedback { get; set; } + + public LightingScene() + { + IsActiveFeedback = new BoolFeedback(new Func(() => IsActive)); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs index ce36d7a4..35492162 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Shades/Shade Interfaces.cs @@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core.Shades public interface IShadesOpenCloseStop : IShadesOpenClose { void StopOrPreset(); - string StopOrPresetButtonLabel; + string StopOrPresetButtonLabel { get; } } /// From cf88e3b36d8580df13a1494a6d400bdf86d03838 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 6 Dec 2021 16:32:55 -0600 Subject: [PATCH 441/480] fix: Updated link to API's with Xsig's to subscribe to trilist.OnlineStatusChange events and update the Xsig. --- .../VideoCodec/VideoCodecBase.cs | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) 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 79b05046..3eb53041 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 @@ -302,8 +302,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; - - trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); }; } @@ -553,6 +551,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec UpdateParticipantsXSig(codec, trilist, joinMap); }; + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, "\xFC"); + UpdateParticipantsXSig(codec, trilist, joinMap); + }; } private void UpdateParticipantsXSig(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) @@ -784,7 +791,16 @@ ScreenIndexIsPinnedTo: {8} (a{17}) UpdateMeetingsList(codec, trilist, joinMap); } }; - } + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + UpdateMeetingsList(codec, trilist, joinMap); + }; + } private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) { @@ -805,6 +821,15 @@ ScreenIndexIsPinnedTo: {8} (a{17}) var meetingsData = UpdateMeetingsListXSig(_currentMeetings); trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); + UpdateMeetingsListXSig(_currentMeetings); + }; } private string UpdateMeetingsListXSig(List meetings) @@ -918,6 +943,16 @@ ScreenIndexIsPinnedTo: {8} (a{17}) trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); }; + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC"); + UpdateDirectoryXSig(codec.CurrentDirectoryResult, + !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + }; } private void SelectDirectoryEntry(IHasDirectory codec, ushort i) @@ -999,6 +1034,15 @@ ScreenIndexIsPinnedTo: {8} (a{17}) trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); }; + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC"); + UpdateCallStatusXSig(); + }; } private string UpdateCallStatusXSig() @@ -1266,6 +1310,15 @@ ScreenIndexIsPinnedTo: {8} (a{17}) trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty); trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); }); + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + // TODO [ ] #868 + trilist.SetString(joinMap.CameraPresetNames.JoinNumber, "\xFC"); + SetCameraPresetNames(presetCodec.NearEndPresets); + }; } private string SetCameraPresetNames(IEnumerable presets) From 2e1195431fca462c3872befdb8083de2ed1bb37a Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 6 Dec 2021 16:49:25 -0600 Subject: [PATCH 442/480] feat: Updated zoom room join map to add bridge joins. updated LinkToApi to begin linking existing features to bridge. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 3 + .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 169 +++++++++++++++++- 2 files changed, 170 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 44514770..701715e3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2283,6 +2283,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); } + // TODO [ ] #868 + + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index f70c48bf..53c759a6 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -6,7 +6,97 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { public class ZoomRoomJoinMap : VideoCodecControllerJoinMap { - #region Digital + #region Digital + + // TODO [ ] Issue #868 + [JoinName("ShowPasswordPrompt")] + public JoinDataComplete ShowPasswordPrompt = new JoinDataComplete( + new JoinData + { + JoinNumber = 6, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates to show the password prompt", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO [ ] Issue #868 + [JoinName("PasswordIncorrect")] + public JoinDataComplete PasswordIncorrect = new JoinDataComplete( + new JoinData + { + JoinNumber = 7, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates the password entered is incorrect", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO [ ] Issue #868 + [JoinName("NeedWaitForHost")] + public JoinDataComplete NeedWaitForHost = new JoinDataComplete( + new JoinData + { + JoinNumber = 8, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates system is waiting for host", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO [ ] Issue #868 + [JoinName("IsHost")] + public JoinDataComplete IsHost = new JoinDataComplete( + new JoinData + { + JoinNumber = 9, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates system is the host", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO [ ] Issue #868 + [JoinName("StartMeetingNow")] + public JoinDataComplete StartMeetingNow = new JoinDataComplete( + new JoinData + { + JoinNumber = 25, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates the password prompt is active", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + // TODO [ ] Issue #868 + [JoinName("ShareOnlyMeeting")] + public JoinDataComplete ShareOnlyMeeting = new JoinDataComplete( + new JoinData + { + JoinNumber = 26, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Triggers a share only meeting, feedback indicates the current meeting is share only", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); [JoinName("CanSwapContentWithThumbnail")] public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete( @@ -255,7 +345,82 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom #endregion - #region Serials + #region Serials + + // TODO [ ] Issue #868 + [JoinName("SubmitPassword")] + public JoinDataComplete SubmitPassword = new JoinDataComplete( + new JoinData + { + JoinNumber = 6, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Submit password text", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Serial + }); + + // TODO [ ] Issue #868 + [JoinName("PasswordPromptMessage")] + public JoinDataComplete PasswordPromptMessage = new JoinDataComplete( + new JoinData + { + JoinNumber = 6, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Password prompt message", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + // TODO [ ] Issue #868 + [JoinName("MeetingInfoId")] + public JoinDataComplete MeetingInfoId = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Meeting info ID text feedback", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + // TODO [ ] Issue #868 + [JoinName("MeetingInfoHostt")] + public JoinDataComplete MeetingInfoHost = new JoinDataComplete( + new JoinData + { + JoinNumber = 12, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Meeting info Host text feedback", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + // TODO [ ] Issue #868 + [JoinName("MeetingInfoPassword")] + public JoinDataComplete MeetingInfoPassword = new JoinDataComplete( + new JoinData + { + JoinNumber = 13, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Meeting info Password text feedback", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); [JoinName("GetSetCurrentLayout")] public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete( From c48f697b7e5c54eeb3e39c54f9aa2e88b87a7bf9 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 6 Dec 2021 16:51:01 -0600 Subject: [PATCH 443/480] chore: updated todo comments. --- .../VideoCodec/VideoCodecBase.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 3eb53041..f0221a21 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 @@ -556,7 +556,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.CurrentParticipants.JoinNumber, "\xFC"); UpdateParticipantsXSig(codec, trilist, joinMap); }; @@ -796,7 +796,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); UpdateMeetingsList(codec, trilist, joinMap); }; @@ -826,7 +826,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); UpdateMeetingsListXSig(_currentMeetings); }; @@ -948,7 +948,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC"); UpdateDirectoryXSig(codec.CurrentDirectoryResult, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); @@ -1039,7 +1039,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC"); UpdateCallStatusXSig(); }; @@ -1315,7 +1315,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) { if (!args.DeviceOnLine) return; - // TODO [ ] #868 + // TODO [ ] Issue #868 trilist.SetString(joinMap.CameraPresetNames.JoinNumber, "\xFC"); SetCameraPresetNames(presetCodec.NearEndPresets); }; From 3cf85f99ce67c3e04ed8b963312eb3eb2b506b6a Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Mon, 6 Dec 2021 17:09:28 -0600 Subject: [PATCH 444/480] feat: Finished updating LinkToApi to bridge existing features. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 35 +- .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 619 +++++++++--------- 2 files changed, 349 insertions(+), 305 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 701715e3..b6713b6a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1510,7 +1510,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { Status.NeedWaitForHost = JsonConvert.DeserializeObject(responseObj.ToString()); - Debug.Console(1, this, "NeedWaitForHost: {0}", Status.NeedWaitForHost.Wait); + Debug.Console(1, this, "WaitingForHost: {0}", Status.NeedWaitForHost.Wait); if (Status.NeedWaitForHost.Wait) { @@ -1972,6 +1972,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom MeetingIsLockedFeedback.BoolValue ); } + // TODO [ ] Issue #868 + else if (item.Status == eCodecCallStatus.Disconnected) + { + MeetingInfo = new MeetingInfo( + string.Empty, + string.Empty, + string.Empty, + string.Empty, + string.Empty, + false, + false, + false, + false + ); + } base.OnCallStatusChange(item); @@ -2283,8 +2298,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); } - // TODO [ ] #868 - + // TODO [ ] Issue #868 + MeetingInfoChanged += (device, args) => + { + trilist.SetString(joinMap.MeetingInfoId.JoinNumber, args.Info.Id); + trilist.SetString(joinMap.MeetingInfoHost.JoinNumber, args.Info.Host); + trilist.SetString(joinMap.MeetingInfoPassword.JoinNumber, args.Info.Password); + trilist.SetBool(joinMap.IsHost.JoinNumber, args.Info.IsHost); + trilist.SetBool(joinMap.ShareOnlyMeeting.JoinNumber, args.Info.IsSharingMeeting); + trilist.SetBool(joinMap.WaitingForHost.JoinNumber, args.Info.WaitingForHost); + //trilist.SetString(joinMap.CurrentSource.JoinNumber, args.Info.ShareStatus); + }; + + // TODO [ ] Issue #868 + trilist.SetSigTrueAction(joinMap.StartMeetingNow.JoinNumber, () => StartMeeting(0)); + trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting); + trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting); trilist.OnlineStatusChange += (device, args) => { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 53c759a6..68012fc7 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -1,11 +1,11 @@ -using System; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges.JoinMaps; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom -{ - public class ZoomRoomJoinMap : VideoCodecControllerJoinMap - { +using System; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges.JoinMaps; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom +{ + public class ZoomRoomJoinMap : VideoCodecControllerJoinMap + { #region Digital // TODO [ ] Issue #868 @@ -39,8 +39,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom }); // TODO [ ] Issue #868 - [JoinName("NeedWaitForHost")] - public JoinDataComplete NeedWaitForHost = new JoinDataComplete( + [JoinName("WaitingForHost")] + public JoinDataComplete WaitingForHost = new JoinDataComplete( new JoinData { JoinNumber = 8, @@ -96,255 +96,270 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "Triggers a share only meeting, feedback indicates the current meeting is share only", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital - }); - - [JoinName("CanSwapContentWithThumbnail")] - public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete( - new JoinData - { - JoinNumber = 206, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "FB Indicates if content can be swapped with thumbnail", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("SwapContentWithThumbnail")] - public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete( - new JoinData - { - JoinNumber = 206, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Pulse to swap content with thumbnail. FB reports current state", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("GetAvailableLayouts")] - public JoinDataComplete GetAvailableLayouts = new JoinDataComplete( - new JoinData - { - JoinNumber = 215, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("LayoutIsOnFirstPage")] - public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete( - new JoinData - { - JoinNumber = 216, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Indicates if layout is on first page", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("LayoutIsOnLastPage")] - public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete( - new JoinData - { - JoinNumber = 217, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Indicates if layout is on first page", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("LayoutTurnToNextPage")] - public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete( - new JoinData - { - JoinNumber = 216, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Turns layout view to next page", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("LayoutTurnToPreviousPage")] - public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete( - new JoinData - { - JoinNumber = 217, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Turns layout view to previous page", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Digital - }); - - [JoinName("LayoutGalleryIsAvailable")] - public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete( - new JoinData - { - JoinNumber = 221, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Gallery' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - [JoinName("LayoutSpeakerIsAvailable")] - public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete( - new JoinData - { - JoinNumber = 222, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Speaker' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - [JoinName("LayoutStripIsAvailable")] - public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete( - new JoinData - { - JoinNumber = 223, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "FB Indicates if layout 'Strip' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - [JoinName("LayoutShareAllIsAvailable")] - public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete( - new JoinData - { - JoinNumber = 224, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "FB Indicates if layout 'ShareAll' is available", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - // TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle - [JoinName("SelfviewPipSizeToggle")] - public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete( - new JoinData - { - JoinNumber = 231, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Toggles the selfview pip size, (aka layout size)", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Digital - }); - - //[JoinName("ParticipantAudioMuteToggleStart")] - //public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( - // new JoinData - // { - // JoinNumber = 500, - // JoinSpan = 100 - // }, - // new JoinMetadata - // { - // Description = "Toggles the participant's audio mute status", - // JoinCapabilities = eJoinCapabilities.ToSIMPL, - // JoinType = eJoinType.Digital - // }); - - //[JoinName("ParticipantVideoMuteToggleStart")] - //public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( - // new JoinData - // { - // JoinNumber = 800, - // JoinSpan = 100 - // }, - // new JoinMetadata - // { - // Description = "Toggles the participant's video mute status", - // JoinCapabilities = eJoinCapabilities.ToSIMPL, - // JoinType = eJoinType.Digital - // }); - - //[JoinName("ParticipantPinToggleStart")] - //public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( - // new JoinData - // { - // JoinNumber = 1100, - // JoinSpan = 100 - // }, - // new JoinMetadata - // { - // Description = "Toggles the participant's pin status", - // JoinCapabilities = eJoinCapabilities.ToSIMPL, - // JoinType = eJoinType.Digital - // }); - - #endregion - - - #region Analog - - [JoinName("NumberOfScreens")] - public JoinDataComplete NumberOfScreens = new JoinDataComplete( - new JoinData - { - JoinNumber = 11, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Reports the number of screens connected", - JoinCapabilities = eJoinCapabilities.ToSIMPL, - JoinType = eJoinType.Analog - }); - - [JoinName("ScreenIndexToPinUserTo")] - public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete( - new JoinData - { - JoinNumber = 11, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Specifies the screen index a participant should be pinned to", - JoinCapabilities = eJoinCapabilities.FromSIMPL, - JoinType = eJoinType.Analog - }); - - #endregion - - + }); + + // TODO [ ] Issue #868 + [JoinName("StartNormalMeetingFromSharingOnlyMeeting")] + public JoinDataComplete StartNormalMeetingFromSharingOnlyMeeting = new JoinDataComplete( + new JoinData + { + JoinNumber = 27, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Starts a normal meeting from a share only meeting", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("CanSwapContentWithThumbnail")] + public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete( + new JoinData + { + JoinNumber = 206, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if content can be swapped with thumbnail", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("SwapContentWithThumbnail")] + public JoinDataComplete SwapContentWithThumbnail = new JoinDataComplete( + new JoinData + { + JoinNumber = 206, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Pulse to swap content with thumbnail. FB reports current state", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("GetAvailableLayouts")] + public JoinDataComplete GetAvailableLayouts = new JoinDataComplete( + new JoinData + { + JoinNumber = 215, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutIsOnFirstPage")] + public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 216, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutIsOnLastPage")] + public JoinDataComplete LayoutIsOnLastPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 217, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Indicates if layout is on first page", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutTurnToNextPage")] + public JoinDataComplete LayoutTurnToNextPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 216, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Turns layout view to next page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutTurnToPreviousPage")] + public JoinDataComplete LayoutTurnToPreviousPage = new JoinDataComplete( + new JoinData + { + JoinNumber = 217, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Turns layout view to previous page", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("LayoutGalleryIsAvailable")] + public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 221, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Gallery' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + [JoinName("LayoutSpeakerIsAvailable")] + public JoinDataComplete LayoutSpeakerIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 222, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Speaker' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + [JoinName("LayoutStripIsAvailable")] + public JoinDataComplete LayoutStripIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 223, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'Strip' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + [JoinName("LayoutShareAllIsAvailable")] + public JoinDataComplete LayoutShareAllIsAvailable = new JoinDataComplete( + new JoinData + { + JoinNumber = 224, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates if layout 'ShareAll' is available", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + // TODO: #714 [ ] JoinMap >> SelfivewPipSizeToggle + [JoinName("SelfviewPipSizeToggle")] + public JoinDataComplete SelfviewPipSizeToggle = new JoinDataComplete( + new JoinData + { + JoinNumber = 231, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Toggles the selfview pip size, (aka layout size)", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + //[JoinName("ParticipantAudioMuteToggleStart")] + //public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 500, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's audio mute status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); + + //[JoinName("ParticipantVideoMuteToggleStart")] + //public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 800, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's video mute status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); + + //[JoinName("ParticipantPinToggleStart")] + //public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete( + // new JoinData + // { + // JoinNumber = 1100, + // JoinSpan = 100 + // }, + // new JoinMetadata + // { + // Description = "Toggles the participant's pin status", + // JoinCapabilities = eJoinCapabilities.ToSIMPL, + // JoinType = eJoinType.Digital + // }); + + #endregion + + + #region Analog + + [JoinName("NumberOfScreens")] + public JoinDataComplete NumberOfScreens = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Reports the number of screens connected", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Analog + }); + + [JoinName("ScreenIndexToPinUserTo")] + public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete( + new JoinData + { + JoinNumber = 11, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Specifies the screen index a participant should be pinned to", + JoinCapabilities = eJoinCapabilities.FromSIMPL, + JoinType = eJoinType.Analog + }); + + #endregion + + #region Serials // TODO [ ] Issue #868 @@ -420,47 +435,47 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom Description = "Meeting info Password text feedback", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial - }); - - [JoinName("GetSetCurrentLayout")] - public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete( - new JoinData - { - JoinNumber = 215, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.Serial - }); - - // TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize - [JoinName("GetSetSelfviewPipSize")] - public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete( - new JoinData - { - JoinNumber = 230, - JoinSpan = 1 - }, - new JoinMetadata - { - Description = "Sets and reports the selfview pip size, (aka layout size).", - JoinCapabilities = eJoinCapabilities.ToFromSIMPL, - JoinType = eJoinType.DigitalSerial - }); - - #endregion - - public ZoomRoomJoinMap(uint joinStart) - : base(joinStart, typeof(ZoomRoomJoinMap)) - { - } - - public ZoomRoomJoinMap(uint joinStart, Type type) - : base(joinStart, type) - { - } - } + }); + + [JoinName("GetSetCurrentLayout")] + public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete( + new JoinData + { + JoinNumber = 215, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Serial + }); + + // TODO: #714 [ ] JoinMap >> GetSetSelfviewPipSize + [JoinName("GetSetSelfviewPipSize")] + public JoinDataComplete GetSetSelfviewPipSize = new JoinDataComplete( + new JoinData + { + JoinNumber = 230, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Sets and reports the selfview pip size, (aka layout size).", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.DigitalSerial + }); + + #endregion + + public ZoomRoomJoinMap(uint joinStart) + : base(joinStart, typeof(ZoomRoomJoinMap)) + { + } + + public ZoomRoomJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } } \ No newline at end of file From 2f901b9fc4cd67fd1e06c8bcda396e9c8c57d6c1 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Mon, 6 Dec 2021 18:50:01 -0600 Subject: [PATCH 445/480] feat: added PasswordRequired event subscription to LinkToApi. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index b6713b6a..58e762e3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2315,6 +2315,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting); trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting); + // TODO [ ] Issue #868 + trilist.SetStringSigAction(joinMap.SubmitPassword.JoinNumber, SubmitPassword); + PasswordRequired += (devices, args) => + { + if (args.LoginAttemptCancelled) + { + trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, false); + return; + } + + if (!string.IsNullOrEmpty(args.Message)) + { + trilist.SetString(joinMap.PasswordPromptMessage.JoinNumber, args.Message); + } + + if (args.LoginAttemptFailed) + { + // login attempt failed + return; + } + + trilist.SetBool(joinMap.PasswordIncorrect.JoinNumber, args.LastAttemptWasIncorrect); + trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, true); + }; + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; From a6e4efd64fb9baab59b5ce1f109d701b273d9642 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 9 Dec 2021 13:31:58 -0500 Subject: [PATCH 446/480] Add Dmps microphone controller with bridge --- .../DmpsAudioOutputControllerJoinMap.cs | 4 + .../DmpsMicrophoneControllerJoinMap.cs | 50 +++++ .../PepperDash_Essentials_Core.csproj | 1 + .../Chassis/DmpsAudioOutputController.cs | 11 ++ .../Chassis/DmpsMicrophoneController.cs | 186 ++++++++++++++++++ .../Chassis/DmpsRoutingController.cs | 3 + .../PepperDash_Essentials_DM.csproj | 1 + 7 files changed, 256 insertions(+) create mode 100644 essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsMicrophoneControllerJoinMap.cs create mode 100644 essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs index 2da94bb0..c7d5c0e5 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsAudioOutputControllerJoinMap.cs @@ -13,6 +13,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete MasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata { Description = "Master Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("MixerPresetRecall")] + public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, + new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("MasterVolumeMuteOn")] public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsMicrophoneControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsMicrophoneControllerJoinMap.cs new file mode 100644 index 00000000..6922c569 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsMicrophoneControllerJoinMap.cs @@ -0,0 +1,50 @@ +using System; + +namespace PepperDash.Essentials.Core.Bridges +{ + public class DmpsMicrophoneControllerJoinMap : JoinMapBaseAdvanced + { + [JoinName("MicGain")] + public JoinDataComplete MicGain = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Gain dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("MicGainScaled")] + public JoinDataComplete MicGainScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Gain 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog }); + + [JoinName("MicMuteOn")] + public JoinDataComplete MicMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicMuteOff")] + public JoinDataComplete MicMuteOff = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Mute Off Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicGainScaledSend")] + public JoinDataComplete MicGainScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Gain Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("MicName")] + public JoinDataComplete MicName = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, + new JoinMetadata { Description = "Mic Name Get", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + + /// + /// Constructor to use when instantiating this Join Map without inheriting from it + /// + /// Join this join map will start at + public DmpsMicrophoneControllerJoinMap(uint joinStart) + : this(joinStart, typeof(DmpsMicrophoneControllerJoinMap)) + { + } + + /// + /// Constructor to use when extending this Join map + /// + /// Join this join map will start at + /// Type of the child join map + protected DmpsMicrophoneControllerJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 3c7a6c31..cdf6406c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -131,6 +131,7 @@ + diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index c2cd741f..97c582b3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -175,6 +175,11 @@ namespace PepperDash.Essentials.DM if (MasterVolumeLevel != null) { SetUpDmpsAudioOutputJoins(trilist, MasterVolumeLevel, joinMap.MasterVolumeLevel.JoinNumber); + var mixer = MasterVolumeLevel as DmpsAudioOutputWithMixer; + if (mixer != null) + { + trilist.SetUShortSigAction(3, mixer.RecallPreset); + } } if (SourceVolumeLevel != null) @@ -253,6 +258,12 @@ namespace PepperDash.Essentials.DM VolumeLevelScaledFeedback.FireUpdate(); } } + + public void RecallPreset(ushort preset) + { + Mixer.PresetNumber.UShortValue = preset; + Mixer.RecallPreset(); + } } public class DmpsAudioOutput : IBasicVolumeWithFeedback diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs new file mode 100644 index 00000000..55615bcc --- /dev/null +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + + +namespace PepperDash.Essentials.DM +{ + /// + /// Exposes the volume levels for microphones DMPS3 chassis + /// + public class DmpsMicrophoneController + { + private Dictionary Mics; + + public DmpsMicrophoneController(CrestronControlSystem dmps) + { + Debug.Console(2, "Creating Dmps Microphone Controller"); + Mics = new Dictionary(); + + foreach (var mic in dmps.Microphones) + { + Debug.Console(0, "Dmps Microphone Controller Adding Mic: {0} Name: {1}", mic.ID, mic.Name); + var dmpsMic = new DmpsMicrophone("processor-microphone" + mic.ID, mic.Name, mic); + + DeviceManager.AddDevice(dmpsMic); + Mics.Add(mic.ID, dmpsMic); + } + + dmps.MicrophoneChange += new MicrophoneChangeEventHandler(Dmps_MicrophoneChange); + } + + void Dmps_MicrophoneChange(MicrophoneBase mic, GenericEventArgs args) + { + Debug.Console(2, "Dmps Microphone Controller Index: {0} EventId: {1}", mic.ID, args.EventId.ToString()); + + if(Mics.ContainsKey(mic.ID)) + { + Mics[mic.ID].Event(); + } + } + } + + public class DmpsMicrophone : EssentialsBridgeableDevice, IBasicVolumeWithFeedback + { + MicrophoneBase Mic; + + private bool EnableVolumeSend; + private ushort VolumeLevelInput; + protected short MinLevel { get; set; } + protected short MaxLevel { get; set; } + + public BoolFeedback MuteFeedback { get; private set; } + public IntFeedback VolumeLevelFeedback { get; private set; } + public IntFeedback VolumeLevelScaledFeedback { get; private set; } + public StringFeedback NameFeedback { get; private set; } + + Action MuteOnAction; + Action MuteOffAction; + + public DmpsMicrophone(string key, string name, MicrophoneBase mic) : base(key, name) + { + Mic = mic; + VolumeLevelInput = 0; + EnableVolumeSend = false; + MinLevel = 0; + MaxLevel = 600; + + MuteFeedback = new BoolFeedback(new Func(() => Mic.MuteOnFeedBack.BoolValue)); + VolumeLevelFeedback = new IntFeedback(new Func(() => Mic.GainFeedBack.UShortValue)); + VolumeLevelScaledFeedback = new IntFeedback(new Func(() => ScaleVolumeFeedback(VolumeLevelFeedback.UShortValue))); + NameFeedback = new StringFeedback(new Func(() => "Microphone " + Mic.ID)); + MuteOnAction = new Action(Mic.MuteOn); + MuteOffAction = new Action(Mic.MuteOff); + + VolumeLevelFeedback.FireUpdate(); + VolumeLevelScaledFeedback.FireUpdate(); + NameFeedback.FireUpdate(); + MuteFeedback.FireUpdate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new DmpsMicrophoneControllerJoinMap(joinStart); + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + else + { + Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); + } + + Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.MicGain.JoinNumber]); + VolumeLevelScaledFeedback.LinkInputSig(trilist.UShortInput[joinMap.MicGainScaled.JoinNumber ]); + MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]); + MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]); + NameFeedback.LinkInputSig(trilist.StringInput[joinMap.MicName.JoinNumber]); + + trilist.SetUShortSigAction(joinMap.MicGain.JoinNumber, SetVolume); + trilist.SetUShortSigAction(joinMap.MicGainScaled.JoinNumber, SetVolumeScaled); + trilist.SetBoolSigAction(joinMap.MicGainScaledSend.JoinNumber, SendScaledVolume); + trilist.SetSigTrueAction(joinMap.MicMuteOn.JoinNumber, MuteOnAction); + trilist.SetSigTrueAction(joinMap.MicMuteOff.JoinNumber, MuteOffAction); + } + + public void Event() + { + VolumeLevelFeedback.FireUpdate(); + VolumeLevelScaledFeedback.FireUpdate(); + MuteFeedback.FireUpdate(); + } + + public void SetVolumeScaled(ushort level) + { + VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); + if (EnableVolumeSend == true) + { + Mic.Gain.UShortValue = VolumeLevelInput; + } + } + + public ushort ScaleVolumeFeedback(ushort level) + { + short signedLevel = (short)level; + return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); + } + + public void SendScaledVolume(bool pressRelease) + { + EnableVolumeSend = pressRelease; + if (pressRelease == false) + { + SetVolumeScaled(VolumeLevelInput); + } + } + + #region IBasicVolumeWithFeedback Members + + public void SetVolume(ushort level) + { + Mic.Gain.UShortValue = level; + } + + public void MuteOn() + { + MuteOnAction(); + } + + public void MuteOff() + { + MuteOffAction(); + } + + #endregion + + #region IBasicVolumeControls Members + + public void VolumeUp(bool pressRelease) + { + } + + public void VolumeDown(bool pressRelease) + { + } + + public void MuteToggle() + { + if (MuteFeedback.BoolValue) + MuteOff(); + else + MuteOn(); + } + + #endregion + } +} \ 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 35c83f2c..b1c8b532 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -60,6 +60,7 @@ namespace PepperDash.Essentials.DM public Dictionary InputNames { get; set; } public Dictionary OutputNames { get; set; } public Dictionary VolumeControls { get; private set; } + public DmpsMicrophoneController Microphones { get; private set; } public const int RouteOffTime = 500; Dictionary RouteOffTimers = new Dictionary(); @@ -192,6 +193,8 @@ namespace PepperDash.Essentials.DM SetupOutputCards(); SetupInputCards(); + + Microphones = new DmpsMicrophoneController(Dmps); } public override bool CustomActivate() 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 4f674d9d..cef61b1a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj @@ -93,6 +93,7 @@ + From 0745f301770f8aca84e416d0dc00d93107775b80 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Mon, 13 Dec 2021 15:26:50 -0500 Subject: [PATCH 447/480] Fixes dmps microphone event ids --- .../Chassis/DmpsMicrophoneController.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs index 55615bcc..30b2cfab 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsMicrophoneController.cs @@ -42,7 +42,7 @@ namespace PepperDash.Essentials.DM if(Mics.ContainsKey(mic.ID)) { - Mics[mic.ID].Event(); + Mics[mic.ID].Event(args.EventId); } } } @@ -113,11 +113,17 @@ namespace PepperDash.Essentials.DM trilist.SetSigTrueAction(joinMap.MicMuteOff.JoinNumber, MuteOffAction); } - public void Event() + public void Event(int id) { - VolumeLevelFeedback.FireUpdate(); - VolumeLevelScaledFeedback.FireUpdate(); - MuteFeedback.FireUpdate(); + if (id == MicrophoneEventIds.MuteOnFeedBackEventId) + { + MuteFeedback.FireUpdate(); + } + else if (id == MicrophoneEventIds.GainFeedBackEventId) + { + VolumeLevelFeedback.FireUpdate(); + VolumeLevelScaledFeedback.FireUpdate(); + } } public void SetVolumeScaled(ushort level) From d12a2a19a8de7cba8006120a050fb02f64d115db Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Tue, 14 Dec 2021 09:34:20 -0600 Subject: [PATCH 448/480] feat: added LoginFailed join to bridge map for passwords. --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 32 +++++++++++++++++++ .../VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs | 19 +++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index b6713b6a..862e8f82 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2298,6 +2298,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); } + // TODO [ ] Issue #868 + PasswordRequired += (device, args) => + { + if (args.LoginAttemptCancelled) + { + trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, false); + return; + } + + if (!string.IsNullOrEmpty(args.Message)) + { + trilist.SetString(joinMap.PasswordPromptMessage.JoinNumber, args.Message); + } + + if (args.LoginAttemptFailed) + { + trilist.SetBool(joinMap.PasswordLoginFailed.JoinNumber, true); + return; + } + + trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, true); + }; + // TODO [ ] Issue #868 MeetingInfoChanged += (device, args) => { @@ -2315,6 +2338,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting); trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting); + + // TODO [ ] Issue #868 + // not sure if this would be needed here, should be handled by VideoCodecBase.cs LinkToApi methods + //DirectoryResultReturned += (device, args) => + //{ + // // add logic here if necessary when event fires + + //}; + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs index 68012fc7..b977cfe3 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoomJoinMap.cs @@ -38,12 +38,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom JoinType = eJoinType.Digital }); + // TODO [ ] Issue #868 + [JoinName("PassowrdLoginFailed")] + public JoinDataComplete PasswordLoginFailed = new JoinDataComplete( + new JoinData + { + JoinNumber = 8, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "FB Indicates the password entered is incorrect", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + // TODO [ ] Issue #868 [JoinName("WaitingForHost")] public JoinDataComplete WaitingForHost = new JoinDataComplete( new JoinData { - JoinNumber = 8, + JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata @@ -58,7 +73,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public JoinDataComplete IsHost = new JoinDataComplete( new JoinData { - JoinNumber = 9, + JoinNumber = 10, JoinSpan = 1 }, new JoinMetadata From 72a5491309e35a671330e2fb77d61c6ed0fd00be Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 15 Dec 2021 12:04:15 -0700 Subject: [PATCH 449/480] feat(essentails): #869 Adds Apple TV Driver --- IR Drivers/Apple_AppleTV_4th_Gen_Essentials.ir | Bin 0 -> 688 bytes .../Streaming/AppleTV.cs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 IR Drivers/Apple_AppleTV_4th_Gen_Essentials.ir diff --git a/IR Drivers/Apple_AppleTV_4th_Gen_Essentials.ir b/IR Drivers/Apple_AppleTV_4th_Gen_Essentials.ir new file mode 100644 index 0000000000000000000000000000000000000000..f112ee8b727f116f905ee390f4109284a89cf03c GIT binary patch literal 688 zcma)(T}uK%6o%)Vncb0!1uqi4Te=Ocm7)?avWyT6#5KF+sixOT_E z5B3Rq;;U%4Y`4+Y>vmIgbW`;1MURaDQX>Sw4#FkHGlu61T&Wo6N?#evcQ!^~V+yJ7 z#eK7qE|;q5V{>o8$gCUN8Do2AEB*s=3@9*AKm{(lRf=hqmc_NpS=DY?E>{j5SM*f% zNI3l^UTHTT)+&wuoxtBbSSy$!%OpW|NrBYKBb+Kvnj?Tx>RqqMBYWu*cHRfxjOB5L zJ@MJ$JXX&8tjsxK=?okA4zcK^&p{s6MUTowQT literal 0 HcmV?d00001 diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs index 709afb72..07df3602 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Streaming/AppleTV.cs @@ -19,7 +19,7 @@ namespace PepperDash.Essentials.Devices.Common public class AppleTV : EssentialsBridgeableDevice, IDPad, ITransport, IUiDisplayInfo, IRoutingOutputs { public IrOutputPortController IrPort { get; private set; } - public const string StandardDriverName = "Apple AppleTV-v2.ir"; + public const string StandardDriverName = "Apple_AppleTV_4th_Gen_Essentials.ir"; public uint DisplayUiType { get { return DisplayUiConstants.TypeAppleTv; } } public AppleTV(string key, string name, IrOutputPortController portCont) From 5fd8e4bc2be265d3cedd626f272e7d838fa61dad Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 15 Dec 2021 15:47:15 -0700 Subject: [PATCH 450/480] fix(essentials): Fixes sharing content feedback FireUpdate() call and prevents Vtc1 room default call route from being recalled if already sharing --- .../Room/Types/EssentialsHuddleVtc1Room.cs | 8 ++++++++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 8 ++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs index 42a4a353..7a8430c9 100644 --- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs +++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs @@ -427,6 +427,14 @@ namespace PepperDash.Essentials /// public bool RunDefaultCallRoute() { + Debug.Console(2, this, "RunDefaultCallRoute() Currently Sharing Content: {0}", VideoCodec.SharingContentIsOnFeedback.BoolValue); + + if (VideoCodec.SharingContentIsOnFeedback.BoolValue) + { + Debug.Console(2, this, "Currently sharing content. Ignoring request to run default call route."); + return false; + } + RunRouteAction(DefaultCodecRouteString); return true; } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index f894141c..8dac777c 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -421,8 +421,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate; CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus; CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; - CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; + CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = () => + { + SharingContentIsOnFeedback.FireUpdate(); + FarEndIsSharingContentFeedback.FireUpdate(); + }; + try { CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; From 156d58f42fa87134e25e0164721a6d7d7cac8bd3 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 22 Dec 2021 09:27:33 -0500 Subject: [PATCH 451/480] Fixes program info for slots 2-10 on join map if joinOffset is > 0 --- .../Bridges/JoinMaps/SystemMonitorJoinMap.cs | 2 +- .../Monitoring/SystemMonitorController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs index e07ad275..363d389b 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs @@ -45,7 +45,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinMetadata { Description = "Processor Last Boot", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); [JoinName("ProgramOffsetJoin")] - public JoinDataComplete ProgramOffsetJoin = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 }, + public JoinDataComplete ProgramOffsetJoin = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 5 }, new JoinMetadata { Description = "All Program Data is offset between slots by 5 - First Joins Start at 11", JoinCapabilities = eJoinCapabilities.None, JoinType = eJoinType.None }); [JoinName("ProgramStart")] diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index ec18c995..056686b1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -301,7 +301,7 @@ namespace PepperDash.Essentials.Core.Monitoring p.Value.AggregatedProgramInfoFeedback.LinkInputSig( trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo.JoinNumber]); - programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber; + programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinSpan; } } From 661bf41de58d0430a504df068254aa659a3e6726 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 4 Jan 2022 15:29:20 -0700 Subject: [PATCH 452/480] fix(essentials): Removed leftover merge text that should not have been there --- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 2d4644bd..6c12a21a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2214,14 +2214,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom { layoutsCodec.LayoutInfoChanged += (o, a) => { - trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Gallery - == - (a.AvailableLayouts & - zConfiguration.eLayoutStyle.Gallery)); - trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Speaker - == - (a.AvailableLayouts & - zConfiguration.eLayoutStyle.Speaker)); + trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, + zConfiguration.eLayoutStyle.Gallery == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery)); + + trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, + zConfiguration.eLayoutStyle.Speaker == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker)); + + + trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, zConfiguration.eLayoutStyle.Strip == (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip)); @@ -2338,8 +2338,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting); trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting); -<<<<<<< HEAD - // TODO [ ] Issue #868 // not sure if this would be needed here, should be handled by VideoCodecBase.cs LinkToApi methods //DirectoryResultReturned += (device, args) => @@ -2348,7 +2346,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //}; -======= + // TODO [ ] Issue #868 trilist.SetStringSigAction(joinMap.SubmitPassword.JoinNumber, SubmitPassword); PasswordRequired += (devices, args) => @@ -2373,8 +2371,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetBool(joinMap.PasswordIncorrect.JoinNumber, args.LastAttemptWasIncorrect); trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, true); }; - ->>>>>>> 2f901b9fc4cd67fd1e06c8bcda396e9c8c57d6c1 + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; From 458de1aaa6dd6bb7b4fa8fe913d37b5794b35c75 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 4 Jan 2022 15:31:47 -0700 Subject: [PATCH 453/480] fix(essentials): Remove TODOs --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 2 +- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index d33c3707..c2b08f89 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -375,7 +375,7 @@ Params: {2}" { bridge.AddJoinMap(Key, joinMap); } - uint i; + if (_config.IsPrimary) { Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring"); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 6c12a21a..8fc40f29 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -2276,7 +2276,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u); } - // TODO: #714 [ ] LinkZoomRoomToApi >> layoutSizeCoodec var layoutSizeCodec = this as IHasSelfviewSize; if (layoutSizeCodec != null) { @@ -2298,7 +2297,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom layoutSizeCodec.SelfviewPipSizeFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetSelfviewPipSize.JoinNumber]); } - // TODO [ ] Issue #868 PasswordRequired += (device, args) => { if (args.LoginAttemptCancelled) @@ -2321,7 +2319,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom trilist.SetBool(joinMap.ShowPasswordPrompt.JoinNumber, true); }; - // TODO [ ] Issue #868 MeetingInfoChanged += (device, args) => { trilist.SetString(joinMap.MeetingInfoId.JoinNumber, args.Info.Id); @@ -2333,12 +2330,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //trilist.SetString(joinMap.CurrentSource.JoinNumber, args.Info.ShareStatus); }; - // TODO [ ] Issue #868 trilist.SetSigTrueAction(joinMap.StartMeetingNow.JoinNumber, () => StartMeeting(0)); trilist.SetSigTrueAction(joinMap.ShareOnlyMeeting.JoinNumber, StartSharingOnlyMeeting); trilist.SetSigTrueAction(joinMap.StartNormalMeetingFromSharingOnlyMeeting.JoinNumber, StartNormalMeetingFromSharingOnlyMeeting); - // TODO [ ] Issue #868 // not sure if this would be needed here, should be handled by VideoCodecBase.cs LinkToApi methods //DirectoryResultReturned += (device, args) => //{ @@ -2347,7 +2342,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom //}; - // TODO [ ] Issue #868 trilist.SetStringSigAction(joinMap.SubmitPassword.JoinNumber, SubmitPassword); PasswordRequired += (devices, args) => { From e275d747f84baa9aeb33aab86748dad62985d897 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 5 Jan 2022 11:58:47 -0500 Subject: [PATCH 454/480] Fixes issue with vsync activation on dmps 4k airmedia input --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index b1c8b532..8c845628 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -60,7 +60,6 @@ namespace PepperDash.Essentials.DM public Dictionary InputNames { get; set; } public Dictionary OutputNames { get; set; } public Dictionary VolumeControls { get; private set; } - public DmpsMicrophoneController Microphones { get; private set; } public const int RouteOffTime = 500; Dictionary RouteOffTimers = new Dictionary(); @@ -193,8 +192,6 @@ namespace PepperDash.Essentials.DM SetupOutputCards(); SetupInputCards(); - - Microphones = new DmpsMicrophoneController(Dmps); } public override bool CustomActivate() @@ -412,13 +409,13 @@ namespace PepperDash.Essentials.DM var ioSlot = i; var ioSlotJoin = ioSlot - 1; - if (VideoInputSyncFeedbacks[ioSlot] != null) + if (VideoInputSyncFeedbacks.ContainsKey(ioSlot) && VideoInputSyncFeedbacks[ioSlot] != null) { VideoInputSyncFeedbacks[ioSlot].LinkInputSig( trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); } - if (InputNameFeedbacks[ioSlot] != null) + if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null) { InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); } @@ -445,7 +442,7 @@ namespace PepperDash.Essentials.DM }); - if (InputEndpointOnlineFeedbacks[ioSlot] != null) + if (InputEndpointOnlineFeedbacks.ContainsKey(ioSlot) && InputEndpointOnlineFeedbacks[ioSlot] != null) { InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); @@ -542,7 +539,7 @@ namespace PepperDash.Essentials.DM InputEndpointOnlineFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.EndpointOnlineFeedback); - if (inputCard.VideoDetectedFeedback != null) + if (inputCard.VideoDetectedFeedback != null && inputCard.VideoDetectedFeedback.Supported) { VideoInputSyncFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.VideoDetectedFeedback.BoolValue); } From 5816c3cafea33a357c89cc4aff441bece235411a Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Wed, 5 Jan 2022 12:05:12 -0500 Subject: [PATCH 455/480] Restore microphones to DMPS controller --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 8c845628..021ee246 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -60,6 +60,7 @@ namespace PepperDash.Essentials.DM public Dictionary InputNames { get; set; } public Dictionary OutputNames { get; set; } public Dictionary VolumeControls { get; private set; } + public DmpsMicrophoneController Microphones { get; private set; } public const int RouteOffTime = 500; Dictionary RouteOffTimers = new Dictionary(); @@ -192,6 +193,8 @@ namespace PepperDash.Essentials.DM SetupOutputCards(); SetupInputCards(); + + Microphones = new DmpsMicrophoneController(Dmps); } public override bool CustomActivate() From 4650d17695f78a04858dfa63c51161208152b947 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 6 Jan 2022 11:17:58 -0500 Subject: [PATCH 456/480] Change dmps type detection to use eSystemControlType enum --- .../Chassis/DmpsRoutingController.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 021ee246..43f67d41 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -124,18 +124,16 @@ namespace PepperDash.Essentials.DM { Dmps = Global.ControlSystem; - switch (name.Replace("-", "").Replace("c", "").Replace("C", "")) + switch (systemControl.SystemControlType) { - case "dmps34k50": - case "dmps34k100": - case "dmps34k150": + case eSystemControlType.Dmps34K150CSystemControl: SystemControl = systemControl as Dmps34K150CSystemControl; Dmps4kType = true; break; - case "dmps34k200": - case "dmps34k250": - case "dmps34k300": - case "dmps34k350": + case eSystemControlType.Dmps34K200CSystemControl: + case eSystemControlType.Dmps34K250CSystemControl: + case eSystemControlType.Dmps34K300CSystemControl: + case eSystemControlType.Dmps34K350CSystemControl: SystemControl = systemControl as Dmps34K300CSystemControl; Dmps4kType = true; break; @@ -144,6 +142,7 @@ namespace PepperDash.Essentials.DM Dmps4kType = false; break; } + Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Dmps4kType); InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); From 8e46d575e4a3a8fc42d7537d49f7c078753f6a8b Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Jan 2022 12:24:36 -0700 Subject: [PATCH 457/480] feat(essentials): Adds JsonProperty attribute tags --- .../Essentials Devices Common/Codec/iHasDirectory.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs index b2ccb29c..642f03d0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasDirectory.cs @@ -69,6 +69,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec [JsonProperty("directoryResults")] public List CurrentDirectoryResults { get; private set; } + [JsonProperty("contacts")] public List Contacts { get @@ -77,6 +78,7 @@ namespace PepperDash.Essentials.Devices.Common.Codec } } + [JsonProperty("folders")] public List Folders { get From ce785ceb25efa44a9b7f0fa3d37c9fab6b251022 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 6 Jan 2022 16:47:11 -0500 Subject: [PATCH 458/480] Fixes DMPS input name feedback on DMPS-4k. Need to check for NullStringOutputSig which was causing an exception --- .../Chassis/DmpsAudioOutputController.cs | 5 +++++ .../Chassis/DmpsRoutingController.cs | 20 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 97c582b3..4f8d8f02 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -71,6 +71,11 @@ namespace PepperDash.Essentials.DM Debug.Console(2, this, "Dmps Audio Controller Event Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); switch (args.EventId) { + case DMOutputEventIds.OutputVuFeedBackEventId: + { + //Frequently called event that isn't needed + break; + } case DMOutputEventIds.MasterVolumeFeedBackEventId: { MasterVolumeLevel.VolumeLevelFeedback.FireUpdate(); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 43f67d41..78ed8050 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -224,6 +224,24 @@ namespace PepperDash.Essentials.DM { x.Value.FireUpdate(); } + foreach (var x in InputNameFeedbacks) + { + Debug.Console(0, this, "input {0} name update", x.Key); + x.Value.FireUpdate(); + } + foreach (var x in OutputNameFeedbacks) + { + Debug.Console(0, this, "output {0} name update", x.Key); + x.Value.FireUpdate(); + } + foreach (var x in OutputVideoRouteNameFeedbacks) + { + x.Value.FireUpdate(); + } + foreach (var x in OutputAudioRouteNameFeedbacks) + { + x.Value.FireUpdate(); + } foreach (var x in OutputEndpointOnlineFeedbacks) { x.Value.FireUpdate(); @@ -548,7 +566,7 @@ namespace PepperDash.Essentials.DM InputNameFeedbacks[inputCard.Number] = new StringFeedback(() => { - if (inputCard.NameFeedback != null && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue)) + if (inputCard.NameFeedback != null && inputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue)) { Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue); return inputCard.NameFeedback.StringValue; From c8b1808513082e566daa7b1e52ff09b4fa9006d8 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 6 Jan 2022 16:49:00 -0500 Subject: [PATCH 459/480] Fixes output name feedback on DMPS-4K --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 78ed8050..70c57d99 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -513,7 +513,7 @@ namespace PepperDash.Essentials.DM OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() => { - if (outputCard.NameFeedback != null && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) + if (outputCard.NameFeedback != null && outputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) { Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue); return outputCard.NameFeedback.StringValue; From acdd9bb674addb7b4d1beb1ec8492f1a86b1e742 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 6 Jan 2022 16:58:38 -0500 Subject: [PATCH 460/480] Removes some unneeded post activation stuff from testing --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 70c57d99..327b01d0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -226,19 +226,9 @@ namespace PepperDash.Essentials.DM } foreach (var x in InputNameFeedbacks) { - Debug.Console(0, this, "input {0} name update", x.Key); x.Value.FireUpdate(); } foreach (var x in OutputNameFeedbacks) - { - Debug.Console(0, this, "output {0} name update", x.Key); - x.Value.FireUpdate(); - } - foreach (var x in OutputVideoRouteNameFeedbacks) - { - x.Value.FireUpdate(); - } - foreach (var x in OutputAudioRouteNameFeedbacks) { x.Value.FireUpdate(); } From 2d64e49f8ee3f1521435aa8b59f81e3650497d92 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 6 Jan 2022 15:32:47 -0700 Subject: [PATCH 461/480] feat(essentials): Adds JsonProperty attributes to LightingScene --- .../PepperDashEssentialsBase/Lighting/LightingBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs index eeb25531..569d2005 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs @@ -113,9 +113,12 @@ namespace PepperDash.Essentials.Core.Lighting public class LightingScene { + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; set; } + [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] public string ID { get; set; } bool _IsActive; + [JsonProperty("isActive", NullValueHandling = NullValueHandling.Ignore)] public bool IsActive { get @@ -128,6 +131,8 @@ namespace PepperDash.Essentials.Core.Lighting IsActiveFeedback.FireUpdate(); } } + + [JsonIgnore] public BoolFeedback IsActiveFeedback { get; set; } public LightingScene() From 0d4d86e0e677c64e5ef7f384bcf295c136bce5ff Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 7 Jan 2022 14:59:54 -0700 Subject: [PATCH 462/480] Adds Discord link to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index efb706c0..0fe4f075 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,10 @@ Utilization of Essentials Framework falls into the following categories: For detailed documentation, see the [Wiki](https://github.com/PepperDash/EssentialsFramework/wiki). +## Support + +* Check out our [Discord Server](https://discord.gg/rWyeRH3K) + ## How-To (Getting Started) See [Getting Started](https://github.com/PepperDash/Essentials/wiki/Get-started#how-to-get-started) From 7d89f51dcf29f0dfde3e2ffb8e2013737aabde16 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Mon, 10 Jan 2022 13:20:10 -0500 Subject: [PATCH 463/480] Adds support for DMPS-4K audio input names being shifted by 5 for aux inputs. --- .../JoinMaps/DmpsRoutingControllerJoinMap.cs | 38 +++++++++++++++++++ .../Chassis/DmpsRoutingController.cs | 21 ++++++++++ 2 files changed, 59 insertions(+) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs index 7ed99c61..549d01fa 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -44,6 +44,44 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete OutputNames = new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Output Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("InputVideoNames")] + public JoinDataComplete InputVideoNames = + new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 32 }, + new JoinMetadata + { + Description = "Video Input Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + + [JoinName("InputAudioNames")] + public JoinDataComplete InputAudioNames = + new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 32 }, + new JoinMetadata + { + Description = "Audio Input Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + [JoinName("OutputVideoNames")] + public JoinDataComplete OutputVideoNames = + new JoinDataComplete(new JoinData { JoinNumber = 901, JoinSpan = 32 }, + new JoinMetadata + { + Description = "Video Output Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + [JoinName("OutputAudioNames")] + public JoinDataComplete OutputAudioNames = + new JoinDataComplete(new JoinData { JoinNumber = 1101, JoinSpan = 32 }, + new JoinMetadata + { + Description = "Audio Output Name", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Serial + }); + [JoinName("OutputCurrentVideoInputNames")] public JoinDataComplete OutputCurrentVideoInputNames = new JoinDataComplete(new JoinData { JoinNumber = 2001, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Video Output Currently Routed Video Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 327b01d0..bf72afdf 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -391,6 +391,8 @@ namespace PepperDash.Essentials.DM if (OutputNameFeedbacks[ioSlot] != null) { OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputVideoNames.JoinNumber + ioSlotJoin]); + OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]); } if (OutputVideoRouteNameFeedbacks[ioSlot] != null) { @@ -412,6 +414,14 @@ namespace PepperDash.Essentials.DM private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap) { + if (Dmps4kType) + { + //DMPS-4K audio inputs 1-5 are aux inputs + for (uint i = 1; i <= 5; i++) + { + trilist.StringInput[joinMap.InputAudioNames.JoinNumber + i - 1].StringValue = String.Format("Aux Input {0}", i); + } + } for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++) { Debug.Console(2, this, "Linking Input Card {0}", i); @@ -428,6 +438,17 @@ namespace PepperDash.Essentials.DM if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null) { InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputVideoNames.JoinNumber + ioSlotJoin]); + + if (Dmps4kType) + { + //DMPS-4K Audio Inputs are offset by 5 + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin + 5]); + } + else + { + InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin]); + } } trilist.SetStringSigAction(joinMap.InputNames.JoinNumber + ioSlotJoin, s => From 60ed2ea537fba9db0c750ba68e7901962777edcf Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Tue, 11 Jan 2022 15:26:39 -0500 Subject: [PATCH 464/480] Fixes DMPS preset recall. Adds event to catch vumeter event ID and exit (can spam the event handler) --- .../Essentials_DM/Chassis/DmpsAudioOutputController.cs | 5 +++-- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs index 4f8d8f02..751c1a5a 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsAudioOutputController.cs @@ -74,7 +74,7 @@ namespace PepperDash.Essentials.DM case DMOutputEventIds.OutputVuFeedBackEventId: { //Frequently called event that isn't needed - break; + return; } case DMOutputEventIds.MasterVolumeFeedBackEventId: { @@ -183,7 +183,7 @@ namespace PepperDash.Essentials.DM var mixer = MasterVolumeLevel as DmpsAudioOutputWithMixer; if (mixer != null) { - trilist.SetUShortSigAction(3, mixer.RecallPreset); + trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset); } } @@ -266,6 +266,7 @@ namespace PepperDash.Essentials.DM public void RecallPreset(ushort preset) { + Debug.Console(1, "DMPS Recalling Preset {0}", preset); Mixer.PresetNumber.UShortValue = preset; Mixer.RecallPreset(); } diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index bf72afdf..e3ded3e3 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -895,6 +895,12 @@ namespace PepperDash.Essentials.DM { Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString()); + if (args.EventId == DMOutputEventIds.OutputVuFeedBackEventId) + { + //Frequently called event that isn't needed + return; + } + var output = args.Number; DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput; From 99580ae8b54b0deebc08cc4a3a2c47d99141488f Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Thu, 13 Jan 2022 08:44:23 -0600 Subject: [PATCH 465/480] fix: Added MeetingsToDisplay analog join to join map to take in number of MeetingsToDisplay via the xsig bridge and provide feedback of property. fix: Added MeetingsToDisplay property with backer field and feedback. Updated LinkVideoCodecScheduleToApi method with new property. Updated Constructor to instantiate the feedback property. --- .../JoinMaps/VideoCodecControllerJoinMap.cs | 17 ++++++++- .../VideoCodec/VideoCodecBase.cs | 38 ++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs index dcb66a2e..21b88ed3 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/VideoCodecControllerJoinMap.cs @@ -922,7 +922,22 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps - #region Analog + #region Analog + + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + [JoinName("MeetingsToDisplay")] + public JoinDataComplete MeetingsToDisplay = new JoinDataComplete( + new JoinData + { + JoinNumber = 40, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Set/FB the number of meetings to display via the bridge xsig; default: 3 meetings.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Analog + }); [JoinName("MinutesBeforeMeetingStart")] public JoinDataComplete MinutesBeforeMeetingStart = new JoinDataComplete( 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 f0221a21..7db58b1e 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 @@ -41,6 +41,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + MeetingsToDisplayFeedback = new IntFeedback(() => MeetingsToDisplay); + InputPorts = new RoutingPortCollection(); OutputPorts = new RoutingPortCollection(); @@ -792,6 +795,10 @@ ScreenIndexIsPinnedTo: {8} (a{17}) } }; + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + trilist.SetUShortSigAction(joinMap.MeetingsToDisplay.JoinNumber, m => MeetingsToDisplay = m); + MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); + trilist.OnlineStatusChange += (device, args) => { if (!args.DeviceOnLine) return; @@ -799,6 +806,8 @@ ScreenIndexIsPinnedTo: {8} (a{17}) // TODO [ ] Issue #868 trilist.SetString(joinMap.Schedule.JoinNumber, "\xFC"); UpdateMeetingsList(codec, trilist, joinMap); + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + MeetingsToDisplayFeedback.LinkInputSig(trilist.UShortInput[joinMap.MeetingsToDisplay.JoinNumber]); }; } @@ -832,17 +841,34 @@ ScreenIndexIsPinnedTo: {8} (a{17}) }; } + + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + private int _meetingsToDisplay = 3; + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + protected int MeetingsToDisplay + { + get { return _meetingsToDisplay; } + set { + _meetingsToDisplay = (ushort) (value == 0 ? 3 : value); + MeetingsToDisplayFeedback.FireUpdate(); + } + } + + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + public IntFeedback MeetingsToDisplayFeedback { get; set; } + private string UpdateMeetingsListXSig(List meetings) { - const int maxMeetings = 3; + // TODO [ ] hotfix/videocodecbase-max-meeting-xsig-set + //const int _meetingsToDisplay = 3; const int maxDigitals = 2; const int maxStrings = 7; const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings * maxMeetings; //15 + var digitalIndex = maxStrings * _meetingsToDisplay; //15 var stringIndex = 0; var meetingIndex = 0; - var tokenArray = new XSigToken[maxMeetings * offset]; + var tokenArray = new XSigToken[_meetingsToDisplay * offset]; /* * Digitals * IsJoinable - 1 @@ -865,7 +891,7 @@ ScreenIndexIsPinnedTo: {8} (a{17}) if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; - if (meetingIndex >= maxMeetings * offset) + if (meetingIndex >= _meetingsToDisplay * offset) { Debug.Console(2, this, "Max Meetings reached"); break; @@ -890,10 +916,10 @@ ScreenIndexIsPinnedTo: {8} (a{17}) stringIndex += maxStrings; } - while (meetingIndex < maxMeetings * offset) + while (meetingIndex < _meetingsToDisplay * offset) { Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", - meetingIndex, maxMeetings * offset); + meetingIndex, _meetingsToDisplay * offset); //digitals tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); From 482bef435ac3d4d1d731b71cc000aa04b201b393 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 19 Jan 2022 11:40:12 -0700 Subject: [PATCH 466/480] fix(essentials): #887 Adds missing "crestronapp" typename to factory --- PepperDashEssentials/UI/EssentialsTouchpanelController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs index 9a8006e5..72e22b9c 100644 --- a/PepperDashEssentials/UI/EssentialsTouchpanelController.cs +++ b/PepperDashEssentials/UI/EssentialsTouchpanelController.cs @@ -213,7 +213,7 @@ namespace PepperDash.Essentials { public EssentialsTouchpanelControllerFactory() { - TypeNames = new List() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" }; + TypeNames = new List() { "crestronapp", "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" }; } public override EssentialsDevice BuildDevice(DeviceConfig dc) From 52c589b56b03666fc48394a4285075d5478adc36 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 19 Jan 2022 11:50:18 -0700 Subject: [PATCH 467/480] fix(essentials): #888 fixes legacy typename in example config files --- .../configurationFile-HuddleSpace-2-Source.json | 2 +- .../configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PepperDashEssentials/Example Configuration/EssentialsHuddleSpaceRoom/configurationFile-HuddleSpace-2-Source.json b/PepperDashEssentials/Example Configuration/EssentialsHuddleSpaceRoom/configurationFile-HuddleSpace-2-Source.json index 3e43dac6..d3ce3275 100644 --- a/PepperDashEssentials/Example Configuration/EssentialsHuddleSpaceRoom/configurationFile-HuddleSpace-2-Source.json +++ b/PepperDashEssentials/Example Configuration/EssentialsHuddleSpaceRoom/configurationFile-HuddleSpace-2-Source.json @@ -88,7 +88,7 @@ { "name": "Wireless Video", "key": "wePresent-1", - "type": "wePresent", + "type": "genericSource", "group": "genericSource", "uid": 9, "properties": { diff --git a/PepperDashEssentials/Example Configuration/EssentialsHuddleVtc1Room/configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json b/PepperDashEssentials/Example Configuration/EssentialsHuddleVtc1Room/configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json index 7cc97c47..1e5b66d2 100644 --- a/PepperDashEssentials/Example Configuration/EssentialsHuddleVtc1Room/configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json +++ b/PepperDashEssentials/Example Configuration/EssentialsHuddleVtc1Room/configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json @@ -114,7 +114,7 @@ { "name": "Wireless Video", "key": "wePresent-1", - "type": "wePresent", + "type": "genericSource", "properties": {}, "group": "genericSource", "uid": 3 From dba60cfd76827fde15a9688e0a998ff556ce611c Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 19 Jan 2022 11:51:26 -0700 Subject: [PATCH 468/480] fix(essentials): Fixes incorrect logical comparison for processor prompt with config value --- PepperDashEssentials/ControlSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index ef1a9378..84018a15 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -343,7 +343,7 @@ namespace PepperDash.Essentials { var prompt = Global.ControlSystem.ControllerPrompt; - var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) && + var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) || String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase); if (!typeMatch) From 56fa88a956d37259f1be94f55ea0b0fdc53ec9e1 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 20 Jan 2022 16:56:57 -0500 Subject: [PATCH 469/480] Adds front panel lock control for DMPS. Cleans up system power for DMPS which doesn't do anything on 4K models --- .../JoinMaps/DmpsRoutingControllerJoinMap.cs | 8 ++ .../Chassis/DmpsRoutingController.cs | 96 +++++++++---------- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs index 549d01fa..44917899 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmpsRoutingControllerJoinMap.cs @@ -16,6 +16,14 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete SystemPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 }, new JoinMetadata { Description = "DMPS System Power Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("FrontPanelLockOn")] + public JoinDataComplete FrontPanelLockOn = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 }, + new JoinMetadata { Description = "DMPS Front Panel Lock On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + + [JoinName("FrontPanelLockOff")] + public JoinDataComplete FrontPanelLockOff = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 }, + new JoinMetadata { Description = "DMPS Front Panel Lock Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); + [JoinName("VideoSyncStatus")] public JoinDataComplete VideoSyncStatus = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 }, new JoinMetadata { Description = "DM Input Video Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital }); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index e3ded3e3..056d6ec0 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -33,9 +33,11 @@ namespace PepperDash.Essentials.DM //IroutingNumericEvent public event EventHandler NumericSwitchChange; - //Feedback for DMPS System Power + //Feedback for DMPS System Control public BoolFeedback SystemPowerOnFeedback { get; private set; } public BoolFeedback SystemPowerOffFeedback { get; private set; } + public BoolFeedback FrontPanelLockOnFeedback { get; private set; } + public BoolFeedback FrontPanelLockOffFeedback { get; private set; } // Feedbacks for EssentialDM public Dictionary VideoOutputFeedbacks { get; private set; } @@ -129,6 +131,8 @@ namespace PepperDash.Essentials.DM case eSystemControlType.Dmps34K150CSystemControl: SystemControl = systemControl as Dmps34K150CSystemControl; Dmps4kType = true; + SystemPowerOnFeedback = new BoolFeedback(() => { return true; }); + SystemPowerOffFeedback = new BoolFeedback(() => { return false; }); break; case eSystemControlType.Dmps34K200CSystemControl: case eSystemControlType.Dmps34K250CSystemControl: @@ -136,10 +140,20 @@ namespace PepperDash.Essentials.DM case eSystemControlType.Dmps34K350CSystemControl: SystemControl = systemControl as Dmps34K300CSystemControl; Dmps4kType = true; + SystemPowerOnFeedback = new BoolFeedback(() => { return true; }); + SystemPowerOffFeedback = new BoolFeedback(() => { return false; }); break; default: SystemControl = systemControl as Dmps3SystemControl; Dmps4kType = false; + SystemPowerOnFeedback = new BoolFeedback(() => + { + return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue; + }); + SystemPowerOffFeedback = new BoolFeedback(() => + { + return ((Dmps3SystemControl)SystemControl).SystemPowerOffFeedBack.BoolValue; + }); break; } Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Dmps4kType); @@ -150,27 +164,13 @@ namespace PepperDash.Essentials.DM TxDictionary = new Dictionary(); RxDictionary = new Dictionary(); - SystemPowerOnFeedback = new BoolFeedback(() => + FrontPanelLockOnFeedback = new BoolFeedback(() => { - if (SystemControl is Dmps3SystemControl) - { - return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue; - } - else - { - return false; - } + return SystemControl.FrontPanelLockOnFeedback.BoolValue; }); - SystemPowerOffFeedback = new BoolFeedback(() => + FrontPanelLockOffFeedback = new BoolFeedback(() => { - if (SystemControl is Dmps3SystemControl) - { - return ((Dmps3SystemControl)SystemControl).SystemPowerOffFeedBack.BoolValue; - } - else - { - return false; - } + return SystemControl.FrontPanelLockOffFeedback.BoolValue; }); VideoOutputFeedbacks = new Dictionary(); @@ -237,6 +237,12 @@ namespace PepperDash.Essentials.DM x.Value.FireUpdate(); } + SystemPowerOnFeedback.FireUpdate(); + SystemPowerOffFeedback.FireUpdate(); + + FrontPanelLockOnFeedback.FireUpdate(); + FrontPanelLockOffFeedback.FireUpdate(); + return base.CustomActivate(); } @@ -279,22 +285,6 @@ namespace PepperDash.Essentials.DM EnableRouting = enable; } - public void SetPowerOn(bool a) - { - if (SystemControl is Dmps3SystemControl) - { - ((Dmps3SystemControl)SystemControl).SystemPowerOn(); - } - } - - public void SetPowerOff(bool a) - { - if (SystemControl is Dmps3SystemControl) - { - ((Dmps3SystemControl)SystemControl).SystemPowerOff(); - } - } - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { var joinMap = new DmpsRoutingControllerJoinMap(joinStart); @@ -315,20 +305,22 @@ namespace PepperDash.Essentials.DM Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - //Link up system - trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, SetPowerOn); - trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, SetPowerOff); - if (SystemPowerOnFeedback != null) + //Link up system power only for non-4k DMPS3 + if (SystemControl is Dmps3SystemControl) { - SystemPowerOnFeedback.LinkInputSig( - trilist.BooleanInput[joinMap.SystemPowerOn.JoinNumber]); - } - if (SystemPowerOffFeedback != null) - { - SystemPowerOffFeedback.LinkInputSig( - trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]); + trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, a => { if (a) { ((Dmps3SystemControl)SystemControl).SystemPowerOff(); } }); + trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, a => { if (a) { ((Dmps3SystemControl)SystemControl).SystemPowerOff(); } }); } + SystemPowerOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemPowerOn.JoinNumber]); + SystemPowerOffFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemPowerOff.JoinNumber]); + + trilist.SetBoolSigAction(joinMap.FrontPanelLockOn.JoinNumber, a => { if (a) {SystemControl.FrontPanelLockOn();}}); + trilist.SetBoolSigAction(joinMap.FrontPanelLockOff.JoinNumber, a => { if (a) {SystemControl.FrontPanelLockOff();}}); + + FrontPanelLockOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FrontPanelLockOn.JoinNumber]); + FrontPanelLockOffFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FrontPanelLockOff.JoinNumber]); + trilist.SetBoolSigAction(joinMap.EnableRouting.JoinNumber, SetRoutingEnable); // Link up outputs @@ -970,15 +962,19 @@ namespace PepperDash.Essentials.DM switch (args.EventId) { case DMSystemEventIds.SystemPowerOnEventId: - { - SystemPowerOnFeedback.FireUpdate(); - break; - } case DMSystemEventIds.SystemPowerOffEventId: { + SystemPowerOnFeedback.FireUpdate(); SystemPowerOffFeedback.FireUpdate(); break; } + case DMSystemEventIds.FrontPanelLockOnEventId: + case DMSystemEventIds.FrontPanelLockOffEventId: + { + FrontPanelLockOnFeedback.FireUpdate(); + FrontPanelLockOffFeedback.FireUpdate(); + break; + } } } From 8bfd3ffd51318c9e8a57f86e7b6ac0d9bd052b57 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Thu, 20 Jan 2022 17:20:39 -0500 Subject: [PATCH 470/480] Fix DMPS system power on from last commit --- .../Essentials_DM/Chassis/DmpsRoutingController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs index 056d6ec0..f6592699 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmpsRoutingController.cs @@ -308,7 +308,7 @@ namespace PepperDash.Essentials.DM //Link up system power only for non-4k DMPS3 if (SystemControl is Dmps3SystemControl) { - trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, a => { if (a) { ((Dmps3SystemControl)SystemControl).SystemPowerOff(); } }); + trilist.SetBoolSigAction(joinMap.SystemPowerOn.JoinNumber, a => { if (a) { ((Dmps3SystemControl)SystemControl).SystemPowerOn(); } }); trilist.SetBoolSigAction(joinMap.SystemPowerOff.JoinNumber, a => { if (a) { ((Dmps3SystemControl)SystemControl).SystemPowerOff(); } }); } From 89bd9883918cd753a6ad471aef59f5aceeb654db Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 26 Jan 2022 09:34:44 -0700 Subject: [PATCH 471/480] fix (Core): Add better log messages and null checks Checking if a device exists in the Device Manager and if it implements `IRelayPorts` are now 2 separate steps instead of one. There is now a null check in the PostActivation method to allow for logging an error if getting the relay device fails. --- .../Crestron IO/Relay/GenericRelayDevice.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs index 445ac338..5a49a443 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs @@ -44,6 +44,12 @@ namespace PepperDash.Essentials.Core.CrestronIO { RelayOutput = postActivationFunc(config); + if (RelayOutput == null) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Unable to get parent relay device for device key {0} and port {1}", config.PortDeviceKey, config.PortNumber); + return; + } + RelayOutput.Register(); RelayOutput.StateChange += RelayOutput_StateChange; @@ -61,30 +67,32 @@ namespace PepperDash.Essentials.Core.CrestronIO { if (!Global.ControlSystem.SupportsRelay) { - Debug.Console(0, "GetRelayDevice: Processor does not support relays"); + Debug.Console(0, "Processor does not support relays"); return null; } relayDevice = Global.ControlSystem; + + return relayDevice.RelayPorts[dc.PortNumber]; } - else + + var essentialsDevice = DeviceManager.GetDeviceForKey(dc.PortDeviceKey); + if (essentialsDevice == null) { - var relayDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IRelayPorts; - if (relayDev == null) - { - Debug.Console(0, "GetRelayDevice: Device {0} is not a valid device", dc.PortDeviceKey); - return null; - } - relayDevice = relayDev; + Debug.Console(0, "Device {0} was not found in Device Manager. Check configuration or for errors with device.", dc.PortDeviceKey); + return null; } + + relayDevice = essentialsDevice as IRelayPorts; + if (relayDevice == null) { - Debug.Console(0, "GetRelayDevice: Device '0' is not a valid IRelayPorts Device", dc.PortDeviceKey); + Debug.Console(0, "Device {0} is not a valid relay parent. Please check configuration.", dc.PortDeviceKey); return null; } if (dc.PortNumber > relayDevice.NumberOfRelayPorts) { - Debug.Console(0, "GetRelayDevice: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + Debug.Console(0, "Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); } return relayDevice.RelayPorts[dc.PortNumber]; From 4eace11943a60b526b64044e33489ea9fd207d4b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 26 Jan 2022 09:35:09 -0700 Subject: [PATCH 472/480] refactor(Core): Removed old commented out code --- .../Crestron IO/Relay/GenericRelayDevice.cs | 52 ------------------- 1 file changed, 52 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs index 5a49a443..effe2a93 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs @@ -208,58 +208,6 @@ namespace PepperDash.Essentials.Core.CrestronIO var portDevice = new GenericRelayDevice(dc.Key, dc.Name, GetRelay, props); return portDevice; - - - /* - if (props.PortDeviceKey == "processor") - portDevice = Global.ControlSystem as IRelayPorts; - else - portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts; - - if (portDevice == null) - Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key); - else - { - var cs = (portDevice as CrestronControlSystem); - - if (cs != null) - { - // The relay is on a control system processor - if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts) - { - Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays"); - return null; - } - } - else - { - // The relay is on another device type - - if (props.PortNumber > portDevice.NumberOfRelayPorts) - { - Debug.Console(0, "Port Device: {0} does not have enough relays"); - return null; - } - } - - Relay relay = portDevice.RelayPorts[props.PortNumber]; - - if (!relay.Registered) - { - if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success) - return new GenericRelayDevice(key, relay); - else - Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey); - } - else - { - return new GenericRelayDevice(key, relay); - } - - // Future: Check if portDevice is 3-series card or other non control system that supports versiports - } - */ - } } From 8393ae3dedf13c95d5f9e3994e7a1189e276fe77 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 26 Jan 2022 09:39:57 -0700 Subject: [PATCH 473/480] fix(Core): Add return if port number is greater than supported ports on the device --- .../Crestron IO/Relay/GenericRelayDevice.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs index effe2a93..69c588ae 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Relay/GenericRelayDevice.cs @@ -90,12 +90,13 @@ namespace PepperDash.Essentials.Core.CrestronIO return null; } - if (dc.PortNumber > relayDevice.NumberOfRelayPorts) + if (dc.PortNumber <= relayDevice.NumberOfRelayPorts) { - Debug.Console(0, "Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + return relayDevice.RelayPorts[dc.PortNumber]; } - - return relayDevice.RelayPorts[dc.PortNumber]; + + Debug.Console(0, "Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber); + return null; } #endregion From 05aece772fae128256f3609297512279ab40329f Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 26 Jan 2022 10:51:03 -0700 Subject: [PATCH 474/480] fix(DM): Add `IRelayPorts` implementation the `DmRmc4kzScalerCController` class now implements `IRelayPorts` and delegates implementation to the Crestron `DmRm4kzScalerC` class. #891 --- .../Receivers/DmRmc4kZScalerCController.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs index 21663e78..73dd59b9 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs @@ -14,7 +14,7 @@ namespace PepperDash.Essentials.DM { [Description("Wrapper Class for DM-RMC-4K-Z-SCALER-C")] public class DmRmc4kZScalerCController : DmRmcControllerBase, IRmcRoutingWithFeedback, - IIROutputPorts, IComPorts, ICec + IIROutputPorts, IComPorts, ICec, IRelayPorts { private readonly DmRmc4kzScalerC _rmc; @@ -168,5 +168,18 @@ namespace PepperDash.Essentials.DM } #endregion + #region Implementation of IRelayPorts + + public CrestronCollection RelayPorts + { + get { return _rmc.RelayPorts; } + } + + public int NumberOfRelayPorts + { + get { return _rmc.NumberOfRelayPorts; } + } + + #endregion } } \ No newline at end of file From fb6021424e4993f807e0e7b4cb24c4fa5a46a975 Mon Sep 17 00:00:00 2001 From: Jason DeVito Date: Wed, 26 Jan 2022 15:06:17 -0600 Subject: [PATCH 475/480] feat: Updated joinMap to include NoRouteText @ serial-100. fix: Updated joinMap descriptions for Video/Audio Input/Output names. feat: Updated DmChassisController LinkChassisToApi to pass noRouteText across bridge. --- .../Bridges/JoinMaps/DmChassisControllerJoinMap.cs | 12 ++++++++---- .../Essentials_DM/Chassis/DmChassisController.cs | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index 60973801..3582e6cf 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -84,6 +84,10 @@ namespace PepperDash.Essentials.Core.Bridges public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); + [JoinName("NoRouteName")] + public JoinDataComplete NoRouteName = new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 }, + new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); + [JoinName("InputNames")] public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 }, new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial }); @@ -96,7 +100,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinDataComplete(new JoinData {JoinNumber = 501, JoinSpan = 200}, new JoinMetadata { - Description = "Video Input Name", + Description = "DM Chassis Video Input Names", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); @@ -106,7 +110,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 200 }, new JoinMetadata { - Description = "Video Input Name", + Description = "DM Chassis Audio Input Names", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); @@ -115,7 +119,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinDataComplete(new JoinData { JoinNumber = 901, JoinSpan = 200 }, new JoinMetadata { - Description = "Video Input Name", + Description = "DM Chassis Video Output Names", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); @@ -124,7 +128,7 @@ namespace PepperDash.Essentials.Core.Bridges new JoinDataComplete(new JoinData { JoinNumber = 1101, JoinSpan = 200 }, new JoinMetadata { - Description = "Video Input Name", + Description = "DM Chassis Audio Output Names", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial }); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index 030536df..ef7fc577 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1901,6 +1901,8 @@ namespace PepperDash.Essentials.DM EnableAudioBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAudioBreakaway.JoinNumber]); EnableUsbBreakawayFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsbBreakaway.JoinNumber]); + trilist.SetString(joinMap.NoRouteName.JoinNumber, NoRouteText); + trilist.OnlineStatusChange += (o, a) => { if (!a.DeviceOnLine) @@ -1912,6 +1914,8 @@ namespace PepperDash.Essentials.DM EnableUsbBreakawayFeedback.FireUpdate(); SystemIdBusyFeedback.FireUpdate(); SystemIdFeebdack.FireUpdate(); + + trilist.SetString(joinMap.NoRouteName.JoinNumber, NoRouteText); }; } From 08aa8fb2e60b2ccf1b6db2f1c306c35ce6be9e80 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Tue, 8 Feb 2022 16:05:02 -0500 Subject: [PATCH 476/480] Fixes issue where DisableAutoPhonebookDownload is set to true, but phonebook would still auto-download. Check condition was inversed --- .../Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index 8fc40f29..ef3b59cb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1090,7 +1090,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom SendText("zFeedback Register Op: ex Path: /Event/InfoResult/Info/toll_free_callinLlist"); Thread.Sleep(100); - if (!_props.DisablePhonebookAutoDownload) + if (_props.DisablePhonebookAutoDownload) { SendText("zFeedback Register Op: ex Path: /Event/Phonebook/AddedContact"); } From 582390c7c7042511e1e8db4b07955d9fe514ae4b Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Wed, 9 Feb 2022 08:38:27 -0700 Subject: [PATCH 477/480] ci: Fix Windows image --- .github/workflows/docker.yml | 2 +- .github/workflows/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 94c45937..cdcc925b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -22,7 +22,7 @@ env: RELEASE_BRANCH: main jobs: Build_Project: - runs-on: windows-latest + runs-on: windows-2019 steps: # First we checkout the source repo - name: Checkout repo diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc219ce3..ef43152b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,7 +19,7 @@ env: RELEASE_BRANCH: main jobs: Build_Project: - runs-on: windows-latest + runs-on: windows-2019 steps: # First we checkout the source repo - name: Checkout repo From 747c68bd1e9d4dfe31b2476d4460ce536dde4361 Mon Sep 17 00:00:00 2001 From: Jonathan Arndt Date: Wed, 16 Feb 2022 22:17:45 -0800 Subject: [PATCH 478/480] Updates to forEach loop sceneIndex to include local sceneIndex context --- .../PepperDashEssentialsBase/Lighting/LightingBase.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs index 569d2005..0549985c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Lighting/LightingBase.cs @@ -99,13 +99,18 @@ namespace PepperDash.Essentials.Core.Lighting var sceneIndex = 0; foreach (var scene in lightingDevice.LightingScenes) { - trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[sceneIndex])); + var index1 = sceneIndex; + trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex), () => + { + var index = index1; + Debug.Console(2, this, "LightingDevice: sceneIndex: {0} index: {1} > inside action", index1, index); + lightingDevice.SelectScene(lightingDevice.LightingScenes[index]); + }); scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)]); trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + sceneIndex)].StringValue = scene.Name; trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + sceneIndex)].BoolValue = true; sceneIndex++; } - return joinMap; } From 0ab1ece4455b7ef35183cee2d87bfea11ab628d2 Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Mon, 14 Mar 2022 19:26:50 -0400 Subject: [PATCH 479/480] feat (essentials): split up volume interfaces for better composition fix (essentials): fixed a few misc devices that are probably deprecated anyhow --- .../Devices/IVolumeAndAudioInterfaces.cs | 50 +++++++++++++++---- .../Display/NECPSXMDisplay.cs | 7 ++- .../Display/PanasonicThDisplay.cs | 5 +- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs index 1cff62fc..516c3283 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs @@ -7,25 +7,53 @@ using Crestron.SimplSharp; namespace PepperDash.Essentials.Core { /// - /// Defines minimal volume control methods + /// Defines minimal volume and mute control methods /// - public interface IBasicVolumeControls + public interface IBasicVolumeControls : IBasicVolumeControl, IBasicMuteControl { - void VolumeUp(bool pressRelease); - void VolumeDown(bool pressRelease); - void MuteToggle(); } + /// + /// Defines basic volume control methods + /// + public interface IBasicVolumeControl + { + void VolumeUp(bool pressRelease); + void VolumeDown(bool pressRelease); + } + + /// + /// Defines volume control methods and properties with feedback + /// + public interface IBasicVolumeControlWithFeedback : IBasicVolumeControl + { + void SetVolume(ushort level); + IntFeedback VolumeLevelFeedback { get; } + } + + /// + /// Defines basic mute control methods + /// + public interface IBasicMuteControl + { + void MuteToggle(); + } + + /// + /// Defines mute control methods and properties with feedback + /// + public interface IBasicMuteControlWithFeedback : IBasicMuteControl + { + BoolFeedback MuteFeedback { get; } + void MuteOn(); + void MuteOff(); + } + /// /// Adds feedback and direct volume level set to IBasicVolumeControls /// - public interface IBasicVolumeWithFeedback : IBasicVolumeControls + public interface IBasicVolumeWithFeedback : IBasicVolumeControlWithFeedback, IBasicMuteControlWithFeedback { - void SetVolume(ushort level); - void MuteOn(); - void MuteOff(); - IntFeedback VolumeLevelFeedback { get; } - BoolFeedback MuteFeedback { get; } } /// diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs index 176f28ac..a674b11a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/NECPSXMDisplay.cs @@ -308,7 +308,7 @@ namespace PepperDash.Essentials.Devices.Displays //Send((string)selector); } - void SetVolume(ushort level) + public void SetVolume(ushort level) { var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level); AppendChecksumAndSend(levelString); @@ -333,10 +333,13 @@ namespace PepperDash.Essentials.Devices.Displays Send(MuteOnCmd); } - void IBasicVolumeWithFeedback.SetVolume(ushort level) + + /* + public void IBasicVolumeWithFeedback.SetVolume(ushort level) { SetVolume(level); } + */ #endregion diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs index b8d33bd1..9acc395e 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Display/PanasonicThDisplay.cs @@ -290,7 +290,7 @@ namespace PepperDash.Essentials.Devices.Displays //Send((string)selector); } - void SetVolume(ushort level) + public void SetVolume(ushort level) { var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level); @@ -315,11 +315,12 @@ namespace PepperDash.Essentials.Devices.Displays Send(MuteOnCmd); } + /* void IBasicVolumeWithFeedback.SetVolume(ushort level) { SetVolume(level); } - + */ #endregion #region IBasicVolumeControls Members From 34a695ba95997fe066ccfcdfa1dee358f2279270 Mon Sep 17 00:00:00 2001 From: Nick Genovese Date: Mon, 14 Mar 2022 19:51:55 -0400 Subject: [PATCH 480/480] feat (essentials): fixed a few build issues with the new volume interfaces --- .../Devices/IVolumeAndAudioInterfaces.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs index 516c3283..254eada2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs @@ -9,14 +9,14 @@ namespace PepperDash.Essentials.Core /// /// Defines minimal volume and mute control methods /// - public interface IBasicVolumeControls : IBasicVolumeControl, IBasicMuteControl + public interface IBasicVolumeControls : IHasVolumeControl, IHasMuteControl { } /// /// Defines basic volume control methods /// - public interface IBasicVolumeControl + public interface IHasVolumeControl { void VolumeUp(bool pressRelease); void VolumeDown(bool pressRelease); @@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core /// /// Defines volume control methods and properties with feedback /// - public interface IBasicVolumeControlWithFeedback : IBasicVolumeControl + public interface IHasVolumeControlWithFeedback : IHasVolumeControl { void SetVolume(ushort level); IntFeedback VolumeLevelFeedback { get; } @@ -34,7 +34,7 @@ namespace PepperDash.Essentials.Core /// /// Defines basic mute control methods /// - public interface IBasicMuteControl + public interface IHasMuteControl { void MuteToggle(); } @@ -42,7 +42,7 @@ namespace PepperDash.Essentials.Core /// /// Defines mute control methods and properties with feedback /// - public interface IBasicMuteControlWithFeedback : IBasicMuteControl + public interface IHasMuteControlWithFeedback : IHasMuteControl { BoolFeedback MuteFeedback { get; } void MuteOn(); @@ -52,7 +52,7 @@ namespace PepperDash.Essentials.Core /// /// Adds feedback and direct volume level set to IBasicVolumeControls /// - public interface IBasicVolumeWithFeedback : IBasicVolumeControlWithFeedback, IBasicMuteControlWithFeedback + public interface IBasicVolumeWithFeedback : IBasicVolumeControls, IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback { }