From aa61479adc50f992183b8d3cd57407f7400e5511 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Fri, 18 Dec 2020 09:16:40 -0700 Subject: [PATCH 01/14] remove device info stuff from DGE for now --- .../Essentials_DM/Endpoints/DGEs/Dge100Controller.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs index d7996554..39e549cc 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs @@ -39,12 +39,12 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs { _dge = device; _dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs; - _dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo(); + //_dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo(); _dgeEthernetInfo.Use(); DeviceInfo = new DeviceInfo(); - _dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; + //_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; _dc = dc; From 870f2f8fa641d805999b594f8a460deb054adb48 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Fri, 18 Dec 2020 14:34:15 -0700 Subject: [PATCH 02/14] properly defines the IsWarming/Cooling FeedbackFuncs and fires feedbacks --- .../Room/Types/EssentialsTechRoom.cs | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index f0191839..a2943528 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -28,6 +28,33 @@ namespace PepperDash.Essentials private Dictionary _currentPresets; private ScheduledEventGroup _roomScheduledEventGroup; + /// + /// + /// + protected override Func IsWarmingFeedbackFunc + { + get + { + return () => + { + return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue); + }; + } + } + /// + /// + /// + protected override Func IsCoolingFeedbackFunc + { + get + { + return () => + { + return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue); + }; + } + } + public EssentialsTechRoom(DeviceConfig config) : base(config) { _config = config.Properties.ToObject(); @@ -111,7 +138,12 @@ namespace PepperDash.Essentials foreach (var display in _displays) { display.Value.PowerIsOnFeedback.OutputChange += - (sender, args) => RoomPowerIsOnFeedback.InvokeFireUpdate(); + (sender, args) => + { + RoomPowerIsOnFeedback.InvokeFireUpdate(); + IsWarmingUpFeedback.InvokeFireUpdate(); + IsCoolingDownFeedback.InvokeFireUpdate(); + }; } } @@ -281,16 +313,6 @@ namespace PepperDash.Essentials #region Overrides of EssentialsRoomBase - protected override Func IsWarmingFeedbackFunc - { - get { return () => false; } - } - - protected override Func IsCoolingFeedbackFunc - { - get { return () => false; } - } - protected override Func OnFeedbackFunc { get { return () => RoomPowerIsOn; } From 0f924360c11f60e39ec6527ef411908789a8bf77 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 10:51:12 -0700 Subject: [PATCH 03/14] fix issues in LinkToApi --- PepperDashEssentials/Room/Types/EssentialsTechRoom.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index a2943528..0a47933e 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -380,6 +380,8 @@ namespace PepperDash.Essentials feedback.Value.FireUpdate(); } }; + + return; } i = 0; @@ -388,6 +390,8 @@ namespace PepperDash.Essentials var tuner = setTopBox; trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value)); + + i++; } } From 0a43f43f665704ae8edf87f4732a1958508aaee1 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 12:31:00 -0700 Subject: [PATCH 04/14] add ICommunicationMonitor to EiscApiAdvanced --- .../Bridges/BridgeBase.cs | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 86db81ba..33285bff 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core.Bridges /// /// Bridge API using EISC /// - public class EiscApiAdvanced : BridgeApi + public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor { public EiscApiPropertiesConfig PropertiesConfig { get; private set; } @@ -89,6 +89,7 @@ namespace PepperDash.Essentials.Core.Bridges public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) : base(dc.Key) { + CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); JoinMaps = new Dictionary(); PropertiesConfig = dc.Properties.ToObject(); @@ -100,6 +101,19 @@ namespace PepperDash.Essentials.Core.Bridges AddPostActivationAction(LinkDevices); AddPostActivationAction(LinkRooms); + AddPostActivationAction(RegisterEisc); + } + + public override bool CustomActivate() + { + CommunicationMonitor.Start(); + return base.CustomActivate(); + } + + public override bool Deactivate() + { + CommunicationMonitor.Stop(); + return base.Deactivate(); } private void LinkDevices() @@ -137,8 +151,6 @@ namespace PepperDash.Essentials.Core.Bridges bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this); } } - - RegisterEisc(); } private void RegisterEisc() @@ -182,8 +194,6 @@ namespace PepperDash.Essentials.Core.Bridges rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this); } - - RegisterEisc(); } /// @@ -324,6 +334,12 @@ namespace PepperDash.Essentials.Core.Bridges Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e); } } + + #region Implementation of ICommunicationMonitor + + public StatusMonitorBase CommunicationMonitor { get; private set; } + + #endregion } public class EiscApiPropertiesConfig From cc159e306e1295a2aa277f40dd4e0cc060f39148 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 14:40:19 -0700 Subject: [PATCH 05/14] update Essentials to use PepperDash Core 1.0.43 --- .../PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec | 2 +- packages.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec index 5db86afc..dff167ed 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.nuspec @@ -14,7 +14,7 @@ crestron 3series 4series - + diff --git a/packages.config b/packages.config index c138dd1b..67789ca5 100644 --- a/packages.config +++ b/packages.config @@ -1,3 +1,3 @@ - + \ No newline at end of file From ae03b8cd7e1e368619fc32160fc577b89ec0b537 Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 16:19:45 -0700 Subject: [PATCH 06/14] fix PresetsList saving to file --- .../PepperDashEssentialsBase/Presets/DevicePresets.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs index 85e5dfdb..d6a9fad0 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Presets/DevicePresets.cs @@ -266,14 +266,13 @@ namespace PepperDash.Essentials.Core.Presets try { _fileOps.Enter(); - var json = JsonConvert.SerializeObject(PresetsList); + var pl = new PresetsList {Channels = PresetsList, Name = Name}; + var json = JsonConvert.SerializeObject(pl, Formatting.Indented); using (var file = File.Open(_filePath, FileMode.Truncate)) { file.Write(json, Encoding.UTF8); } - - } finally { From 3b0a5285ab5d8d4f4e99397582a1337eade40a9a Mon Sep 17 00:00:00 2001 From: Andrew Welker Date: Mon, 21 Dec 2020 17:00:37 -0700 Subject: [PATCH 07/14] fix order for comm monitor --- .../PepperDashEssentialsBase/Bridges/BridgeBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs index 33285bff..11ede5a1 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs @@ -89,7 +89,6 @@ namespace PepperDash.Essentials.Core.Bridges public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) : base(dc.Key) { - CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); JoinMaps = new Dictionary(); PropertiesConfig = dc.Properties.ToObject(); @@ -99,6 +98,8 @@ namespace PepperDash.Essentials.Core.Bridges Eisc.SigChange += Eisc_SigChange; + CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000); + AddPostActivationAction(LinkDevices); AddPostActivationAction(LinkRooms); AddPostActivationAction(RegisterEisc); From 72197e547f0aacf7b55506c0530af238523c506d Mon Sep 17 00:00:00 2001 From: jkdevito Date: Wed, 6 Jan 2021 16:22:54 -0600 Subject: [PATCH 08/14] Updated VideoCodecBase.cs and ZoomRooms.cs to resolve an issue with dialing the currently scheduled meetings. VideoCodecBase.cs changes: 1. Moved the trilist.SetSigFalseActions for DialMeeting 1-3 from the UpdateMeetinsgList mehtod to the LinkVideoCodecScheduleToApi method. - This was necessary to resolve an issue with dialing current meetings. - When the SetSigFalseActions where located in the UpdateMeetingsList, they were using the codec.CodecSchedule.Meetings to dial, which was not updated based on the time of day. 2. Turned the local var currentMeetings into a private list, _currentMeetings, that can be updated by UpdateMeetingsList and then used in LinkVideoCodecScheduleToApi when the trilist actions are executed. 3. Added debug statements to help narrow down the issue and verify the data. ZoomRoom.cs changes: 1. Added debug statement to Dial(Meeting meeting) method to confirm the data passed from LinkVideoCodecScheduleToApi was matching the _currentMeetings list data. --- .../VideoCodec/VideoCodecBase.cs | 2528 +++++++++-------- .../VideoCodec/ZoomRoom/ZoomRoom.cs | 1 + 2 files changed, 1276 insertions(+), 1253 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index 0977dea2..6b6d5891 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -1,1257 +1,1279 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharp.Ssh; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharp; -using PepperDash.Core; -using PepperDash.Core.Intersystem; -using PepperDash.Core.Intersystem.Tokens; -using PepperDash.Core.WebApi.Presets; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Core.Routing; -using PepperDash.Essentials.Devices.Common.Cameras; -using PepperDash.Essentials.Devices.Common.Codec; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; -using PepperDash_Essentials_Core.Bridges.JoinMaps; -using PepperDash_Essentials_Core.DeviceTypeInterfaces; -using Feedback = PepperDash.Essentials.Core.Feedback; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec -{ - public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, - IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced - { - private const int XSigEncoding = 28591; - private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); - protected VideoCodecBase(DeviceConfig config) - : base(config) - { - - StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); - PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); - VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); - MuteFeedback = new BoolFeedback(MuteFeedbackFunc); - SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); - SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); - - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - - ActiveCalls = new List(); - } - - public IBasicCommunication Communication { get; protected set; } - - /// - /// An internal pseudo-source that is routable and connected to the osd input - /// - public DummyRoutingInputsDevice OsdSource { get; protected set; } - - public BoolFeedback StandbyIsOnFeedback { get; private set; } - - protected abstract Func PrivacyModeIsOnFeedbackFunc { get; } - protected abstract Func VolumeLevelFeedbackFunc { get; } - protected abstract Func MuteFeedbackFunc { get; } - protected abstract Func StandbyIsOnFeedbackFunc { get; } - - public List ActiveCalls { get; set; } - - public bool ShowSelfViewByDefault { get; protected set; } - - protected bool SupportsCameraOff; - protected bool SupportsCameraAutoMode; - - public bool IsReady { get; protected set; } - - public virtual List Feedbacks - { - get - { - return new List +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Ssh; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharp; +using PepperDash.Core; +using PepperDash.Core.Intersystem; +using PepperDash.Core.Intersystem.Tokens; +using PepperDash.Core.WebApi.Presets; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using PepperDash.Essentials.Core.Routing; +using PepperDash.Essentials.Devices.Common.Cameras; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; +using PepperDash_Essentials_Core.Bridges.JoinMaps; +using PepperDash_Essentials_Core.DeviceTypeInterfaces; +using Feedback = PepperDash.Essentials.Core.Feedback; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs, + IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced + { + private const int XSigEncoding = 28591; + private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs(); + protected VideoCodecBase(DeviceConfig config) + : base(config) + { + + StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); + PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); + VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); + MuteFeedback = new BoolFeedback(MuteFeedbackFunc); + SharingSourceFeedback = new StringFeedback(SharingSourceFeedbackFunc); + SharingContentIsOnFeedback = new BoolFeedback(SharingContentIsOnFeedbackFunc); + + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + + ActiveCalls = new List(); + } + + public IBasicCommunication Communication { get; protected set; } + + /// + /// An internal pseudo-source that is routable and connected to the osd input + /// + public DummyRoutingInputsDevice OsdSource { get; protected set; } + + public BoolFeedback StandbyIsOnFeedback { get; private set; } + + protected abstract Func PrivacyModeIsOnFeedbackFunc { get; } + protected abstract Func VolumeLevelFeedbackFunc { get; } + protected abstract Func MuteFeedbackFunc { get; } + protected abstract Func StandbyIsOnFeedbackFunc { get; } + + public List ActiveCalls { get; set; } + + public bool ShowSelfViewByDefault { get; protected set; } + + protected bool SupportsCameraOff; + protected bool SupportsCameraAutoMode; + + public bool IsReady { get; protected set; } + + public virtual List Feedbacks + { + get + { + return new List { PrivacyModeIsOnFeedback, SharingSourceFeedback - }; - } - } - - protected abstract Func SharingSourceFeedbackFunc { get; } - protected abstract Func SharingContentIsOnFeedbackFunc { get; } - - #region ICodecAudio Members - - public abstract void PrivacyModeOn(); - public abstract void PrivacyModeOff(); - public abstract void PrivacyModeToggle(); - public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } - - - public BoolFeedback MuteFeedback { get; private set; } - - public abstract void MuteOff(); - - public abstract void MuteOn(); - - public abstract void SetVolume(ushort level); - - public IntFeedback VolumeLevelFeedback { get; private set; } - - public abstract void MuteToggle(); - - public abstract void VolumeDown(bool pressRelease); - - - public abstract void VolumeUp(bool pressRelease); - - #endregion - - #region IHasContentSharing Members - - public abstract void StartSharing(); - public abstract void StopSharing(); - - public bool AutoShareContentWhileInCall { get; protected set; } - - public StringFeedback SharingSourceFeedback { get; private set; } - public BoolFeedback SharingContentIsOnFeedback { get; private set; } - - #endregion - - #region IHasDialer Members - - /// - /// Fires when the status of any active, dialing, or incoming call changes or is new - /// - public event EventHandler CallStatusChange; - - /// - /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected - /// - public bool IsInCall - { - get - { - var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall); - return value; - } - } - - public abstract void Dial(string number); - public abstract void EndCall(CodecActiveCallItem call); - public abstract void EndAllCalls(); - public abstract void AcceptCall(CodecActiveCallItem call); - public abstract void RejectCall(CodecActiveCallItem call); - public abstract void SendDtmf(string s); - - #endregion - - #region IRoutingInputsOutputs Members - - public RoutingPortCollection InputPorts { get; private set; } - - public RoutingPortCollection OutputPorts { get; private set; } - - #endregion - - #region IUsageTracking Members - - /// - /// This object can be added by outside users of this class to provide usage tracking - /// for various services - /// - public UsageTracking UsageTracker { get; set; } - - #endregion - - #region iVideoCodecInfo Members - - public VideoCodecInfo CodecInfo { get; protected set; } - - #endregion - - public event EventHandler IsReadyChange; - public abstract void Dial(Meeting meeting); - - public virtual void Dial(IInvitableContact contact) - { - } - - public abstract void ExecuteSwitch(object selector); - - /// - /// Helper method to fire CallStatusChange event with old and new status - /// - protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call) - { - call.Status = newStatus; - - OnCallStatusChange(call); - } - - /// - /// - /// - /// - /// - /// - protected virtual void OnCallStatusChange(CodecActiveCallItem item) - { - var handler = CallStatusChange; - if (handler != null) - { - handler(this, new CodecCallStatusItemChangeEventArgs(item)); - } - - if (AutoShareContentWhileInCall) - { - StartSharing(); - } - - if (UsageTracker != null) - { - if (IsInCall && !UsageTracker.UsageTrackingStarted) - { - UsageTracker.StartDeviceUsage(); - } - else if (UsageTracker.UsageTrackingStarted && !IsInCall) - { - UsageTracker.EndDeviceUsage(); - } - } - } - - /// - /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data. - /// - protected void SetIsReady() - { - CrestronInvoke.BeginInvoke( (o) => - { - try - { - IsReady = true; - var h = IsReadyChange; - if (h != null) - { - h(this, new EventArgs()); - } - } - catch (Exception e) - { - Debug.Console(2, this, "Error in SetIsReady() : {0}", e); - } - }); - } - - // **** DEBUGGING THINGS **** - /// - /// - /// - public virtual void ListCalls() - { - var sb = new StringBuilder(); - foreach (var c in ActiveCalls) - { - sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status); - } - Debug.Console(1, this, "\n{0}\n", sb.ToString()); - } - - public abstract void StandbyActivate(); - - public abstract void StandbyDeactivate(); - - #region Implementation of IBridgeAdvanced - - public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); - - protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, - EiscApiAdvanced bridge) - { - var joinMap = new VideoCodecControllerJoinMap(joinStart); - - var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); - - if (customJoins != null) - { - joinMap.SetCustomJoinData(customJoins); - } - - if (bridge != null) - { - bridge.AddJoinMap(Key, joinMap); - } - - Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); - - - - LinkVideoCodecDtmfToApi(trilist, joinMap); - - LinkVideoCodecCallControlsToApi(trilist, joinMap); - - LinkVideoCodecContentSharingToApi(trilist, joinMap); - - LinkVideoCodecPrivacyToApi(trilist, joinMap); - - LinkVideoCodecVolumeToApi(trilist, joinMap); - - if (codec is ICommunicationMonitor) - { - LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); - } - - if (codec is IHasCodecCameras) - { - LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); - } - - if (codec is IHasCodecSelfView) - { - LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); - LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); - } - - if (codec is IHasCameraOff) - { - trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); - LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); - } - - if (codec is IHasCodecLayouts) - { - LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); - } - - if (codec is IHasSelfviewPosition) - { - LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); - } - - if (codec is IHasDirectory) - { - LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); - } - - if (codec is IHasScheduleAwareness) - { - LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); - } - - if (codec is IHasParticipants) - { - LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); - } - - if (codec is IHasFarEndContentStatus) - { - (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); - } - - if (codec is IHasPhoneDialing) - { - LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); - } - - trilist.OnlineStatusChange += (device, args) => - { - if (!args.DeviceOnLine) return; - - if (codec is IHasDirectory) - { - (codec as IHasDirectory).SetCurrentDirectoryToRoot(); - } - - if (codec is IHasScheduleAwareness) - { - (codec as IHasScheduleAwareness).GetSchedule(); - } - - if (codec is IHasParticipants) - { - UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); - } - - if (codec is IHasCameraAutoMode) - { - trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); - - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCodecSelfView) - { - (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraAutoMode) - { - (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); - } - - if (codec is IHasCameraOff) - { - (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); - } - - if (codec is IHasPhoneDialing) - { - (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); - } - - SharingContentIsOnFeedback.FireUpdate(); - - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; - } - - private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber, - () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue)); - - trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall); - } - - private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle); - - codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]); - } - - private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff); - - codec.CameraIsOffFeedback.OutputChange += (o, a) => - { - if (a.BoolValue) - { - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - - var autoCodec = codec as IHasCameraAutoMode; - - if (autoCodec == null) return; - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue); - }; - - if (codec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - - var autoModeCodec = codec as IHasCameraAutoMode; - - if (autoModeCodec == null) return; - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); - } - - private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]); - MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn); - trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff); - trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle); - - VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]); - - trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp); - trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown); - - trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume); - - } - - private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]); - PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn); - trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff); - trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle); - } - - private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); - } - - private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.Participants.ParticipantsListHasChanged += (sender, args) => - { - string participantsXSig; - - if (codec.Participants.CurrentParticipants.Count == 0) - { - participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); - return; - } - - participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); - - trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); - - trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort) codec.Participants.CurrentParticipants.Count); - }; - } - - private string UpdateParticipantsXSig(List currentParticipants) - { - const int maxParticipants = 50; - const int maxDigitals = 5; - const int maxStrings = 1; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings * maxParticipants; //15 - var stringIndex = 0; - var meetingIndex = 0; - - var tokenArray = new XSigToken[maxParticipants * offset]; - - foreach (var participant in currentParticipants) - { - if (meetingIndex >= maxParticipants * offset) break; - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb); - tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); - tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); - tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - while (meetingIndex < maxParticipants*offset) - { - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); - tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); - tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); - tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); - SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]); - - SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing); - trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing); - - trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); - } - - private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule); - - trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) => - { - codec.CodecSchedule.MeetingWarningMinutes = i; - }); - - codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap); - - codec.CodecSchedule.MeetingEventChange += - (sender, args) => - { - if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning) - { - UpdateMeetingsList(codec, trilist, joinMap); - } - }; - } - - private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - var currentTime = DateTime.Now; - var currentMeetings = - codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); - - var meetingsData = UpdateMeetingsListXSig(currentMeetings); - - trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); - - trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => - { - if(codec.CodecSchedule.Meetings[0] != null) - Dial(codec.CodecSchedule.Meetings[0]); - }); - trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => - { - if (codec.CodecSchedule.Meetings[1] != null) - Dial(codec.CodecSchedule.Meetings[1]); - }); - trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => - { - if (codec.CodecSchedule.Meetings[2] != null) - Dial(codec.CodecSchedule.Meetings[2]); - }); - - trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)currentMeetings.Count); - } - - private string UpdateMeetingsListXSig(List meetings) - { - const int maxMeetings = 3; - const int maxDigitals = 2; - const int maxStrings = 7; - const int offset = maxDigitals + maxStrings; - var digitalIndex = maxStrings*maxMeetings; //15 - var stringIndex = 0; - var meetingIndex = 0; - - var tokenArray = new XSigToken[maxMeetings*offset]; - /* - * Digitals - * IsJoinable - 1 - * IsDialable - 2 - * - * Serials - * Organizer - 1 - * Title - 2 - * Start Date - 3 - * Start Time - 4 - * End Date - 5 - * End Time - 6 - */ - - - foreach(var meeting in meetings) - { - var currentTime = DateTime.Now; - - if(meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; - - if (meetingIndex >= maxMeetings*offset) - { - Debug.Console(2, this, "Max Meetings reached"); - break;} - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0"); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString()); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString()); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString()); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString()); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); - - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - while (meetingIndex < maxMeetings*offset) - { - Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", - meetingIndex, maxMeetings*offset); - - //digitals - tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); - tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); - - //serials - tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); - tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); - tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); - - digitalIndex += maxDigitals; - meetingIndex += offset; - stringIndex += maxStrings; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig( - trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); - - trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); - - trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory); - - trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i)); - - trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); - - trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents); - - codec.DirectoryResultReturned += (sender, args) => - { - trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort) args.Directory.CurrentDirectoryResults.Count); - - var clearBytes = XSigHelpers.ClearOutputs(); - - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, - Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); - var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); - - trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); - }; - } - - private void SelectDirectoryEntry(IHasDirectory codec, ushort i) - { - var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; - - if (entry is DirectoryFolder) - { - codec.GetDirectoryFolderContents(entry.FolderId); - return; - } - - var dialableEntry = entry as IInvitableContact; - - if (dialableEntry != null) - { - Dial(dialableEntry); - return; - } - - var entryToDial = entry as DirectoryContact; - - if (entryToDial == null) return; - - Dial(entryToDial.ContactMethods[0].Number); - } - - private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) - { - var contactIndex = 1; - var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count]; - - foreach(var entry in directory.CurrentDirectoryResults) - { - var arrayIndex = contactIndex - 1; - - if (entry is DirectoryFolder && entry.ParentFolderId == "root") - { - tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name)); - - contactIndex++; - - continue; - } - - if(isRoot && String.IsNullOrEmpty(entry.FolderId)) continue; - - tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name); - - contactIndex++; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber, - () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue)); - - //End All calls for now - trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls); - - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - CallStatusChange += (sender, args) => - { - trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); - - Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); - Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); - trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); - - if (args.CallItem.Direction == eCodecCallDirection.Incoming) - { - trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); - trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); - } - - trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); - }; - } - - private string UpdateCallStatusXSig() - { - const int maxCalls = 8; - const int maxStrings = 5; - const int offset = 6; - var stringIndex = 0; - var digitalIndex = maxStrings * maxCalls; - var arrayIndex = 0; - - var tokenArray = new XSigToken[maxCalls*offset]; //set array size for number of calls * pieces of info - - foreach (var call in ActiveCalls) - { - if (arrayIndex >= maxCalls * offset) - break; - //digitals - tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); - - //serials - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); - tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); - tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); - - arrayIndex += offset; - stringIndex += maxStrings; - digitalIndex++; - } - while (digitalIndex < maxCalls) - { - //digitals - tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false); - - //serials - tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); - tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); - tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); - tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty); - tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty); - - arrayIndex += offset; - stringIndex += maxStrings; - digitalIndex++; - } - - return GetXSigString(tokenArray); - } - - private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0")); - trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1")); - trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2")); - trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3")); - trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4")); - trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5")); - trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6")); - trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7")); - trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8")); - trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9")); - trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*")); - trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#")); - } - - private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle); - - codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]); - } - - private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); - trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff); - - codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) => - { - var offCodec = codec as IHasCameraOff; - - if (offCodec != null) - { - if (offCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - }; - - var offModeCodec = codec as IHasCameraOff; - - if (offModeCodec != null) - { - if (offModeCodec.CameraIsOffFeedback.BoolValue) - { - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - return; - } - - trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); - trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); - } - - private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist, - VideoCodecControllerJoinMap joinMap) - { - trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle); - - codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]); - } - - private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) - { - //Camera PTZ - trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.TiltUp(); - else camera.TiltStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.TiltDown(); - else camera.TiltStop(); - }); - trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.PanLeft(); - else camera.PanStop(); - }); - trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.PanRight(); - else camera.PanStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.ZoomIn(); - else camera.ZoomStop(); - }); - - trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) => - { - if (codec.SelectedCamera == null) return; - var camera = codec.SelectedCamera as IHasCameraPtzControl; - - if (camera == null) return; - - if (b) camera.ZoomOut(); - else camera.ZoomStop(); - }); - - //Camera Select - trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) => - { - if (codec.SelectedCamera == null) return; - - codec.SelectCamera(codec.Cameras[i].Key); - }); - - codec.CameraSelected += (sender, args) => - { - var i = (ushort) codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key); - - if (codec is IHasCodecRoomPresets) - { - return; - } - - if (!(args.SelectedCamera is IHasCameraPresets)) - { - return; - } - - var cam = args.SelectedCamera as IHasCameraPresets; - SetCameraPresetNames(cam.Presets); - - (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets); - - trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, - (a) => - { - cam.PresetSelect(a); - trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a); - }); - - trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, - () => - { - cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, - String.Empty); - trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); - }); - }; - - if (!(codec is IHasCodecRoomPresets)) return; - - var presetCodec = codec as IHasCodecRoomPresets; - - presetCodec.CodecRoomPresetsListHasChanged += - (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets); - - //Camera Presets - trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) => - { - presetCodec.CodecRoomPresetSelect(i); - - trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i); - }); - - trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, - () => - { - presetCodec.CodecRoomPresetStore( - trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty); - trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); - }); - } - - private string SetCameraPresetNames(IEnumerable presets) - { - return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); - } - - private string SetCameraPresetNames(IEnumerable presets) - { - return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); - } - - private string SetCameraPresetNames(ICollection presets) - { - var i = 1; //start index for xsig; - - var tokenArray = new XSigToken[presets.Count]; - - foreach (var preset in presets) - { - var cameraPreset = new XSigSerialToken(i, preset); - tokenArray[i - 1] = cameraPreset; - i++; - } - - return GetXSigString(tokenArray); - } - - private string GetXSigString(XSigToken[] tokenArray) - { - string returnString; - using (var s = new MemoryStream()) - { - using (var tw = new XSigTokenStreamWriter(s, true)) - { - tw.WriteXSigData(tokenArray); - } - - var xSig = s.ToArray(); - - returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length); - } - - return returnString; - } - - #endregion - } - - - /// - /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info - /// - public class CodecPhonebookSyncState : IKeyed - { - private bool _InitialSyncComplete; - - public CodecPhonebookSyncState(string key) - { - Key = key; - - CodecDisconnected(); - } - - public bool InitialSyncComplete - { - get { return _InitialSyncComplete; } - private set - { - if (value == true) - { - var handler = InitialSyncCompleted; - if (handler != null) - { - handler(this, new EventArgs()); - } - } - _InitialSyncComplete = value; - } - } - - public bool InitialPhonebookFoldersWasReceived { get; private set; } - - public bool NumberOfContactsWasReceived { get; private set; } - - public bool PhonebookRootEntriesWasRecieved { get; private set; } - - public bool PhonebookHasFolders { get; private set; } - - public int NumberOfContacts { get; private set; } - - #region IKeyed Members - - public string Key { get; private set; } - - #endregion - - public event EventHandler InitialSyncCompleted; - - public void InitialPhonebookFoldersReceived() - { - InitialPhonebookFoldersWasReceived = true; - - CheckSyncStatus(); - } - - public void PhonebookRootEntriesReceived() - { - PhonebookRootEntriesWasRecieved = true; - - CheckSyncStatus(); - } - - public void SetPhonebookHasFolders(bool value) - { - PhonebookHasFolders = value; - - Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders); - } - - public void SetNumberOfContacts(int contacts) - { - NumberOfContacts = contacts; - NumberOfContactsWasReceived = true; - - Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts); - - CheckSyncStatus(); - } - - public void CodecDisconnected() - { - InitialPhonebookFoldersWasReceived = false; - PhonebookHasFolders = false; - NumberOfContacts = 0; - NumberOfContactsWasReceived = false; - } - - private void CheckSyncStatus() - { - if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) - { - InitialSyncComplete = true; - Debug.Console(1, this, "Initial Phonebook Sync Complete!"); - } - else - { - InitialSyncComplete = false; - } - } - } + }; + } + } + + protected abstract Func SharingSourceFeedbackFunc { get; } + protected abstract Func SharingContentIsOnFeedbackFunc { get; } + + #region ICodecAudio Members + + public abstract void PrivacyModeOn(); + public abstract void PrivacyModeOff(); + public abstract void PrivacyModeToggle(); + public BoolFeedback PrivacyModeIsOnFeedback { get; private set; } + + + public BoolFeedback MuteFeedback { get; private set; } + + public abstract void MuteOff(); + + public abstract void MuteOn(); + + public abstract void SetVolume(ushort level); + + public IntFeedback VolumeLevelFeedback { get; private set; } + + public abstract void MuteToggle(); + + public abstract void VolumeDown(bool pressRelease); + + + public abstract void VolumeUp(bool pressRelease); + + #endregion + + #region IHasContentSharing Members + + public abstract void StartSharing(); + public abstract void StopSharing(); + + public bool AutoShareContentWhileInCall { get; protected set; } + + public StringFeedback SharingSourceFeedback { get; private set; } + public BoolFeedback SharingContentIsOnFeedback { get; private set; } + + #endregion + + #region IHasDialer Members + + /// + /// Fires when the status of any active, dialing, or incoming call changes or is new + /// + public event EventHandler CallStatusChange; + + /// + /// Returns true when any call is not in state Unknown, Disconnecting, Disconnected + /// + public bool IsInCall + { + get + { + var value = ActiveCalls != null && ActiveCalls.Any(c => c.IsActiveCall); + return value; + } + } + + public abstract void Dial(string number); + public abstract void EndCall(CodecActiveCallItem call); + public abstract void EndAllCalls(); + public abstract void AcceptCall(CodecActiveCallItem call); + public abstract void RejectCall(CodecActiveCallItem call); + public abstract void SendDtmf(string s); + + #endregion + + #region IRoutingInputsOutputs Members + + public RoutingPortCollection InputPorts { get; private set; } + + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + #region IUsageTracking Members + + /// + /// This object can be added by outside users of this class to provide usage tracking + /// for various services + /// + public UsageTracking UsageTracker { get; set; } + + #endregion + + #region iVideoCodecInfo Members + + public VideoCodecInfo CodecInfo { get; protected set; } + + #endregion + + public event EventHandler IsReadyChange; + public abstract void Dial(Meeting meeting); + + public virtual void Dial(IInvitableContact contact) + { + } + + public abstract void ExecuteSwitch(object selector); + + /// + /// Helper method to fire CallStatusChange event with old and new status + /// + protected void SetNewCallStatusAndFireCallStatusChange(eCodecCallStatus newStatus, CodecActiveCallItem call) + { + call.Status = newStatus; + + OnCallStatusChange(call); + } + + /// + /// + /// + /// + /// + /// + protected virtual void OnCallStatusChange(CodecActiveCallItem item) + { + var handler = CallStatusChange; + if (handler != null) + { + handler(this, new CodecCallStatusItemChangeEventArgs(item)); + } + + if (AutoShareContentWhileInCall) + { + StartSharing(); + } + + if (UsageTracker != null) + { + if (IsInCall && !UsageTracker.UsageTrackingStarted) + { + UsageTracker.StartDeviceUsage(); + } + else if (UsageTracker.UsageTrackingStarted && !IsInCall) + { + UsageTracker.EndDeviceUsage(); + } + } + } + + /// + /// Sets IsReady property and fires the event. Used for dependent classes to sync up their data. + /// + protected void SetIsReady() + { + CrestronInvoke.BeginInvoke((o) => + { + try + { + IsReady = true; + var h = IsReadyChange; + if (h != null) + { + h(this, new EventArgs()); + } + } + catch (Exception e) + { + Debug.Console(2, this, "Error in SetIsReady() : {0}", e); + } + }); + } + + // **** DEBUGGING THINGS **** + /// + /// + /// + public virtual void ListCalls() + { + var sb = new StringBuilder(); + foreach (var c in ActiveCalls) + { + sb.AppendFormat("{0} {1} -- {2} {3}\n", c.Id, c.Number, c.Name, c.Status); + } + Debug.Console(1, this, "\n{0}\n", sb.ToString()); + } + + public abstract void StandbyActivate(); + + public abstract void StandbyDeactivate(); + + #region Implementation of IBridgeAdvanced + + public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge); + + protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey, + EiscApiAdvanced bridge) + { + var joinMap = new VideoCodecControllerJoinMap(joinStart); + + var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey); + + if (customJoins != null) + { + joinMap.SetCustomJoinData(customJoins); + } + + if (bridge != null) + { + bridge.AddJoinMap(Key, joinMap); + } + + Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X")); + + + + LinkVideoCodecDtmfToApi(trilist, joinMap); + + LinkVideoCodecCallControlsToApi(trilist, joinMap); + + LinkVideoCodecContentSharingToApi(trilist, joinMap); + + LinkVideoCodecPrivacyToApi(trilist, joinMap); + + LinkVideoCodecVolumeToApi(trilist, joinMap); + + if (codec is ICommunicationMonitor) + { + LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap); + } + + if (codec is IHasCodecCameras) + { + LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap); + } + + if (codec is IHasCodecSelfView) + { + LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode); + LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap); + } + + if (codec is IHasCameraOff) + { + trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff); + LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap); + } + + if (codec is IHasCodecLayouts) + { + LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); + } + + if (codec is IHasSelfviewPosition) + { + LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); + } + + if (codec is IHasDirectory) + { + LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap); + } + + if (codec is IHasScheduleAwareness) + { + LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap); + } + + if (codec is IHasParticipants) + { + LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap); + } + + if (codec is IHasFarEndContentStatus) + { + (codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]); + } + + if (codec is IHasPhoneDialing) + { + LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap); + } + + trilist.OnlineStatusChange += (device, args) => + { + if (!args.DeviceOnLine) return; + + if (codec is IHasDirectory) + { + (codec as IHasDirectory).SetCurrentDirectoryToRoot(); + } + + if (codec is IHasScheduleAwareness) + { + (codec as IHasScheduleAwareness).GetSchedule(); + } + + if (codec is IHasParticipants) + { + UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants); + } + + if (codec is IHasCameraAutoMode) + { + trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true); + + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCodecSelfView) + { + (codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraAutoMode) + { + (codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate(); + } + + if (codec is IHasCameraOff) + { + (codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate(); + } + + if (codec is IHasPhoneDialing) + { + (codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate(); + } + + SharingContentIsOnFeedback.FireUpdate(); + + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } + + private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.DialPhone.JoinNumber, + () => codec.DialPhoneCall(trilist.StringOutput[joinMap.PhoneDialString.JoinNumber].StringValue)); + + trilist.SetSigFalseAction(joinMap.HangUpPhone.JoinNumber, codec.EndPhoneCall); + } + + private void LinkVideoCodecSelfviewPositionToApi(IHasSelfviewPosition codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.SelfviewPosition.JoinNumber, codec.SelfviewPipPositionToggle); + + codec.SelfviewPipPositionFeedback.LinkInputSig(trilist.StringInput[joinMap.SelfviewPositionFb.JoinNumber]); + } + + private void LinkVideoCodecCameraOffToApi(IHasCameraOff codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraModeOff.JoinNumber, codec.CameraOff); + + codec.CameraIsOffFeedback.OutputChange += (o, a) => + { + if (a.BoolValue) + { + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + + var autoCodec = codec as IHasCameraAutoMode; + + if (autoCodec == null) return; + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoCodec.CameraAutoModeIsOnFeedback.BoolValue); + }; + + if (codec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + + var autoModeCodec = codec as IHasCameraAutoMode; + + if (autoModeCodec == null) return; + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !autoModeCodec.CameraAutoModeIsOnFeedback.BoolValue); + } + + private void LinkVideoCodecVolumeToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]); + MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.VolumeMuteOn.JoinNumber, MuteOn); + trilist.SetSigFalseAction(joinMap.VolumeMuteOff.JoinNumber, MuteOff); + trilist.SetSigFalseAction(joinMap.VolumeMuteToggle.JoinNumber, MuteToggle); + + VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]); + + trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, VolumeUp); + trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, VolumeDown); + + trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, SetVolume); + + } + + private void LinkVideoCodecPrivacyToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + PrivacyModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.MicMuteOn.JoinNumber]); + PrivacyModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.MicMuteOff.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.MicMuteOn.JoinNumber, PrivacyModeOn); + trilist.SetSigFalseAction(joinMap.MicMuteOff.JoinNumber, PrivacyModeOff); + trilist.SetSigFalseAction(joinMap.MicMuteToggle.JoinNumber, PrivacyModeToggle); + } + + private void LinkVideoCodecCommMonitorToApi(ICommunicationMonitor codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); + } + + private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.Participants.ParticipantsListHasChanged += (sender, args) => + { + string participantsXSig; + + if (codec.Participants.CurrentParticipants.Count == 0) + { + participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length); + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + return; + } + + participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants); + + trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig); + + trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count); + }; + } + + private string UpdateParticipantsXSig(List currentParticipants) + { + const int maxParticipants = 50; + const int maxDigitals = 5; + const int maxStrings = 1; + const int offset = maxDigitals + maxStrings; + var digitalIndex = maxStrings * maxParticipants; //15 + var stringIndex = 0; + var meetingIndex = 0; + + var tokenArray = new XSigToken[maxParticipants * offset]; + + foreach (var participant in currentParticipants) + { + if (meetingIndex >= maxParticipants * offset) break; + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb); + tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo); + tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo); + tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + while (meetingIndex < maxParticipants * offset) + { + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false); + tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false); + tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]); + SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]); + + SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing); + trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing); + + trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b); + } + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + private List _currentMeetings = new List(); + + private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule); + + trilist.SetUShortSigAction(joinMap.MinutesBeforeMeetingStart.JoinNumber, (i) => + { + codec.CodecSchedule.MeetingWarningMinutes = i; + }); + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting1.JoinNumber, () => + { + var mtg = 1; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting1.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting2.JoinNumber, () => + { + var mtg = 2; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting2.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + trilist.SetSigFalseAction(joinMap.DialMeeting3.JoinNumber, () => + { + var mtg = 3; + var index = mtg - 1; + Debug.Console(1, this, "Meeting {0} Selected (EISC dig-o{1}) > _currentMeetings[{2}].Id: {3}, Title: {4}", + mtg, joinMap.DialMeeting3.JoinNumber, index, _currentMeetings[index].Id, _currentMeetings[index].Title); + if (_currentMeetings[index] != null) + Dial(_currentMeetings[index]); + }); + + codec.CodecSchedule.MeetingsListHasChanged += (sender, args) => UpdateMeetingsList(codec, trilist, joinMap); + codec.CodecSchedule.MeetingEventChange += (sender, args) => + { + if (args.ChangeType == eMeetingEventChangeType.MeetingStartWarning) + { + UpdateMeetingsList(codec, trilist, joinMap); + } + }; + } + + private void UpdateMeetingsList(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + var currentTime = DateTime.Now; + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + // - changed var currentMeetings >> field _currentMeetings + //_currentMeetings.Clear(); + _currentMeetings = codec.CodecSchedule.Meetings.Where(m => m.StartTime >= currentTime || m.EndTime >= currentTime).ToList(); + + // TODO [ ] 2021-01-06, jkd: Added to debug OBTP dialing issues + // - moved the trilist.SetSigFlaseAction(joinMap.DialMeeting1..3.JoinNumber) lambda's to LinkVideoCodecScheduleToApi + + var meetingsData = UpdateMeetingsListXSig(_currentMeetings); + trilist.SetString(joinMap.Schedule.JoinNumber, meetingsData); + trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort)_currentMeetings.Count); + } + + private string UpdateMeetingsListXSig(List meetings) + { + const int maxMeetings = 3; + const int maxDigitals = 2; + const int maxStrings = 7; + const int offset = maxDigitals + maxStrings; + var digitalIndex = maxStrings * maxMeetings; //15 + var stringIndex = 0; + var meetingIndex = 0; + + var tokenArray = new XSigToken[maxMeetings * offset]; + /* + * Digitals + * IsJoinable - 1 + * IsDialable - 2 + * + * Serials + * Organizer - 1 + * Title - 2 + * Start Date - 3 + * Start Time - 4 + * End Date - 5 + * End Time - 6 + * Id - 7 + */ + + + foreach (var meeting in meetings) + { + var currentTime = DateTime.Now; + + if (meeting.StartTime < currentTime && meeting.EndTime < currentTime) continue; + + if (meetingIndex >= maxMeetings * offset) + { + Debug.Console(2, this, "Max Meetings reached"); + break; + } + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0"); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString()); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString()); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString()); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString()); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id); + + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + while (meetingIndex < maxMeetings * offset) + { + Debug.Console(2, this, "Clearing unused data. Meeting Index: {0} MaxMeetings * Offset: {1}", + meetingIndex, maxMeetings * offset); + + //digitals + tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false); + tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false); + + //serials + tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty); + tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty); + tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, String.Empty); + + digitalIndex += maxDigitals; + meetingIndex += offset; + stringIndex += maxStrings; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecDirectoryToApi(IHasDirectory codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + codec.CurrentDirectoryResultIsNotDirectoryRoot.LinkComplementInputSig( + trilist.BooleanInput[joinMap.DirectoryIsRoot.JoinNumber]); + + trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); + + trilist.SetStringSigAction(joinMap.DirectorySearchString.JoinNumber, codec.SearchDirectory); + + trilist.SetUShortSigAction(joinMap.DirectorySelectRow.JoinNumber, (i) => SelectDirectoryEntry(codec, i)); + + trilist.SetSigFalseAction(joinMap.DirectoryRoot.JoinNumber, codec.SetCurrentDirectoryToRoot); + + trilist.SetSigFalseAction(joinMap.DirectoryFolderBack.JoinNumber, codec.GetDirectoryParentFolderContents); + + codec.DirectoryResultReturned += (sender, args) => + { + trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)args.Directory.CurrentDirectoryResults.Count); + + var clearBytes = XSigHelpers.ClearOutputs(); + + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, + Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length)); + var directoryXSig = UpdateDirectoryXSig(args.Directory, !codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue); + + trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig); + }; + } + + private void SelectDirectoryEntry(IHasDirectory codec, ushort i) + { + var entry = codec.CurrentDirectoryResult.CurrentDirectoryResults[i - 1]; + + if (entry is DirectoryFolder) + { + codec.GetDirectoryFolderContents(entry.FolderId); + return; + } + + var dialableEntry = entry as IInvitableContact; + + if (dialableEntry != null) + { + Dial(dialableEntry); + return; + } + + var entryToDial = entry as DirectoryContact; + + if (entryToDial == null) return; + + Dial(entryToDial.ContactMethods[0].Number); + } + + private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot) + { + var contactIndex = 1; + var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count]; + + foreach (var entry in directory.CurrentDirectoryResults) + { + var arrayIndex = contactIndex - 1; + + if (entry is DirectoryFolder && entry.ParentFolderId == "root") + { + tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, String.Format("[+] {0}", entry.Name)); + + contactIndex++; + + continue; + } + + if (isRoot && String.IsNullOrEmpty(entry.FolderId)) continue; + + tokenArray[arrayIndex] = new XSigSerialToken(contactIndex, entry.Name); + + contactIndex++; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.ManualDial.JoinNumber, + () => Dial(trilist.StringOutput[joinMap.CurrentDialString.JoinNumber].StringValue)); + + //End All calls for now + trilist.SetSigFalseAction(joinMap.EndCall.JoinNumber, EndAllCalls); + + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + CallStatusChange += (sender, args) => + { + trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall); + + Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); + Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); + trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); + + if (args.CallItem.Direction == eCodecCallDirection.Incoming) + { + trilist.SetSigFalseAction(joinMap.IncomingAnswer.JoinNumber, () => AcceptCall(args.CallItem)); + trilist.SetSigFalseAction(joinMap.IncomingReject.JoinNumber, () => RejectCall(args.CallItem)); + } + + trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig()); + }; + } + + private string UpdateCallStatusXSig() + { + const int maxCalls = 8; + const int maxStrings = 5; + const int offset = 6; + var stringIndex = 0; + var digitalIndex = maxStrings * maxCalls; + var arrayIndex = 0; + + var tokenArray = new XSigToken[maxCalls * offset]; //set array size for number of calls * pieces of info + + foreach (var call in ActiveCalls) + { + if (arrayIndex >= maxCalls * offset) + break; + //digitals + tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, call.IsActiveCall); + + //serials + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString()); + tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, call.Type.ToString()); + tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, call.Status.ToString()); + + arrayIndex += offset; + stringIndex += maxStrings; + digitalIndex++; + } + while (digitalIndex < maxCalls) + { + //digitals + tokenArray[arrayIndex] = new XSigDigitalToken(digitalIndex + 1, false); + + //serials + tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 1, String.Empty); + tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 2, String.Empty); + tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 3, String.Empty); + tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 4, String.Empty); + tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 5, String.Empty); + + arrayIndex += offset; + stringIndex += maxStrings; + digitalIndex++; + } + + return GetXSigString(tokenArray); + } + + private void LinkVideoCodecDtmfToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.Dtmf0.JoinNumber, () => SendDtmf("0")); + trilist.SetSigFalseAction(joinMap.Dtmf1.JoinNumber, () => SendDtmf("1")); + trilist.SetSigFalseAction(joinMap.Dtmf2.JoinNumber, () => SendDtmf("2")); + trilist.SetSigFalseAction(joinMap.Dtmf3.JoinNumber, () => SendDtmf("3")); + trilist.SetSigFalseAction(joinMap.Dtmf4.JoinNumber, () => SendDtmf("4")); + trilist.SetSigFalseAction(joinMap.Dtmf5.JoinNumber, () => SendDtmf("5")); + trilist.SetSigFalseAction(joinMap.Dtmf6.JoinNumber, () => SendDtmf("6")); + trilist.SetSigFalseAction(joinMap.Dtmf7.JoinNumber, () => SendDtmf("7")); + trilist.SetSigFalseAction(joinMap.Dtmf8.JoinNumber, () => SendDtmf("8")); + trilist.SetSigFalseAction(joinMap.Dtmf9.JoinNumber, () => SendDtmf("9")); + trilist.SetSigFalseAction(joinMap.DtmfStar.JoinNumber, () => SendDtmf("*")); + trilist.SetSigFalseAction(joinMap.DtmfPound.JoinNumber, () => SendDtmf("#")); + } + + private void LinkVideoCodecCameraLayoutsToApi(IHasCodecLayouts codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraLayout.JoinNumber, codec.LocalLayoutToggle); + + codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CameraLayoutStringFb.JoinNumber]); + } + + private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); + trilist.SetSigFalseAction(joinMap.CameraModeManual.JoinNumber, codec.CameraAutoModeOff); + + codec.CameraAutoModeIsOnFeedback.OutputChange += (o, a) => + { + var offCodec = codec as IHasCameraOff; + + if (offCodec != null) + { + if (offCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, a.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !a.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + }; + + var offModeCodec = codec as IHasCameraOff; + + if (offModeCodec != null) + { + if (offModeCodec.CameraIsOffFeedback.BoolValue) + { + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, false); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, true); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + return; + } + + trilist.SetBool(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeManual.JoinNumber, !codec.CameraAutoModeIsOnFeedback.BoolValue); + trilist.SetBool(joinMap.CameraModeOff.JoinNumber, false); + } + + private void LinkVideoCodecSelfviewToApi(IHasCodecSelfView codec, BasicTriList trilist, + VideoCodecControllerJoinMap joinMap) + { + trilist.SetSigFalseAction(joinMap.CameraSelfView.JoinNumber, codec.SelfViewModeToggle); + + codec.SelfviewIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CameraSelfView.JoinNumber]); + } + + private void LinkVideoCodecCameraToApi(IHasCodecCameras codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) + { + //Camera PTZ + trilist.SetBoolSigAction(joinMap.CameraTiltUp.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.TiltUp(); + else camera.TiltStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraTiltDown.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.TiltDown(); + else camera.TiltStop(); + }); + trilist.SetBoolSigAction(joinMap.CameraPanLeft.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.PanLeft(); + else camera.PanStop(); + }); + trilist.SetBoolSigAction(joinMap.CameraPanRight.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.PanRight(); + else camera.PanStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraZoomIn.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.ZoomIn(); + else camera.ZoomStop(); + }); + + trilist.SetBoolSigAction(joinMap.CameraZoomOut.JoinNumber, (b) => + { + if (codec.SelectedCamera == null) return; + var camera = codec.SelectedCamera as IHasCameraPtzControl; + + if (camera == null) return; + + if (b) camera.ZoomOut(); + else camera.ZoomStop(); + }); + + //Camera Select + trilist.SetUShortSigAction(joinMap.CameraNumberSelect.JoinNumber, (i) => + { + if (codec.SelectedCamera == null) return; + + codec.SelectCamera(codec.Cameras[i].Key); + }); + + codec.CameraSelected += (sender, args) => + { + var i = (ushort)codec.Cameras.FindIndex((c) => c.Key == args.SelectedCamera.Key); + + if (codec is IHasCodecRoomPresets) + { + return; + } + + if (!(args.SelectedCamera is IHasCameraPresets)) + { + return; + } + + var cam = args.SelectedCamera as IHasCameraPresets; + SetCameraPresetNames(cam.Presets); + + (args.SelectedCamera as IHasCameraPresets).PresetsListHasChanged += (o, eventArgs) => SetCameraPresetNames(cam.Presets); + + trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, + (a) => + { + cam.PresetSelect(a); + trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, a); + }); + + trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, + () => + { + cam.PresetStore(trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, + String.Empty); + trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); + }); + }; + + if (!(codec is IHasCodecRoomPresets)) return; + + var presetCodec = codec as IHasCodecRoomPresets; + + presetCodec.CodecRoomPresetsListHasChanged += + (sender, args) => SetCameraPresetNames(presetCodec.NearEndPresets); + + //Camera Presets + trilist.SetUShortSigAction(joinMap.CameraPresetSelect.JoinNumber, (i) => + { + presetCodec.CodecRoomPresetSelect(i); + + trilist.SetUshort(joinMap.CameraPresetSelect.JoinNumber, i); + }); + + trilist.SetSigFalseAction(joinMap.CameraPresetSave.JoinNumber, + () => + { + presetCodec.CodecRoomPresetStore( + trilist.UShortOutput[joinMap.CameraPresetSelect.JoinNumber].UShortValue, String.Empty); + trilist.PulseBool(joinMap.CameraPresetSave.JoinNumber, 3000); + }); + } + + private string SetCameraPresetNames(IEnumerable presets) + { + return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); + } + + private string SetCameraPresetNames(IEnumerable presets) + { + return SetCameraPresetNames(presets.Select(p => p.Description).ToList()); + } + + private string SetCameraPresetNames(ICollection presets) + { + var i = 1; //start index for xsig; + + var tokenArray = new XSigToken[presets.Count]; + + foreach (var preset in presets) + { + var cameraPreset = new XSigSerialToken(i, preset); + tokenArray[i - 1] = cameraPreset; + i++; + } + + return GetXSigString(tokenArray); + } + + private string GetXSigString(XSigToken[] tokenArray) + { + string returnString; + using (var s = new MemoryStream()) + { + using (var tw = new XSigTokenStreamWriter(s, true)) + { + tw.WriteXSigData(tokenArray); + } + + var xSig = s.ToArray(); + + returnString = Encoding.GetEncoding(XSigEncoding).GetString(xSig, 0, xSig.Length); + } + + return returnString; + } + + #endregion + } + + + /// + /// Used to track the status of syncronizing the phonebook values when connecting to a codec or refreshing the phonebook info + /// + public class CodecPhonebookSyncState : IKeyed + { + private bool _InitialSyncComplete; + + public CodecPhonebookSyncState(string key) + { + Key = key; + + CodecDisconnected(); + } + + public bool InitialSyncComplete + { + get { return _InitialSyncComplete; } + private set + { + if (value == true) + { + var handler = InitialSyncCompleted; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + _InitialSyncComplete = value; + } + } + + public bool InitialPhonebookFoldersWasReceived { get; private set; } + + public bool NumberOfContactsWasReceived { get; private set; } + + public bool PhonebookRootEntriesWasRecieved { get; private set; } + + public bool PhonebookHasFolders { get; private set; } + + public int NumberOfContacts { get; private set; } + + #region IKeyed Members + + public string Key { get; private set; } + + #endregion + + public event EventHandler InitialSyncCompleted; + + public void InitialPhonebookFoldersReceived() + { + InitialPhonebookFoldersWasReceived = true; + + CheckSyncStatus(); + } + + public void PhonebookRootEntriesReceived() + { + PhonebookRootEntriesWasRecieved = true; + + CheckSyncStatus(); + } + + public void SetPhonebookHasFolders(bool value) + { + PhonebookHasFolders = value; + + Debug.Console(1, this, "Phonebook has folders: {0}", PhonebookHasFolders); + } + + public void SetNumberOfContacts(int contacts) + { + NumberOfContacts = contacts; + NumberOfContactsWasReceived = true; + + Debug.Console(1, this, "Phonebook contains {0} contacts.", NumberOfContacts); + + CheckSyncStatus(); + } + + public void CodecDisconnected() + { + InitialPhonebookFoldersWasReceived = false; + PhonebookHasFolders = false; + NumberOfContacts = 0; + NumberOfContactsWasReceived = false; + } + + private void CheckSyncStatus() + { + if (InitialPhonebookFoldersWasReceived && NumberOfContactsWasReceived && PhonebookRootEntriesWasRecieved) + { + InitialSyncComplete = true; + Debug.Console(1, this, "Initial Phonebook Sync Complete!"); + } + else + { + InitialSyncComplete = false; + } + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs index fc440e5b..980c7a61 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs @@ -1655,6 +1655,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom public override void Dial(Meeting meeting) { + Debug.Console(1, this,"Dialing meeting.Id: {0} Title: {1}", meeting.Id, meeting.Title); SendText(string.Format("zCommand Dial Start meetingNumber: {0}", meeting.Id)); } From 89990971001734da09d7a02a0ea6b15452e20a21 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 6 Jan 2021 16:12:12 -0700 Subject: [PATCH 09/14] Adds additional debug to help with room on/off events --- .../Room/Types/EssentialsTechRoom.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs index 0a47933e..bfa56646 100644 --- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs +++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs @@ -261,8 +261,16 @@ namespace PepperDash.Essentials CrestronInvoke.BeginInvoke((o) => { + Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count); + foreach (var a in eventConfig.Actions) { + Debug.Console(2, this, +@"Attempting to run action: +DeviceKey: {0} +MethodName: {1} +Params: {2}" + , a.DeviceKey, a.MethodName, a.Params); DeviceJsonApi.DoDeviceAction(a); } }); @@ -271,6 +279,8 @@ namespace PepperDash.Essentials public void RoomPowerOn() { + Debug.Console(2, this, "Room Powering On"); + var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs; if (dummySource == null) @@ -287,6 +297,8 @@ namespace PepperDash.Essentials public void RoomPowerOff() { + Debug.Console(2, this, "Room Powering Off"); + foreach (var display in _displays) { display.Value.PowerOff(); From 3c1ed6e58aac601f4db9442ff8a8f654caa9d547 Mon Sep 17 00:00:00 2001 From: Trevor Payne Date: Thu, 7 Jan 2021 12:41:29 -0600 Subject: [PATCH 10/14] Added debug statements to ExecuteNumericSwitch in DmTx4kz302CController --- .../Endpoints/Transmitters/DmTx4kz302CController.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index 1e44396c..1c5ce36e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -282,6 +282,12 @@ namespace PepperDash.Essentials.DM ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); break; } + default: + { + Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input); + break; + } + } @@ -289,6 +295,7 @@ namespace PepperDash.Essentials.DM public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) { + Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) Tx.VideoSource = (eVst)inputSelector; From 82029894e47bc5a06ca07fe21ab3bdc9d1ae4794 Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 7 Jan 2021 14:46:49 -0700 Subject: [PATCH 11/14] Changed to use passed in type value for signal type instead of assuming both audio and video --- .../Transmitters/DmTx4kz302CController.cs | 713 +++++++++--------- 1 file changed, 360 insertions(+), 353 deletions(-) diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs index 1c5ce36e..fb8f3ac5 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs @@ -1,44 +1,44 @@ -using Crestron.SimplSharpPro; -using System; -using System.Linq; -//using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.DM -{ - using eVst = eX02VideoSourceType; - using eAst = eX02AudioSourceType; - - +using Crestron.SimplSharpPro; +using System; +using System.Linq; +//using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.DM +{ + using eVst = eX02VideoSourceType; + using eAst = eX02AudioSourceType; + + [Description("Wrapper class for DM-TX-4K-Z-302-C")] - public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback, - IIROutputPorts, IComPorts - { - public DmTx4kz302C Tx { get; private set; } - - public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } - public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } - public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } - public RoutingOutputPort DmOut { get; private set; } - public RoutingOutputPort HdmiLoopOut { get; private set; } - - public override StringFeedback ActiveVideoInputFeedback { get; protected set; } - public IntFeedback VideoSourceNumericFeedback { get; protected set; } - public IntFeedback AudioSourceNumericFeedback { get; protected set; } - public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } - public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } - public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } - public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } - public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } - - //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } + public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback, + IIROutputPorts, IComPorts + { + public DmTx4kz302C Tx { get; private set; } + + public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; } + public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; } + public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; } + public RoutingOutputPort DmOut { get; private set; } + public RoutingOutputPort HdmiLoopOut { get; private set; } + + public override StringFeedback ActiveVideoInputFeedback { get; protected set; } + public IntFeedback VideoSourceNumericFeedback { get; protected set; } + public IntFeedback AudioSourceNumericFeedback { get; protected set; } + public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } + public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } + public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } + public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } + public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } + + //public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; } //IroutingNumericEvent @@ -52,279 +52,286 @@ namespace PepperDash.Essentials.DM { var newEvent = NumericSwitchChange; if (newEvent != null) newEvent(this, e); - } - - /// - /// Helps get the "real" inputs, including when in Auto - /// - public eX02VideoSourceType ActualActiveVideoInput - { - get - { - if (Tx.VideoSourceFeedback != eVst.Auto) - return Tx.VideoSourceFeedback; - if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - return eVst.Hdmi1; - if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) - return eVst.Hdmi2; - - return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled; - } - } - public RoutingPortCollection InputPorts - { - get - { - return new RoutingPortCollection - { - HdmiIn1, - HdmiIn2, - DisplayPortIn, - AnyVideoInput - }; - } - } - public RoutingPortCollection OutputPorts - { - get - { - return new RoutingPortCollection { DmOut, HdmiLoopOut }; - } - } - public DmTx4kz302CController(string key, string name, DmTx4kz302C tx) - : base(key, name, tx) - { - Tx = tx; - - HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, + } + + /// + /// Helps get the "real" inputs, including when in Auto + /// + public eX02VideoSourceType ActualActiveVideoInput + { + get + { + if (Tx.VideoSourceFeedback != eVst.Auto) + return Tx.VideoSourceFeedback; + if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + return eVst.Hdmi1; + if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) + return eVst.Hdmi2; + + return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled; + } + } + public RoutingPortCollection InputPorts + { + get + { + return new RoutingPortCollection + { + HdmiIn1, + HdmiIn2, + DisplayPortIn, + AnyVideoInput + }; + } + } + public RoutingPortCollection OutputPorts + { + get + { + return new RoutingPortCollection { DmOut, HdmiLoopOut }; + } + } + public DmTx4kz302CController(string key, string name, DmTx4kz302C tx) + : base(key, name, tx) + { + Tx = tx; + + HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])) { FeedbackMatchObject = eVst.Hdmi1 - }; - HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, + }; + HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])) { FeedbackMatchObject = eVst.Hdmi2 - }; - DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this, + }; + DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this, VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput)) { FeedbackMatchObject = eVst.DisplayPort - }; - ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", - () => ActualActiveVideoInput.ToString()); - - Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; - Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; - Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange; - Tx.BaseEvent += Tx_BaseEvent; - Tx.OnlineStatusChange += Tx_OnlineStatusChange; - - VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); - - HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); - - HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpStateFeedback = - new IntFeedback( - () => - tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback - ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback - : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); - - HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; - - Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); - - Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); - - DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue); - - - var combinedFuncs = new VideoStatusFuncsWrapper - { - HdcpActiveFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), - - HdcpStateFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); - return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : ""; - }, - - VideoResolutionFeedbackFunc = () => - { - if (ActualActiveVideoInput == eVst.Hdmi1) - return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); - if (ActualActiveVideoInput == eVst.Hdmi2) - return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); - return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : ""; - }, - VideoSyncFeedbackFunc = () => - (ActualActiveVideoInput == eVst.Hdmi1 - && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Hdmi2 - && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) - || (ActualActiveVideoInput == eVst.Vga - && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) - - }; - - AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, - eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); - - DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.DmCat, null, this); - HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - - - AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, - AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, - AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, - AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, - Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback); - - // Set Ports for CEC - HdmiIn1.Port = Tx.HdmiInputs[1]; - HdmiIn2.Port = Tx.HdmiInputs[2]; - HdmiLoopOut.Port = Tx.HdmiOutput; - DmOut.Port = Tx.DmOutput; - } - - void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) - { - Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); - - switch (args.EventId) - { - case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: - DisplayPortVideoSyncFeedback.FireUpdate(); - break; - } - } - - - - public override bool CustomActivate() - { - // Link up all of these damned events to the various RoutingPorts via a helper handler - Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); - Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); - - Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); - Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); - - Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); - Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); - - // Base does register and sets up comm monitoring. - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) - { - var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); - - if (Hdmi1VideoSyncFeedback != null) - { - Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); - } - if (Hdmi2VideoSyncFeedback != null) - { - Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); - } - if (DisplayPortVideoSyncFeedback != null) - { - DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]); - } - - LinkDmTxToApi(this, trilist, joinMap, bridge); - } - - public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) - { - Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); - - switch (input) - { - case 0: - { - ExecuteSwitch(eVst.Auto, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 1: - { - ExecuteSwitch(HdmiIn1.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 2: - { - ExecuteSwitch(HdmiIn2.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 3: - { - ExecuteSwitch(DisplayPortIn.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } - case 4: - { - ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video); - break; - } + }; + ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", + () => ActualActiveVideoInput.ToString()); + + Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; + Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; + Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange; + Tx.BaseEvent += Tx_BaseEvent; + Tx.OnlineStatusChange += Tx_OnlineStatusChange; + + VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); + + HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); + + HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpStateFeedback = + new IntFeedback( + () => + tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback + ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback + : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); + + HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; + + Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); + + Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue); + + DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue); + + + var combinedFuncs = new VideoStatusFuncsWrapper + { + HdcpActiveFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), + + HdcpStateFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString(); + return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : ""; + }, + + VideoResolutionFeedbackFunc = () => + { + if (ActualActiveVideoInput == eVst.Hdmi1) + return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); + if (ActualActiveVideoInput == eVst.Hdmi2) + return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); + return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : ""; + }, + VideoSyncFeedbackFunc = () => + (ActualActiveVideoInput == eVst.Hdmi1 + && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Hdmi2 + && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) + || (ActualActiveVideoInput == eVst.Vga + && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue) + + }; + + AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, + eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); + + DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, null, this); + HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + + + AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback, + AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, + AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback, + AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, + Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback); + + // Set Ports for CEC + HdmiIn1.Port = Tx.HdmiInputs[1]; + HdmiIn2.Port = Tx.HdmiInputs[2]; + HdmiLoopOut.Port = Tx.HdmiOutput; + DmOut.Port = Tx.DmOutput; + } + + void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) + { + Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); + + switch (args.EventId) + { + case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: + DisplayPortVideoSyncFeedback.FireUpdate(); + break; + } + } + + + + public override bool CustomActivate() + { + // Link up all of these damned events to the various RoutingPorts via a helper handler + Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId); + Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId); + + Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId); + Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId); + + Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId); + Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId); + + // Base does register and sets up comm monitoring. + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = GetDmTxJoinMap(joinStart, joinMapKey); + + if (Hdmi1VideoSyncFeedback != null) + { + Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]); + } + if (Hdmi2VideoSyncFeedback != null) + { + Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]); + } + if (DisplayPortVideoSyncFeedback != null) + { + DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]); + } + + LinkDmTxToApi(this, trilist, joinMap, bridge); + } + + public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type) + { + Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input); + + switch (input) + { + case 0: + { + ExecuteSwitch(eVst.Auto, null, type); + break; + } + case 1: + { + ExecuteSwitch(HdmiIn1.Selector, null, type); + break; + } + case 2: + { + ExecuteSwitch(HdmiIn2.Selector, null, type); + break; + } + case 3: + { + ExecuteSwitch(DisplayPortIn.Selector, null, type); + break; + } + case 4: + { + ExecuteSwitch(eVst.AllDisabled, null, type); + break; + } default: { Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input); break; - } - - } - - - } - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) - { - Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); - if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) - Tx.VideoSource = (eVst)inputSelector; - - // NOTE: It's possible that this particular TX model may not like the AudioSource property being set. - // The SIMPL definition only shows a single analog for AudioVideo Source - if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - //it doesn't - Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); - //Tx.AudioSource = (eAst)inputSelector; - } - - void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) - { - Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); - - switch (args.EventId) - { - case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: - case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: - case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); - HdcpStateFeedback.FireUpdate(); - break; - case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: - if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); - if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); - break; - } + } + + } + + + } + + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType) + { + try + { + Debug.Console(2, this, "Attempting to switch InputSelector {0}", ((eVst)inputSelector).ToString()); + if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video) + Tx.VideoSource = (eVst)inputSelector; + + // NOTE: It's possible that this particular TX model may not like the AudioSource property being set. + // The SIMPL definition only shows a single analog for AudioVideo Source + if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + //it doesn't + Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key); + //Tx.AudioSource = (eAst)inputSelector; + } + catch (Exception e) + { + Debug.Console(2, this, "Exception in ExecuteSwitch: {0}", e); + } + } + + void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) + { + Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString()); + + switch (args.EventId) + { + case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId: + case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId: + case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate(); + HdcpStateFeedback.FireUpdate(); + break; + case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId: + if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate(); + if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); + break; + } } void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) @@ -363,57 +370,57 @@ namespace PepperDash.Essentials.DM OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio)); break; } - } - - /// - /// Relays the input stream change to the appropriate RoutingInputPort. - /// - void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return; - inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); - } - - /// - /// Relays the VideoAttributes change to a RoutingInputPort - /// - void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) - { - //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds - //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", - // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); - switch (eventId) - { - case VideoAttributeEventIds.HdcpActiveFeedbackEventId: - inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HdcpStateFeedbackEventId: - inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: - case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: - inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); - AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); - break; - } - } - - - #region IIROutputPorts Members - public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } - public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } - #endregion - - #region IComPorts Members - public CrestronCollection ComPorts { get { return Tx.ComPorts; } } - public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } - #endregion - } + } + + /// + /// Relays the input stream change to the appropriate RoutingInputPort. + /// + void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return; + inputPort.VideoStatus.VideoSyncFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate(); + } + + /// + /// Relays the VideoAttributes change to a RoutingInputPort + /// + void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId) + { + //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds + //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}", + // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType()); + switch (eventId) + { + case VideoAttributeEventIds.HdcpActiveFeedbackEventId: + inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HdcpStateFeedbackEventId: + inputPort.VideoStatus.HdcpStateFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId: + case VideoAttributeEventIds.VerticalResolutionFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + case VideoAttributeEventIds.FramesPerSecondFeedbackEventId: + inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate(); + AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate(); + break; + } + } + + + #region IIROutputPorts Members + public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } } + public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } } + #endregion + + #region IComPorts Members + public CrestronCollection ComPorts { get { return Tx.ComPorts; } } + public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } } + #endregion + } } \ No newline at end of file From 91abe4c09a78c904193a285692e6170c7922c22a Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 7 Jan 2021 15:23:35 -0700 Subject: [PATCH 12/14] Updates to IR files and Enter command --- IR Drivers/Comcast X1.ir | Bin 3757 -> 3757 bytes IR Drivers/DirecTV H21.ir | Bin 3854 -> 3872 bytes .../SetTopBox/IRSetTopBoxBase.cs | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/IR Drivers/Comcast X1.ir b/IR Drivers/Comcast X1.ir index bff5afff90cd427859f081cb3ae4b0ec91ce3004..4f6c638e63b27f78ee33fd30f295b789b8b7c2b0 100644 GIT binary patch delta 16 XcmZ20yH<8WD664?xsl<nYguCN_1FC Pby>>wSjsjo%Hab54CfFe delta 41 xcmZ1=*C!{!^1(BR Date: Tue, 12 Jan 2021 09:20:15 -0500 Subject: [PATCH 13/14] fixes a bug where the system monitor bridge wasn't updating - fires off all program start/stop/register feedbacks when they are created to set initial state --- .../Monitoring/SystemMonitorController.cs | 1352 +++++++++-------- 1 file changed, 679 insertions(+), 673 deletions(-) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index eadaab12..ec18c995 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -1,106 +1,106 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.Diagnostics; -using PepperDash.Core; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using PepperDash.Essentials.Core.Bridges; - -namespace PepperDash.Essentials.Core.Monitoring -{ - /// - /// Wrapper for the static SystemMonitor class to extend functionality and provide external access - /// to SystemMonitor via APIs - /// - public class SystemMonitorController : EssentialsBridgeableDevice - { - private const long UptimePollTime = 300000; - private CTimer _uptimePollTimer; - - private string _uptime; - private string _lastStart; - - public event EventHandler SystemMonitorPropertiesChanged; - - public Dictionary ProgramStatusFeedbackCollection; - public Dictionary EthernetStatusFeedbackCollection; - - public IntFeedback TimeZoneFeedback { get; protected set; } - public StringFeedback TimeZoneTextFeedback { get; protected set; } - - public StringFeedback IoControllerVersionFeedback { get; protected set; } - public StringFeedback SnmpVersionFeedback { get; protected set; } - public StringFeedback BaCnetAppVersionFeedback { get; protected set; } - public StringFeedback ControllerVersionFeedback { get; protected set; } - - //new feedbacks. Issue #50 - public StringFeedback SerialNumberFeedback { get; protected set; } - public StringFeedback ModelFeedback { get; set; } - - public StringFeedback UptimeFeedback { get; set; } - public StringFeedback LastStartFeedback { get; set; } - - public SystemMonitorController(string key) - : base(key) - { - Debug.Console(2, this, "Adding SystemMonitorController."); - - SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; - - TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); - TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); - - IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); - SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); - BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); - ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); - - SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); - ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); - UptimeFeedback = new StringFeedback(() => _uptime); - LastStartFeedback = new StringFeedback(()=> _lastStart); - - ProgramStatusFeedbackCollection = new Dictionary(); - - foreach (var prog in SystemMonitor.ProgramCollection) - { - var program = new ProgramStatusFeedbacks(prog); - ProgramStatusFeedbackCollection.Add(prog.Number, program); - } - - CreateEthernetStatusFeedbacks(); - UpdateEthernetStatusFeeedbacks(); - - _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); - - SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; - SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; - CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; - CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; - } - - private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) - { - if (programEventType != eProgramStatusEventType.Stopping) return; - - _uptimePollTimer.Stop(); - _uptimePollTimer.Dispose(); - _uptimePollTimer = null; - } - - private void PollUptime(object obj) - { - var consoleResponse = string.Empty; - - CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); - - ParseUptime(consoleResponse); - - UptimeFeedback.FireUpdate(); - LastStartFeedback.FireUpdate(); +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.Diagnostics; +using PepperDash.Core; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using PepperDash.Essentials.Core.Bridges; + +namespace PepperDash.Essentials.Core.Monitoring +{ + /// + /// Wrapper for the static SystemMonitor class to extend functionality and provide external access + /// to SystemMonitor via APIs + /// + public class SystemMonitorController : EssentialsBridgeableDevice + { + private const long UptimePollTime = 300000; + private CTimer _uptimePollTimer; + + private string _uptime; + private string _lastStart; + + public event EventHandler SystemMonitorPropertiesChanged; + + public Dictionary ProgramStatusFeedbackCollection; + public Dictionary EthernetStatusFeedbackCollection; + + public IntFeedback TimeZoneFeedback { get; protected set; } + public StringFeedback TimeZoneTextFeedback { get; protected set; } + + public StringFeedback IoControllerVersionFeedback { get; protected set; } + public StringFeedback SnmpVersionFeedback { get; protected set; } + public StringFeedback BaCnetAppVersionFeedback { get; protected set; } + public StringFeedback ControllerVersionFeedback { get; protected set; } + + //new feedbacks. Issue #50 + public StringFeedback SerialNumberFeedback { get; protected set; } + public StringFeedback ModelFeedback { get; set; } + + public StringFeedback UptimeFeedback { get; set; } + public StringFeedback LastStartFeedback { get; set; } + + public SystemMonitorController(string key) + : base(key) + { + Debug.Console(2, this, "Adding SystemMonitorController."); + + SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; + + TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); + TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); + + IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); + SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); + BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); + ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); + + SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); + ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); + UptimeFeedback = new StringFeedback(() => _uptime); + LastStartFeedback = new StringFeedback(()=> _lastStart); + + ProgramStatusFeedbackCollection = new Dictionary(); + + foreach (var prog in SystemMonitor.ProgramCollection) + { + var program = new ProgramStatusFeedbacks(prog); + ProgramStatusFeedbackCollection.Add(prog.Number, program); + } + + CreateEthernetStatusFeedbacks(); + UpdateEthernetStatusFeeedbacks(); + + _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); + + SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; + SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; + CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; + } + + private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType != eProgramStatusEventType.Stopping) return; + + _uptimePollTimer.Stop(); + _uptimePollTimer.Dispose(); + _uptimePollTimer = null; + } + + private void PollUptime(object obj) + { + var consoleResponse = string.Empty; + + CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); + + ParseUptime(consoleResponse); + + UptimeFeedback.FireUpdate(); + LastStartFeedback.FireUpdate(); } private void ParseUptime(string response) @@ -123,94 +123,94 @@ namespace PepperDash.Essentials.Core.Monitoring _uptime = uptimeRaw.Substring(forIndex + 4); } - private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) - { - if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; - - foreach (var fb in EthernetStatusFeedbackCollection) - { - fb.Value.UpdateEthernetStatus(); - } - } - - private void CreateEthernetStatusFeedbacks() - { - EthernetStatusFeedbackCollection = new Dictionary(); - - Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); - - for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) - { - Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); - var ethernetInterface = new EthernetStatusFeedbacks(i); - EthernetStatusFeedbackCollection.Add(i, ethernetInterface); - } - } - - private void UpdateEthernetStatusFeeedbacks() - { - foreach (var iface in EthernetStatusFeedbackCollection) - { - iface.Value.CurrentIpAddressFeedback.FireUpdate(); - iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); - iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); - iface.Value.StaticIpAddressFeedback.FireUpdate(); - iface.Value.StaticSubnetMaskFeedback.FireUpdate(); - iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); - iface.Value.HostNameFeedback.FireUpdate(); - iface.Value.DnsServerFeedback.FireUpdate(); - iface.Value.DomainFeedback.FireUpdate(); - iface.Value.DhcpStatusFeedback.FireUpdate(); - iface.Value.MacAddressFeedback.FireUpdate(); - } - } - - /// - /// Gets data in separate thread - /// - private void RefreshSystemMonitorData() - { - // this takes a while, launch a new thread - CrestronInvoke.BeginInvoke(UpdateFeedback); - } - - private void UpdateFeedback(object o) - { - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - IoControllerVersionFeedback.FireUpdate(); - SnmpVersionFeedback.FireUpdate(); - BaCnetAppVersionFeedback.FireUpdate(); - ControllerVersionFeedback.FireUpdate(); - SerialNumberFeedback.FireUpdate(); - ModelFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - - private void OnSystemMonitorPropertiesChanged() - { - var handler = SystemMonitorPropertiesChanged; - if (handler != null) - { - handler(this, new EventArgs()); - } - } - - public override bool CustomActivate() - { - RefreshSystemMonitorData(); - - return base.CustomActivate(); - } - - public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) { - var joinMap = new SystemMonitorJoinMap(joinStart); - - var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) + if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; + + foreach (var fb in EthernetStatusFeedbackCollection) + { + fb.Value.UpdateEthernetStatus(); + } + } + + private void CreateEthernetStatusFeedbacks() + { + EthernetStatusFeedbackCollection = new Dictionary(); + + Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); + + for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) + { + Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); + var ethernetInterface = new EthernetStatusFeedbacks(i); + EthernetStatusFeedbackCollection.Add(i, ethernetInterface); + } + } + + private void UpdateEthernetStatusFeeedbacks() + { + foreach (var iface in EthernetStatusFeedbackCollection) + { + iface.Value.CurrentIpAddressFeedback.FireUpdate(); + iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); + iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); + iface.Value.StaticIpAddressFeedback.FireUpdate(); + iface.Value.StaticSubnetMaskFeedback.FireUpdate(); + iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); + iface.Value.HostNameFeedback.FireUpdate(); + iface.Value.DnsServerFeedback.FireUpdate(); + iface.Value.DomainFeedback.FireUpdate(); + iface.Value.DhcpStatusFeedback.FireUpdate(); + iface.Value.MacAddressFeedback.FireUpdate(); + } + } + + /// + /// Gets data in separate thread + /// + private void RefreshSystemMonitorData() + { + // this takes a while, launch a new thread + CrestronInvoke.BeginInvoke(UpdateFeedback); + } + + private void UpdateFeedback(object o) + { + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + IoControllerVersionFeedback.FireUpdate(); + SnmpVersionFeedback.FireUpdate(); + BaCnetAppVersionFeedback.FireUpdate(); + ControllerVersionFeedback.FireUpdate(); + SerialNumberFeedback.FireUpdate(); + ModelFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + private void OnSystemMonitorPropertiesChanged() + { + var handler = SystemMonitorPropertiesChanged; + if (handler != null) + { + handler(this, new EventArgs()); + } + } + + public override bool CustomActivate() + { + RefreshSystemMonitorData(); + + return base.CustomActivate(); + } + + public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) + { + var joinMap = new SystemMonitorJoinMap(joinStart); + + var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) joinMap = JsonConvert.DeserializeObject(joinMapSerialized); if (bridge != null) @@ -220,11 +220,11 @@ namespace PepperDash.Essentials.Core.Monitoring else { Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); - } - - Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - Debug.Console(2, this, "Linking API starting at join: {0}", joinStart); - + } + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(2, this, "Linking API starting at join: {0}", joinStart); + TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone.JoinNumber]); TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName.JoinNumber]); @@ -235,18 +235,18 @@ namespace PepperDash.Essentials.Core.Monitoring SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber.JoinNumber]); ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model.JoinNumber]); UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime.JoinNumber]); - LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]); - - // iterate the program status feedback collection and map all the joins - LinkProgramInfoJoins(this, trilist, joinMap); - - LinkEthernetInfoJoins(this, trilist, joinMap); - } - - private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) + LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]); + + // iterate the program status feedback collection and map all the joins + LinkProgramInfoJoins(this, trilist, joinMap); + + LinkEthernetInfoJoins(this, trilist, joinMap); + } + + private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) { - uint ethernetSlotJoinStart = 0; - foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) + uint ethernetSlotJoinStart = 0; + foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) { fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress.JoinNumber]); fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask.JoinNumber]); @@ -258,494 +258,500 @@ namespace PepperDash.Essentials.Core.Monitoring fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress.JoinNumber]); fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain.JoinNumber]); fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer.JoinNumber]); - fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]); - - ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber; - } - } - - private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, - SystemMonitorJoinMap joinMap) + fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus.JoinNumber]); + + ethernetSlotJoinStart += joinMap.EthernetOffsetJoin.JoinNumber; + } + } + + private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, + SystemMonitorJoinMap joinMap) { - uint programSlotJoinStart = 0; - - foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) - { + uint programSlotJoinStart = 0; + + foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) + { var programNumber = p.Value.Program.Number; - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber, + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart.JoinNumber, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber, + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop.JoinNumber, b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber, - b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister.JoinNumber, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); p.Value.ProgramRegisteredFeedback.LinkInputSig( trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister.JoinNumber]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber, - b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); p.Value.ProgramUnregisteredFeedback.LinkInputSig( trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister.JoinNumber]); - p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]); + p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName.JoinNumber]); p.Value.ProgramCompileTimeFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime.JoinNumber]); p.Value.CrestronDataBaseVersionFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion.JoinNumber]); p.Value.EnvironmentVersionFeedback.LinkInputSig( - trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]); + trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion.JoinNumber]); p.Value.AggregatedProgramInfoFeedback.LinkInputSig( trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo.JoinNumber]); - programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber; - } - } - - //// Sets the time zone - //public void SetTimeZone(int timeZone) - //{ - // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone; - //} - - /// - /// Responds to program change events and triggers the appropriate feedbacks to update - /// - /// - /// - private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) - { - Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); - Debug.Console(2, this, "Event Type: {0}", args.EventType); - - var program = ProgramStatusFeedbackCollection[sender.Number]; - - switch (args.EventType) - { - case eProgramChangeEventType.OperatingState: - program.ProgramStartedFeedback.FireUpdate(); - program.ProgramStoppedFeedback.FireUpdate(); - program.ProgramInfo.OperatingState = args.OperatingState; - if (args.OperatingState == eProgramOperatingState.Start) - program.GetProgramInfo(); - else - { - program.AggregatedProgramInfoFeedback.FireUpdate(); - program.OnProgramInfoChanged(); - } - break; - case eProgramChangeEventType.RegistrationState: - program.ProgramRegisteredFeedback.FireUpdate(); - program.ProgramUnregisteredFeedback.FireUpdate(); - program.ProgramInfo.RegistrationState = args.RegistrationState; - program.GetProgramInfo(); - break; - } - } - - /// - /// Responds to time zone changes and updates the appropriate feedbacks - /// - /// - private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) - { - Debug.Console(2, this, "Time Zone Change Detected."); - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - - public class EthernetStatusFeedbacks - { - public StringFeedback HostNameFeedback { get; protected set; } - public StringFeedback DnsServerFeedback { get; protected set; } - public StringFeedback DomainFeedback { get; protected set; } - public StringFeedback MacAddressFeedback { get; protected set; } - public StringFeedback DhcpStatusFeedback { get; protected set; } - - public StringFeedback CurrentIpAddressFeedback { get; protected set; } - public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } - public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } - - public StringFeedback StaticIpAddressFeedback { get; protected set; } - public StringFeedback StaticSubnetMaskFeedback { get; protected set; } - public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } - - public EthernetStatusFeedbacks(short adapterIndex) - { - Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); - Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); - Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); - HostNameFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); - - CurrentIpAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); - CurrentDefaultGatewayFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); - CurrentSubnetMaskFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); - StaticIpAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); - StaticDefaultGatewayFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); - StaticSubnetMaskFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); - DomainFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); - DnsServerFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); - MacAddressFeedback = - new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); - - DhcpStatusFeedback = new StringFeedback( - () => - CrestronEthernetHelper.GetEthernetParameter( - CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); - } - - public void UpdateEthernetStatus() - { - HostNameFeedback.FireUpdate(); - CurrentIpAddressFeedback.FireUpdate(); - CurrentSubnetMaskFeedback.FireUpdate(); - CurrentDefaultGatewayFeedback.FireUpdate(); - StaticIpAddressFeedback.FireUpdate(); - StaticSubnetMaskFeedback.FireUpdate(); - StaticDefaultGatewayFeedback.FireUpdate(); - DomainFeedback.FireUpdate(); - DnsServerFeedback.FireUpdate(); - MacAddressFeedback.FireUpdate(); - DhcpStatusFeedback.FireUpdate(); - } - } - - - public class ProgramStatusFeedbacks - { - public event EventHandler ProgramInfoChanged; - - public Program Program; - - public ProgramInfo ProgramInfo { get; set; } - - public BoolFeedback ProgramStartedFeedback; - public BoolFeedback ProgramStoppedFeedback; - public BoolFeedback ProgramRegisteredFeedback; - public BoolFeedback ProgramUnregisteredFeedback; - - public StringFeedback ProgramNameFeedback; - public StringFeedback ProgramCompileTimeFeedback; - public StringFeedback CrestronDataBaseVersionFeedback; - // SIMPL windows version - public StringFeedback EnvironmentVersionFeedback; - public StringFeedback AggregatedProgramInfoFeedback; - - public ProgramStatusFeedbacks(Program program) - { - ProgramInfo = new ProgramInfo(program.Number); - - Program = program; - - ProgramInfo.OperatingState = Program.OperatingState; - ProgramInfo.RegistrationState = Program.RegistrationState; - - ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); - ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); - ProgramRegisteredFeedback = - new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); - ProgramUnregisteredFeedback = - new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); - - ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); - ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); - CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); - EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); - - AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); - - GetProgramInfo(); - } - - /// - /// Retrieves information about a running program - /// - public void GetProgramInfo() - { - CrestronInvoke.BeginInvoke(GetProgramInfo); - } - - private void GetProgramInfo(object o) - { - Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); - - string response = null; - - if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) - { - Debug.Console(2, "Program {0} not registered. Setting default values for program information.", - Program.Number); - - ProgramInfo = new ProgramInfo(Program.Number) - { - OperatingState = Program.OperatingState, - RegistrationState = Program.RegistrationState - }; - - return; - } - - var success = CrestronConsole.SendControlSystemCommand( - string.Format("progcomments:{0}", Program.Number), ref response); - - if (!success) - { - Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); - UpdateFeedbacks(); - return; - } - - if (response.ToLower().Contains("bad or incomplete")) - { - Debug.Console(2, - "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", - Program.Number); - - // Assume no valid program info. Constructing a new object will wipe all properties - ProgramInfo = new ProgramInfo(Program.Number) - { - OperatingState = Program.OperatingState, - RegistrationState = Program.RegistrationState - }; - - UpdateFeedbacks(); - - return; - } - - - // Shared properteis - ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); - ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); - ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); - ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); - - - if (ProgramInfo.ProgramFile.Contains(".dll")) - { - // SSP Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); - ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); - ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); - ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", - "\n"); - ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); - } - else if (ProgramInfo.ProgramFile.Contains(".smw")) - { - // SIMPL Windows Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); - ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); - ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); - ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); - ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); - } - Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); - - UpdateFeedbacks(); - } - - private void UpdateFeedbacks() - { - ProgramNameFeedback.FireUpdate(); - ProgramCompileTimeFeedback.FireUpdate(); - CrestronDataBaseVersionFeedback.FireUpdate(); - EnvironmentVersionFeedback.FireUpdate(); - - AggregatedProgramInfoFeedback.FireUpdate(); - - OnProgramInfoChanged(); - } - - public void OnProgramInfoChanged() - { - //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number); - var handler = ProgramInfoChanged; - if (handler != null) - { - handler(this, new ProgramInfoEventArgs(ProgramInfo)); - } - } - - private string ParseConsoleData(string data, string line, string startString, string endString) - { - var outputData = ""; - - if (data.Length <= 0) return outputData; - - try - { - //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); - var linePosition = data.IndexOf(line, StringComparison.Ordinal); - var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + - startString.Length; - var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); - outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); - //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); - } - catch (Exception e) - { - Debug.Console(1, "Error Parsing Console Data:\r{0}", e); - } - - return outputData; - } - } - } - - /// - /// Class for serializing program slot information - /// - public class ProgramInfo - { - // Shared properties - - [JsonProperty("programNumber")] - public uint ProgramNumber { get; private set; } - - [JsonConverter(typeof (StringEnumConverter))] - [JsonProperty("operatingState")] - public eProgramOperatingState OperatingState { get; set; } - - [JsonConverter(typeof (StringEnumConverter))] - [JsonProperty("registrationState")] - public eProgramRegistrationState RegistrationState { get; set; } - - [JsonProperty("programFile")] - public string ProgramFile { get; set; } - - [JsonProperty("friendlyName")] - public string FriendlyName { get; set; } - - [JsonProperty("compilerRevision")] - public string CompilerRevision { get; set; } - - [JsonProperty("compileTime")] - public string CompileTime { get; set; } - - [JsonProperty("include4Dat")] - public string Include4Dat { get; set; } - - // SIMPL Windows properties - [JsonProperty("systemName")] - public string SystemName { get; set; } - - [JsonProperty("crestronDb")] - public string CrestronDb { get; set; } - - [JsonProperty("environment")] - public string Environment { get; set; } - - [JsonProperty("programmer")] - public string Programmer { get; set; } - - - // SSP Properties - [JsonProperty("applicationName")] - public string ApplicationName { get; set; } - - [JsonProperty("programTool")] - public string ProgramTool { get; set; } - - [JsonProperty("minFirmwareVersion")] - public string MinFirmwareVersion { get; set; } - - [JsonProperty("plugInVersion")] - public string PlugInVersion { get; set; } - - public ProgramInfo(uint number) - { - ProgramNumber = number; - - ProgramFile = ""; - FriendlyName = ""; - CompilerRevision = ""; - CompileTime = ""; - Include4Dat = ""; - - SystemName = ""; - CrestronDb = ""; - Environment = ""; - Programmer = ""; - - ApplicationName = ""; - ProgramTool = ""; - MinFirmwareVersion = ""; - PlugInVersion = ""; - } - } - - public class ProgramInfoEventArgs : EventArgs - { - public ProgramInfo ProgramInfo; - - public ProgramInfoEventArgs(ProgramInfo progInfo) - { - ProgramInfo = progInfo; - } - } + programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinNumber; + } + } + + //// Sets the time zone + //public void SetTimeZone(int timeZone) + //{ + // SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone; + //} + + /// + /// Responds to program change events and triggers the appropriate feedbacks to update + /// + /// + /// + private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) + { + Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); + Debug.Console(2, this, "Event Type: {0}", args.EventType); + + var program = ProgramStatusFeedbackCollection[sender.Number]; + + switch (args.EventType) + { + case eProgramChangeEventType.OperatingState: + program.ProgramStartedFeedback.FireUpdate(); + program.ProgramStoppedFeedback.FireUpdate(); + program.ProgramInfo.OperatingState = args.OperatingState; + if (args.OperatingState == eProgramOperatingState.Start) + program.GetProgramInfo(); + else + { + program.AggregatedProgramInfoFeedback.FireUpdate(); + program.OnProgramInfoChanged(); + } + break; + case eProgramChangeEventType.RegistrationState: + program.ProgramRegisteredFeedback.FireUpdate(); + program.ProgramUnregisteredFeedback.FireUpdate(); + program.ProgramInfo.RegistrationState = args.RegistrationState; + program.GetProgramInfo(); + break; + } + } + + /// + /// Responds to time zone changes and updates the appropriate feedbacks + /// + /// + private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) + { + Debug.Console(2, this, "Time Zone Change Detected."); + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + public class EthernetStatusFeedbacks + { + public StringFeedback HostNameFeedback { get; protected set; } + public StringFeedback DnsServerFeedback { get; protected set; } + public StringFeedback DomainFeedback { get; protected set; } + public StringFeedback MacAddressFeedback { get; protected set; } + public StringFeedback DhcpStatusFeedback { get; protected set; } + + public StringFeedback CurrentIpAddressFeedback { get; protected set; } + public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } + public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } + + public StringFeedback StaticIpAddressFeedback { get; protected set; } + public StringFeedback StaticSubnetMaskFeedback { get; protected set; } + public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } + + public EthernetStatusFeedbacks(short adapterIndex) + { + Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); + Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); + HostNameFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); + + CurrentIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + CurrentDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + CurrentSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + StaticIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + StaticDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + StaticSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + DomainFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); + DnsServerFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); + MacAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); + + DhcpStatusFeedback = new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); + } + + public void UpdateEthernetStatus() + { + HostNameFeedback.FireUpdate(); + CurrentIpAddressFeedback.FireUpdate(); + CurrentSubnetMaskFeedback.FireUpdate(); + CurrentDefaultGatewayFeedback.FireUpdate(); + StaticIpAddressFeedback.FireUpdate(); + StaticSubnetMaskFeedback.FireUpdate(); + StaticDefaultGatewayFeedback.FireUpdate(); + DomainFeedback.FireUpdate(); + DnsServerFeedback.FireUpdate(); + MacAddressFeedback.FireUpdate(); + DhcpStatusFeedback.FireUpdate(); + } + } + + + public class ProgramStatusFeedbacks + { + public event EventHandler ProgramInfoChanged; + + public Program Program; + + public ProgramInfo ProgramInfo { get; set; } + + public BoolFeedback ProgramStartedFeedback; + public BoolFeedback ProgramStoppedFeedback; + public BoolFeedback ProgramRegisteredFeedback; + public BoolFeedback ProgramUnregisteredFeedback; + + public StringFeedback ProgramNameFeedback; + public StringFeedback ProgramCompileTimeFeedback; + public StringFeedback CrestronDataBaseVersionFeedback; + // SIMPL windows version + public StringFeedback EnvironmentVersionFeedback; + public StringFeedback AggregatedProgramInfoFeedback; + + public ProgramStatusFeedbacks(Program program) + { + ProgramInfo = new ProgramInfo(program.Number); + + Program = program; + + ProgramInfo.OperatingState = Program.OperatingState; + ProgramInfo.RegistrationState = Program.RegistrationState; + + ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); + ProgramStartedFeedback.FireUpdate(); + + ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); + ProgramStoppedFeedback.FireUpdate(); + + ProgramRegisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); + ProgramRegisteredFeedback.FireUpdate(); + + ProgramUnregisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); + ProgramUnregisteredFeedback.FireUpdate(); + + ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); + CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); + EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); + AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); + + GetProgramInfo(); + } + + /// + /// Retrieves information about a running program + /// + public void GetProgramInfo() + { + CrestronInvoke.BeginInvoke(GetProgramInfo); + } + + private void GetProgramInfo(object o) + { + Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + + string response = null; + + if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) + { + Debug.Console(2, "Program {0} not registered. Setting default values for program information.", + Program.Number); + + ProgramInfo = new ProgramInfo(Program.Number) + { + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; + + return; + } + + var success = CrestronConsole.SendControlSystemCommand( + string.Format("progcomments:{0}", Program.Number), ref response); + + if (!success) + { + Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); + UpdateFeedbacks(); + return; + } + + if (response.ToLower().Contains("bad or incomplete")) + { + Debug.Console(2, + "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", + Program.Number); + + // Assume no valid program info. Constructing a new object will wipe all properties + ProgramInfo = new ProgramInfo(Program.Number) + { + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; + + UpdateFeedbacks(); + + return; + } + + + // Shared properteis + ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); + ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); + ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); + ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + + + if (ProgramInfo.ProgramFile.Contains(".dll")) + { + // SSP Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); + ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); + ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); + ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", + "\n"); + ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); + } + else if (ProgramInfo.ProgramFile.Contains(".smw")) + { + // SIMPL Windows Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); + ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); + ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); + ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); + ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + } + Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); + + UpdateFeedbacks(); + } + + private void UpdateFeedbacks() + { + ProgramNameFeedback.FireUpdate(); + ProgramCompileTimeFeedback.FireUpdate(); + CrestronDataBaseVersionFeedback.FireUpdate(); + EnvironmentVersionFeedback.FireUpdate(); + + AggregatedProgramInfoFeedback.FireUpdate(); + + OnProgramInfoChanged(); + } + + public void OnProgramInfoChanged() + { + //Debug.Console(1, "Firing ProgramInfoChanged for slot: {0}", Program.Number); + var handler = ProgramInfoChanged; + if (handler != null) + { + handler(this, new ProgramInfoEventArgs(ProgramInfo)); + } + } + + private string ParseConsoleData(string data, string line, string startString, string endString) + { + var outputData = ""; + + if (data.Length <= 0) return outputData; + + try + { + //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); + var linePosition = data.IndexOf(line, StringComparison.Ordinal); + var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + + startString.Length; + var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); + outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); + //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); + } + catch (Exception e) + { + Debug.Console(1, "Error Parsing Console Data:\r{0}", e); + } + + return outputData; + } + } + } + + /// + /// Class for serializing program slot information + /// + public class ProgramInfo + { + // Shared properties + + [JsonProperty("programNumber")] + public uint ProgramNumber { get; private set; } + + [JsonConverter(typeof (StringEnumConverter))] + [JsonProperty("operatingState")] + public eProgramOperatingState OperatingState { get; set; } + + [JsonConverter(typeof (StringEnumConverter))] + [JsonProperty("registrationState")] + public eProgramRegistrationState RegistrationState { get; set; } + + [JsonProperty("programFile")] + public string ProgramFile { get; set; } + + [JsonProperty("friendlyName")] + public string FriendlyName { get; set; } + + [JsonProperty("compilerRevision")] + public string CompilerRevision { get; set; } + + [JsonProperty("compileTime")] + public string CompileTime { get; set; } + + [JsonProperty("include4Dat")] + public string Include4Dat { get; set; } + + // SIMPL Windows properties + [JsonProperty("systemName")] + public string SystemName { get; set; } + + [JsonProperty("crestronDb")] + public string CrestronDb { get; set; } + + [JsonProperty("environment")] + public string Environment { get; set; } + + [JsonProperty("programmer")] + public string Programmer { get; set; } + + + // SSP Properties + [JsonProperty("applicationName")] + public string ApplicationName { get; set; } + + [JsonProperty("programTool")] + public string ProgramTool { get; set; } + + [JsonProperty("minFirmwareVersion")] + public string MinFirmwareVersion { get; set; } + + [JsonProperty("plugInVersion")] + public string PlugInVersion { get; set; } + + public ProgramInfo(uint number) + { + ProgramNumber = number; + + ProgramFile = ""; + FriendlyName = ""; + CompilerRevision = ""; + CompileTime = ""; + Include4Dat = ""; + + SystemName = ""; + CrestronDb = ""; + Environment = ""; + Programmer = ""; + + ApplicationName = ""; + ProgramTool = ""; + MinFirmwareVersion = ""; + PlugInVersion = ""; + } + } + + public class ProgramInfoEventArgs : EventArgs + { + public ProgramInfo ProgramInfo; + + public ProgramInfoEventArgs(ProgramInfo progInfo) + { + ProgramInfo = progInfo; + } + } } \ No newline at end of file From 7945bce854c6643c9547ccd42580034887a767d5 Mon Sep 17 00:00:00 2001 From: jkdevito Date: Mon, 18 Jan 2021 15:37:39 -0600 Subject: [PATCH 14/14] Upadted VideoCodecBase LinkVideoCodecCallControlsToApi IncomingCall bridge action to reference "args.CallItem.Status == eCodecCallStatus.Ringing" (previously referencing "args.CallItem.Status != eCodecCallStatus.Disconnected") --- .../VideoCodec/VideoCodecBase.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index 6b6d5891..8765b0e1 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -74,10 +74,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { get { - return new List - { - PrivacyModeIsOnFeedback, - SharingSourceFeedback + return new List + { + PrivacyModeIsOnFeedback, + SharingSourceFeedback }; } } @@ -677,19 +677,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec var meetingIndex = 0; var tokenArray = new XSigToken[maxMeetings * offset]; - /* - * Digitals - * IsJoinable - 1 - * IsDialable - 2 - * - * Serials - * Organizer - 1 - * Title - 2 - * Start Date - 3 - * Start Time - 4 - * End Date - 5 - * End Time - 6 - * Id - 7 + /* + * Digitals + * IsJoinable - 1 + * IsDialable - 2 + * + * Serials + * Organizer - 1 + * Title - 2 + * Start Date - 3 + * Start Time - 4 + * End Date - 5 + * End Time - 6 + * Id - 7 */ @@ -848,7 +848,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction); Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming); - trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status != eCodecCallStatus.Disconnected); + trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing); if (args.CallItem.Direction == eCodecCallDirection.Incoming) {