From 8d1f1876437079d04900a884c7ce893d752ed926 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Tue, 21 Sep 2021 17:59:12 -0600 Subject: [PATCH] feat(essentials): #830 Adds new Cisco features Adds IHasDoNotDisturbMode, IHasStandbyMode and IHasHalfWakeMode interfaces. Implements all interfaces on CiscoSparkCodec class. Adds CiscoCodecJoinMap to allow for bridging new Cisco specific functions. --- .../Codec/IHasDoNotDisturb.cs | 45 +++++++ .../Essentials Devices Common.csproj | 3 + .../CiscoCodec/CiscoCodecJoinMap.cs | 120 ++++++++++++++++++ .../VideoCodec/CiscoCodec/CiscoSparkCodec.cs | 96 +++++++++++++- .../VideoCodec/CiscoCodec/xStatus.cs | 26 +++- .../VideoCodec/Interfaces/IHasStandbyMode.cs | 32 +++++ .../VideoCodec/VideoCodecBase.cs | 2 +- 7 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs create mode 100644 essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs new file mode 100644 index 00000000..7bb9b924 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/IHasDoNotDisturb.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Codec +{ + /// + /// Describes a device that has Do Not Disturb mode capability + /// + public interface IHasDoNotDisturbMode + { + /// + /// Indictes whether Do Not Disturb mode is on (Activated) + /// + BoolFeedback DoNotDisturbModeIsOnFeedback { get; } + + /// + /// Activates Do Not Disturb mode + /// + void ActivateDoNotDisturbMode(); + + /// + /// Deactivates Do Not Disturb mode + /// + void DeactivateDoNotDisturbMode(); + + /// + /// Toggles Do Not Disturb mode + /// + void ToggleDoNotDisturbMode(); + } + + public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode + { + /// + /// Activates Do Not Disturb mode with a timeout + /// + /// + void ActivateDoNotDisturbMode(int timeout); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index fc5f68d4..1fcffff2 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -108,6 +108,7 @@ + @@ -117,6 +118,7 @@ + @@ -125,6 +127,7 @@ + diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs new file mode 100644 index 00000000..8caeaf3e --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoCodecJoinMap.cs @@ -0,0 +1,120 @@ +using System; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges.JoinMaps; + + +namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco +{ + public class CiscoCodecJoinMap : VideoCodecControllerJoinMap + { + #region Digital + + [JoinName("ActivateDoNotDisturbMode")] + public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 221, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Do Not Disturb Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DeactivateDoNotDisturbMode")] + public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 222, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Deactivates Do Not Disturb Mode. FB High if deactivated.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ToggleDoNotDisturbMode")] + public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 223, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Toggles Do Not Disturb Mode.", + JoinCapabilities = eJoinCapabilities.ToSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ActivateStandby")] + public JoinDataComplete ActivateStandby = new JoinDataComplete( + new JoinData + { + JoinNumber = 226, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Standby Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("DeactivateStandby")] + public JoinDataComplete DeactivateStandby = new JoinDataComplete( + new JoinData + { + JoinNumber = 227, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Deactivates Standby Mode. FB High if deactivated.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + [JoinName("ActivateHalfWakeMode")] + public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete( + new JoinData + { + JoinNumber = 228, + JoinSpan = 1 + }, + new JoinMetadata + { + Description = "Activates Half Wake Mode. FB High if active.", + JoinCapabilities = eJoinCapabilities.ToFromSIMPL, + JoinType = eJoinType.Digital + }); + + #endregion + + + #region Analog + + + #endregion + + + #region Serials + + + #endregion + + public CiscoCodecJoinMap(uint joinStart) + : base(joinStart, typeof(CiscoCodecJoinMap)) + { + } + + public CiscoCodecJoinMap(uint joinStart, Type type) + : base(joinStart, type) + { + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index f894141c..904482b0 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -28,7 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView, - ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute + ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, + IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute, IHasDoNotDisturbMode, + IHasHalfWakeMode { private bool _externalSourceChangeRequested; @@ -316,6 +318,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CameraIsMutedFeedback = CameraIsOffFeedback; SupportsCameraOff = true; + DoNotDisturbModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Conference.DoNotDisturb.BoolValue); + HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value == "Halfwake"); + PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized"); Communication = comm; @@ -413,7 +418,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate; CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate; CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate; - CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate; + CodecStatus.Status.Standby.State.ValueChangedAction = new Action(() => + { + StandbyIsOnFeedback.FireUpdate(); + HalfWakeModeIsOnFeedback.FireUpdate(); + }); CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate; CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate; CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate; @@ -423,6 +432,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout; CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate; CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate; + CodecStatus.Status.Conference.DoNotDisturb.ValueChangedAction = DoNotDisturbModeIsOnFeedback.FireUpdate; + try { CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate; @@ -1495,7 +1506,49 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) { + var joinMap = new CiscoCodecJoinMap(joinStart); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge); + + LinkCiscoCodecToApi(trilist, joinMap); + } + + public void LinkCiscoCodecToApi(BasicTriList trilist, CiscoCodecJoinMap joinMap) + { + var dndCodec = this as IHasDoNotDisturbMode; + if (dndCodec != null) + { + dndCodec.DoNotDisturbModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateDoNotDisturbMode.JoinNumber]); + dndCodec.DoNotDisturbModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateDoNotDisturbMode.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.ActivateDoNotDisturbMode.JoinNumber, () => dndCodec.ActivateDoNotDisturbMode()); + trilist.SetSigFalseAction(joinMap.DeactivateDoNotDisturbMode.JoinNumber, () => dndCodec.DeactivateDoNotDisturbMode()); + trilist.SetSigFalseAction(joinMap.ToggleDoNotDisturbMode.JoinNumber, () => dndCodec.ToggleDoNotDisturbMode()); + } + + var halfwakeCodec = this as IHasHalfWakeMode; + if (halfwakeCodec != null) + { + halfwakeCodec.StandbyIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateStandby.JoinNumber]); + halfwakeCodec.StandbyIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateStandby.JoinNumber]); + halfwakeCodec.HalfWakeModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateHalfWakeMode.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.ActivateStandby.JoinNumber, () => halfwakeCodec.StandbyActivate()); + trilist.SetSigFalseAction(joinMap.DeactivateStandby.JoinNumber, () => halfwakeCodec.StandbyDeactivate()); + trilist.SetSigFalseAction(joinMap.ActivateHalfWakeMode.JoinNumber, () => halfwakeCodec.HalfwakeActivate()); + } } /// @@ -2069,6 +2122,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco else CameraMuteOn(); } + + #region IHasDoNotDisturbMode Members + + public BoolFeedback DoNotDisturbModeIsOnFeedback { get; private set; } + + public void ActivateDoNotDisturbMode() + { + SendText("xCommand Conference DoNotDisturb Activate"); + } + + public void DeactivateDoNotDisturbMode() + { + SendText("xCommand Conference DoNotDisturb Deactivate"); + } + + public void ToggleDoNotDisturbMode() + { + if (DoNotDisturbModeIsOnFeedback.BoolValue) + { + DeactivateDoNotDisturbMode(); + } + else + { + ActivateDoNotDisturbMode(); + } + } + + #endregion + + #region IHasHalfWakeMode Members + + public BoolFeedback HalfWakeModeIsOnFeedback { get; private set; } + + public void HalfwakeActivate() + { + SendText("xCommand Standby Halfwake"); + } + + #endregion } diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs index c1cd92cf..a32ff5bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/xStatus.cs @@ -440,9 +440,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public CallId CallId { get; set; } } - public class DoNotDisturb + public class DoNotDisturb : ValueProperty { - public string Value { get; set; } + string _Value; + + public bool BoolValue { get; private set; } + + public string Value + { + get + { + return _Value; + } + set + { + _Value = value; + // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false + BoolValue = value == "On" || value == "Active"; + OnValueChanged(); + } + } } public class Mode @@ -600,6 +617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public Conference2() { Presentation = new Presentation(); + DoNotDisturb = new DoNotDisturb(); } } @@ -1380,12 +1398,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public class State : ValueProperty { + string _value; + public bool BoolValue { get; private set; } public string Value // Valid values are Standby/EnteringStandby/Halfwake/Off { + get { return _value; } set { + _value = value; // If the incoming value is "On" it sets the BoolValue true, otherwise sets it false BoolValue = value == "On" || value == "Standby"; OnValueChanged(); diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs new file mode 100644 index 00000000..55dcd081 --- /dev/null +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/Interfaces/IHasStandbyMode.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + /// + /// Describes a device that has Standby Mode capability + /// + public interface IHasStandbyMode + { + BoolFeedback StandbyIsOnFeedback { get; } + + void StandbyActivate(); + + void StandbyDeactivate(); + } + + /// + /// Describes a device that has Half Waek Mode capability + /// + public interface IHasHalfWakeMode : IHasStandbyMode + { + BoolFeedback HalfWakeModeIsOnFeedback { get; } + + void HalfwakeActivate(); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index d34c9e3b..26ed54bb 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -25,7 +25,7 @@ using Feedback = PepperDash.Essentials.Core.Feedback; namespace PepperDash.Essentials.Devices.Common.VideoCodec { public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, - IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced + IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode { private const int XSigEncoding = 28591; protected const int MaxParticipants = 50;