From 0cd3c1bdc509d5ec58ccfc42561b789d6077b728 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 29 Jul 2021 13:01:02 -0600 Subject: [PATCH 1/5] 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 2/5] 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 3/5] 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 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 4/5] 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 1696ef3ac11fea37202e6ab0d0f89e2a4d7f7608 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 2 Aug 2021 16:58:32 -0600 Subject: [PATCH 5/5] 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();