From 22aea3089dec7528ec58a2757938c824d503c124 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Mon, 9 Aug 2021 14:41:31 -0600 Subject: [PATCH 01/13] #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 02/13] 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 03/13] 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 072411e4f60a142a749465d8a7fc214a43064a41 Mon Sep 17 00:00:00 2001 From: Louis Iacovelli Date: Thu, 12 Aug 2021 11:49:59 -0400 Subject: [PATCH 04/13] 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 05/13] 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 06/13] 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 07/13] 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 08/13] 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 09/13] 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 10/13] 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 11/13] 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 12/13] 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 13/13] 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) {