diff --git a/src/CiscoRoomOsCodec.cs b/src/CiscoRoomOsCodec.cs index ca893ae..dd2db29 100644 --- a/src/CiscoRoomOsCodec.cs +++ b/src/CiscoRoomOsCodec.cs @@ -2,13 +2,11 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Reflection.Emit; using System.Text; using System.Text.RegularExpressions; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.Diagnostics; using epi_videoCodec_ciscoExtended.Interfaces; using epi_videoCodec_ciscoExtended.UserInterface.UserInterfaceExtensions; using Newtonsoft.Json; @@ -22,11 +20,9 @@ using PepperDash.Essentials.Core.DeviceInfo; using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Queues; -using PepperDash.Essentials.Core.Routing; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using Serilog.Events; using Feedback = PepperDash.Essentials.Core.Feedback; @@ -107,7 +103,7 @@ public class CiscoCodec ICiscoCodecCameraConfig, ISpeakerTrack, IPresenterTrack - { + { public event EventHandler AvailableLayoutsChanged; public event EventHandler CurrentLayoutChanged; private event EventHandler MinuteChanged; @@ -694,8 +690,8 @@ protected Func PresenterTrackStatusPersistentFeedbackFunc //public RoutingInputPort CodecOsdIn { get; private set; } - public RoutingInputPort HdmiIn1 { get; private set; } - public RoutingInputPort HdmiIn2 { get; private set; } + public RoutingInputPort HdmiIn1 { get; private set; } + public RoutingInputPort HdmiIn2 { get; private set; } public RoutingInputPort HdmiIn3 { get; private set; } public RoutingInputPort HdmiIn4 { get; private set; } public RoutingInputPort HdmiIn5 { get; private set; } @@ -728,12 +724,12 @@ public CiscoCodec(DeviceConfig config, IBasicCommunication comm) - CrestronEnvironment.ProgramStatusEventHandler += a => - { - if (a != eProgramStatusEventType.Stopping) - return; - EndGracefully(); - }; + CrestronEnvironment.ProgramStatusEventHandler += a => +{ + if (a != eProgramStatusEventType.Stopping) + return; + EndGracefully(); +}; CrestronEnvironment.SystemEventHandler += a => { @@ -911,6 +907,7 @@ public CiscoCodec(DeviceConfig config, IBasicCommunication comm) { const string pollString = "xstatus systemunit\r" + + "xstatus cameras\r" + "xstatus sip/registration\r" + "xStatus Audio Volume\r"; @@ -976,20 +973,20 @@ public CiscoCodec(DeviceConfig config, IBasicCommunication comm) // new Action(StopSharing), // this //); - HdmiIn1 = new RoutingInputPort( - RoutingPortNames.HdmiIn1, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, - new Action(SelectPresentationSource1), - this - ); - HdmiIn2 = new RoutingInputPort( - RoutingPortNames.HdmiIn2, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, - new Action(SelectPresentationSource2), - this - ); + HdmiIn1 = new RoutingInputPort( + RoutingPortNames.HdmiIn1, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, + new Action(SelectPresentationSource1), + this +); + HdmiIn2 = new RoutingInputPort( + RoutingPortNames.HdmiIn2, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, + new Action(SelectPresentationSource2), + this +); HdmiIn3 = new RoutingInputPort( RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video, @@ -997,20 +994,20 @@ public CiscoCodec(DeviceConfig config, IBasicCommunication comm) new Action(() => SelectPresentationSource(3)), this ); - HdmiIn4 = new RoutingInputPort( - RoutingPortNames.HdmiIn4, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, - new Action(() => SelectPresentationSource(4)), - this + HdmiIn4 = new RoutingInputPort( + RoutingPortNames.HdmiIn4, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, + new Action(() => SelectPresentationSource(4)), + this +); + HdmiIn5 = new RoutingInputPort( + RoutingPortNames.HdmiIn5, + eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, + new Action(() => SelectPresentationSource(5)), + this ); - HdmiIn5 = new RoutingInputPort( - RoutingPortNames.HdmiIn5, - eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, - new Action(() => SelectPresentationSource(5)), - this - ); SdiInput = new RoutingInputPort( RoutingPortNames.SdiIn, eRoutingSignalType.Video, @@ -1548,7 +1545,7 @@ public void InitializeBranding(string roomKey) DeviceManager.GetDeviceForKey(mcBridgeKey) as IMobileControlRoomMessenger; #else - var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey) as IMobileControlRoomBridge; + var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey) as IMobileControlRoomBridge; #endif if (!String.IsNullOrEmpty(_brandingUrl)) @@ -1616,7 +1613,7 @@ private void DisplayUserCode(string code) #if SERIES4 private void SendMcBrandingUrl(IMobileControlRoomMessenger roomMessenger) #else - private void SendMcBrandingUrl(IMobileControlRoomBridge roomMessenger) + private void SendMcBrandingUrl(IMobileControlRoomBridge roomMessenger) #endif { if (roomMessenger == null) @@ -1699,12 +1696,12 @@ public override bool CustomActivate() CodecSchedule.MeetingsListHasChanged += (sender, args) => { }; CodecSchedule.MeetingEventChange += (sender, args) => { }; - var mc = DeviceManager.AllDevices.OfType().FirstOrDefault(); + var mc = DeviceManager.AllDevices.OfType().FirstOrDefault(); - if (mc == null) - { - return base.CustomActivate(); - } + if (mc == null) + { + return base.CustomActivate(); + } var speakerTrackMessenger = new ISpeakerTrackMessenger($"speakerTrack-{Key}", $"/device/{Key}", this); mc.AddDeviceMessenger(speakerTrackMessenger); @@ -1712,7 +1709,7 @@ public override bool CustomActivate() var presenterTrackMessenger = new IPresenterTrackMessenger($"presenterTrack-{Key}", $"/device/{Key}", this); mc.AddDeviceMessenger(presenterTrackMessenger); - return base.CustomActivate(); + return base.CustomActivate(); } private void CiscoCodec_CameraTrackingCapabilitiesChanged( @@ -1762,9 +1759,9 @@ public override void Initialize() //RegisterSystemUnitEvents(); //RegisterSipEvents(); RegisterNetworkEvents(); - /*RegisterVideoEvents();*/ - //RegisterConferenceEvents(); - RegisterRoomPresetEvents(); + /*RegisterVideoEvents();*/ + //RegisterConferenceEvents(); + RegisterRoomPresetEvents(); RegisterH323Configuration(); RegisterAutoAnswer(); RegisterDisconnectEvents(); @@ -1775,22 +1772,22 @@ public override void Initialize() { socket.ConnectionChange += socket_ConnectionChange; - var ssh = socket as GenericSshClient; + var ssh = socket as GenericSshClient; - if (ssh != null) - { - DeviceInfo.IpAddress = ssh.Hostname; - DeviceInfo.HostName = ssh.Hostname; - } + if (ssh != null) + { + DeviceInfo.IpAddress = ssh.Hostname; + DeviceInfo.HostName = ssh.Hostname; + } - var tcp = socket as GenericTcpIpClient; + var tcp = socket as GenericTcpIpClient; - if (tcp != null) - { - DeviceInfo.IpAddress = tcp.Hostname; - DeviceInfo.HostName = tcp.Hostname; - } - } + if (tcp != null) + { + DeviceInfo.IpAddress = tcp.Hostname; + DeviceInfo.HostName = tcp.Hostname; + } + } if (Communication == null) throw new NullReferenceException("Coms"); @@ -1833,10 +1830,10 @@ private string BuildFeedbackRegistrationExpression() + Delimiter + prefix + "/Status/Conference/DoNotDisturb" - + Delimiter - + prefix - + "/Status/Cameras/Camera" - + Delimiter + + Delimiter + + prefix + + "/Status/Cameras/Camera" + + Delimiter + prefix + "/Status/Cameras/SpeakerTrack" + Delimiter @@ -1887,10 +1884,10 @@ private string BuildFeedbackRegistrationExpression() + Delimiter + prefix + "/Event/CameraPresetListUpdated" - + Delimiter - + prefix - + "/Event/Peripherals" - + Delimiter + + Delimiter + + prefix + + "/Event/Peripherals" + + Delimiter + prefix + "/Event/Conference/Call/AuthenticationResponse" + Delimiter @@ -1948,23 +1945,12 @@ private void SyncState_InitialSyncCompleted(object sender, EventArgs e) Debug.Console( 0, this, - "Codec reports {0} cameras", + "Codec reports {0} camera(s)", CodecStatus.Status.Cameras.CameraList.Count ); foreach (var camera in CodecStatus.Status.Cameras.CameraList) { - Debug.Console( - 0, - this, - @"Camera CiscoCallId: {0} -Name: {1} -ConnectorID: {2}", - camera.CameraId, - camera.Manufacturer.Value, - camera.Model.Value - ); - var id = Convert.ToUInt16(camera.CameraId); var newCamera = cameraInfo.FirstOrDefault(o => o.CameraNumber == id); if (newCamera != null) @@ -1985,7 +1971,7 @@ private void SyncState_InitialSyncCompleted(object sender, EventArgs e) Debug.Console( 0, this, - "Successfully got cameraInfo for {0} cameras from codec.", + "Got cameraInfo for {0} cameras from codec.", cameraInfo.Count ); @@ -2153,9 +2139,10 @@ private void ProcessResponse(string response) if (!SyncState.InitialStatusMessageWasReceived) { - SendText("xStatus"); + SendText("xStatus Cameras"); SendText("xStatus SIP"); SendText("xStatus Call"); + SendText("xStatus"); } } else if (data.Contains("xfeedback register /event/calldisconnect")) @@ -2685,8 +2672,8 @@ private void RegisterNetworkEvents() CodecStatus.Status.NetworkCount.ValueChangedAction += () => { Debug.Console(2, this, "CodecStatus.Status.NetworkCount.ValueChangedAction"); - Debug.Console(2, this, "CodecStatus.Status.NetworkCount.Value = {0}", CodecStatus.Status.NetworkCount.Value); - if (CodecStatus.Status.NetworkCount.Value <= 0) + Debug.Console(2, this, "CodecStatus.Status.NetworkCount.Value = {0}", CodecStatus.Status.NetworkCount.Value); + if (CodecStatus.Status.NetworkCount.Value <= 0) return; ParseNetworkList(CodecStatus.Status.Networks); }; @@ -3987,7 +3974,7 @@ private void ParseStatusObject(JToken statusToken) var selfviewToken = statusToken.SelectToken("Video.Selfview.Mode"); var mediaChannelsToken = statusToken.SelectToken("MediaChannels.Call"); var systemUnitToken = statusToken.SelectToken("SystemUnit"); - var cameraToken = statusToken.SelectToken("Cameras"); + var cameraToken = statusToken.SelectToken("Cameras.Camera"); var speakerTrackToken = statusToken.SelectToken("Cameras.SpeakerTrack"); var presenterTrackToken = statusToken.SelectToken("Cameras.PresenterTrack"); var networkToken = statusToken.SelectToken("Network"); @@ -4005,9 +3992,10 @@ private void ParseStatusObject(JToken statusToken) Debug.Console(2, this, "{0}", errorToken.ToString()); return; } - JsonConvert.PopulateObject(statusToken.ToString(), status); - if(status?.UserInterface?.WebViews != null && status.UserInterface.WebViews.Count > 0) + JsonConvert.PopulateObject(serializedToken, status); + + if (status?.UserInterface?.WebViews != null && status.UserInterface.WebViews.Count > 0) { CiscoCodecUiExtensionsHandler?.ParseStatus(status.UserInterface.WebViews); } @@ -4050,8 +4038,73 @@ private void ParseStatusObject(JToken statusToken) } if (cameraToken != null) { - //ParseCameraToken(cameraToken); - PopulateObjectWithToken(statusToken, "Cameras", CodecStatus.Status.Cameras); + var listWasUpdated = false; + var cameraInfo = cameraToken.ToObject>(); + + foreach (var cam in cameraInfo) + { + var modernId = cam.SelectToken("CameraId")?.ToString(); + var legacyId = cam.SelectToken("id")?.ToString(); + var camId = string.IsNullOrEmpty(modernId) ? legacyId : modernId; + + if (string.IsNullOrEmpty(camId)) + { + Debug.Console(1, + this, + "CameraId and id are null or empty. Skipping camera."); + continue; + } + + Debug.Console(1, + this, + "Parsing camera id:{0}", + camId); + + var existingCam = + CodecStatus.Status.Cameras.CameraList.FirstOrDefault(c => c.CameraId == camId); + + if (existingCam == null) + { + var newCam = cam.ToObject(); + CodecStatus.Status.Cameras.CameraList.Add(newCam); + } + else + { + JsonConvert.PopulateObject( + cam.ToString(), + existingCam, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + MissingMemberHandling = MissingMemberHandling.Ignore, + }); + } + + listWasUpdated = true; + } + + Debug.Console(1, + this, + "Number of cameras:{0}", + CodecStatus.Status.Cameras.CameraList.Count); + + if (listWasUpdated) + { + Debug.Console(1, + this, + "Connected Cameras:{0}", + CodecStatus.Status.Cameras.CameraList.Count(c => + c.Connected?.Value.ToLower() == "true")); + + foreach (var cam in CodecStatus.Status.Cameras.CameraList) + { + Debug.Console(1, + this, + "Camera:{0} connected:{1} serial:{2}", + cam.CameraId, cam.Connected?.Value ?? "false", + cam.SerialNumber?.Value ?? "--empty---"); + } + } } if (speakerTrackToken != null) { @@ -4101,12 +4154,13 @@ private void ParseStatusObject(JToken statusToken) { ParseRoomPresetList(status.RoomPresets); } - else - { - JsonConvert.PopulateObject(serializedToken, CodecStatus.Status); - } + + // we don't want to do this... this will expand lists infinitely + //JsonConvert.PopulateObject(serializedToken, CodecStatus.Status); + if (SyncState.InitialStatusMessageWasReceived) return; + SyncState.InitialStatusMessageReceived(); if (!SyncState.InitialConfigurationMessageWasReceived) @@ -4624,12 +4678,6 @@ private void DeserializeResponse(string response) var resultId = ParseResultId(obj); - Debug.Console( - 2, - this, - "Deserialize Response - Parsed ResultID = {0}", - resultId - ); ParseStatusObject(JTokenValidInObject(obj, "Status")); ParseConfigurationObject(JTokenValidInObject(obj, "Configuration")); ParseEventObject(JTokenValidInObject(obj, "Event")); @@ -5835,7 +5883,7 @@ public void SelectPresentationSource2() SelectPresentationSource(3); } - + public override void StartSharing() { if (_desiredPresentationSource > 0) @@ -6910,8 +6958,11 @@ private void SetUpCameras(List cameraInfo) // Add the internal camera Cameras = new List(); - var camCount = CodecStatus.Status.Cameras.CameraList.Count; - Debug.Console(0, this, "THERE ARE {0} CAMERAS", camCount); + var camCount = cameraInfo.Count; + Debug.Console(0, + this, + "Setting up cameras from info:{0}", + JsonConvert.SerializeObject(cameraInfo, Formatting.Indented)); // Deal with the case of 1 or no reported cameras if (camCount <= 1) @@ -6933,14 +6984,18 @@ private void SetUpCameras(List cameraInfo) } Cameras.Add(internalCamera); + Debug.Console(0, + this, + "Adding camera to camera list:{0}", + internalCamera.Key); - var existingInternalCamera = DeviceManager.GetDeviceForKey(internalCamera.Key); + var existingInternalCamera = DeviceManager.GetDeviceForKey(internalCamera.Key); - if (existingInternalCamera == null) - { - DeviceManager.AddDevice(internalCamera); - } - } + if (existingInternalCamera == null) + { + DeviceManager.AddDevice(internalCamera); + } + } else { if (CodecStatus.Status.Cameras.CameraList == null) @@ -6969,7 +7024,7 @@ private void SetUpCameras(List cameraInfo) var existingCamera = existingCameras.FirstOrDefault(c => c.SerialNumber == item.SerialNumber.Value); - if(existingCamera != null) + if (existingCamera != null) { existingCamera.SetParentCodec(this); if (uint.TryParse(item.CameraId, out var id)) @@ -6977,39 +7032,44 @@ private void SetUpCameras(List cameraInfo) existingCamera.SetCameraId(Convert.ToUInt16(id)); } Cameras.Add(existingCamera); - continue; - } + continue; + } - var key = string.Format("{0}-camera{1}", Key, camId); - var camera = new CiscoCamera(key, name, this, camId, sourceId); + var key = string.Format("{0}-camera{1}", Key, camId); + var camera = new CiscoCamera(key, name, this, camId, sourceId); - if (cam.Capabilities != null) - { - camera.SetCapabilites(cam.Capabilities.Options.Value); - } + if (cam.Capabilities != null) + { + camera.SetCapabilites(cam.Capabilities.Options.Value); + } - Debug.Console(0, this, "Adding Camera {0}", camera.CameraId); + Debug.Console(0, this, "Adding Camera {0}", camera.CameraId); Cameras.Add(camera); - if (existingCamera == null) - { - DeviceManager.AddDevice(camera); - } - } + if (existingCamera == null) + { + DeviceManager.AddDevice(camera); + } + } } // Add the far end camera var farEndCamera = new CiscoFarEndCamera(Key + "-cameraFar", "Far End", this); + Debug.Console(0, + this, + "Adding camera to camera list:{0}", + farEndCamera.Key); + Cameras.Add(farEndCamera); - var existingFarEndCamera = DeviceManager.GetDeviceForKey(farEndCamera.Key); + var existingFarEndCamera = DeviceManager.GetDeviceForKey(farEndCamera.Key); - if (existingFarEndCamera == null) - { - DeviceManager.AddDevice(farEndCamera); - } + if (existingFarEndCamera == null) + { + DeviceManager.AddDevice(farEndCamera); + } - SelectedCameraFeedback = new StringFeedback(() => SelectedCamera.Key); + SelectedCameraFeedback = new StringFeedback(() => SelectedCamera.Key); ControllingFarEndCameraFeedback = new BoolFeedback( () => SelectedCamera is IAmFarEndCamera @@ -7126,24 +7186,33 @@ private void SetUpCamerasFromConfig(List cameraInfo) public void SetCameraAssignedSerialNumber(uint cameraId, string serialNumber) { - EnqueueCommand($"xConfiguration Cameras Camera[{cameraId}] AssignedSerialNumber: {serialNumber}"); - } + Debug.Console(1, this, "Setting the serial number of camera {0} to {1}", cameraId, serialNumber); + EnqueueCommand($"xConfiguration Cameras Camera[{cameraId}] AssignedSerialNumber: {serialNumber}"); + } - public void SetCameraName(uint videoConnectorId, string name) + public void SetCameraName(uint videoConnectorId, string name) { - EnqueueCommand($"xConfiguration Video Input Connector[{videoConnectorId}] Name: {name}"); - } + Debug.Console(1, this, "Setting the name of video connector {0} to {1}", videoConnectorId, name); + EnqueueCommand($"xConfiguration Video Input Connector[{videoConnectorId}] Name: \"{name}\""); + } - public void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType) + public void SetInputCameraId(uint videoConnectorId, uint inputCameraId) { - EnqueueCommand($"xConfiguration Video Input Connector[{videoConnectorId}] InputSourceType: {sourceType}"); + Debug.Console(1, this, "Setting the camera id of video connector {0} to {1}", videoConnectorId, inputCameraId); + EnqueueCommand($"xConfiguration Video Input Connector[{videoConnectorId}] CameraControl CameraId: {inputCameraId}"); } - #endregion + public void SetInputSourceType(uint videoConnectorId, eCiscoCodecInputSourceType sourceType) + { + Debug.Console(1, this, "Setting the source type of video connector {0} to {1}", videoConnectorId, sourceType); + EnqueueCommand($"xConfiguration Video Input Connector[{videoConnectorId}] InputSourceType: {sourceType}"); + } + + #endregion - #region IHasCodecCameras Members + #region IHasCodecCameras Members - public event EventHandler CameraSelected; + public event EventHandler CameraSelected; public List Cameras { get; private set; } diff --git a/src/UserInterface/CiscoCodecUserInterface/CiscoCodecUserInterface.cs b/src/UserInterface/CiscoCodecUserInterface/CiscoCodecUserInterface.cs index ffc0c6d..62b3dbb 100644 --- a/src/UserInterface/CiscoCodecUserInterface/CiscoCodecUserInterface.cs +++ b/src/UserInterface/CiscoCodecUserInterface/CiscoCodecUserInterface.cs @@ -4,18 +4,14 @@ using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using Serilog.Events; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace epi_videoCodec_ciscoExtended.UserInterface.CiscoCodecUserInterface { public class CiscoCodecUserInterface : ReconfigurableDevice, ICiscoCodecUserInterface - { + { public CiscoCodec UisCiscoCodec { get; private set; } public CiscoCodecUserInterfaceConfig ConfigProps { get; } public ICiscoCodecUiExtensionsHandler CiscoCodecUiExtensionsHandler { get; set; } @@ -26,51 +22,51 @@ public class CiscoCodecUserInterface : ReconfigurableDevice, ICiscoCodecUserInte public bool EnableLockoutPoll { get; set; } = false; - public bool LockedOut { get; set; } = false; + public bool LockedOut { get; set; } = false; - #region ParseConfigProps - public T ParseConfigProps(DeviceConfig config) + #region ParseConfigProps + public T ParseConfigProps(DeviceConfig config) { return JsonConvert.DeserializeObject(config.Properties.ToString()); } - #endregion - - #region Custom Activate - private List CustomActivateActions = new List(); - - public override bool CustomActivate() - { - foreach (var action in CustomActivateActions) - { - action(); - } - return base.CustomActivate(); - } - - public void AddCustomActivationAction(Action a) - { - CustomActivateActions.Add(a); - } - #endregion + #endregion + + #region Custom Activate + private List CustomActivateActions = new List(); + + public override bool CustomActivate() + { + foreach (var action in CustomActivateActions) + { + action(); + } + return base.CustomActivate(); + } + + public void AddCustomActivationAction(Action a) + { + CustomActivateActions.Add(a); + } + #endregion public virtual void BuildRoomCombinerHandler() { - RoomCombinerHandler = new RoomCombiner.RoomCombinerHandler(this); - } + RoomCombinerHandler = new RoomCombiner.RoomCombinerHandler(this); + } - public CiscoCodecUserInterface(DeviceConfig config) : base(config) + public CiscoCodecUserInterface(DeviceConfig config) : base(config) { ConfigProps = ParseConfigProps(config); EnableLockoutPoll = ConfigProps.EnableLockoutPoll ?? false; - AddPreActivationAction(PreActivateAction); + AddPreActivationAction(PreActivateAction); BuildRoomCombinerHandler(); - } + } public void PreActivateAction() { - Debug.LogMessage(LogEventLevel.Debug, "[DEBUG] Activating Video Codec UI Extensions", this); - UisCiscoCodec = DeviceManager.GetDeviceForKey(ConfigProps.VideoCodecKey) as CiscoCodec; + Debug.LogMessage(LogEventLevel.Debug, "Activating Video Codec UI Extensions", this); + UisCiscoCodec = DeviceManager.GetDeviceForKey(ConfigProps.VideoCodecKey) as CiscoCodec; if (UisCiscoCodec == null) { @@ -91,10 +87,10 @@ public void PreActivateAction() UisCiscoCodec.IsReadyChange += (s, a) => { if (!UisCiscoCodec.IsReady) return; - var msg = UiExtensions != null ? "[DEBUG] Initializing Video Codec UI Extensions" : "[DEBUG] No Ui Extensions in config"; + var msg = UiExtensions != null ? "Initializing Video Codec UI Extensions" : "No Ui Extensions in config"; Debug.LogMessage(LogEventLevel.Debug, msg, this); UiExtensions.Initialize(this, UisCiscoCodec.EnqueueCommand); - Debug.LogMessage(LogEventLevel.Debug, "[DEBUG] Video Codec UI Extensions Handler Initilizing", this); + Debug.LogMessage(LogEventLevel.Debug, "Video Codec UI Extensions Handler Initilizing", this); }; //return base.CustomActivate(); return; diff --git a/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecTouchpanelController.cs b/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecTouchpanelController.cs index 988a082..df321c6 100644 --- a/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecTouchpanelController.cs +++ b/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecTouchpanelController.cs @@ -1,10 +1,7 @@ -using Crestron.SimplSharpPro.UI; -using epi_videoCodec_ciscoExtended.UserInterface.CiscoCodecUserInterface; -using PepperDash.Core; +using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using PepperDash.Essentials.Touchpanel; using Serilog.Events; using System; @@ -13,150 +10,147 @@ namespace epi_videoCodec_ciscoExtended.UserInterface.CiscoCodecUserInterface.MobileControl { - public class McVideoCodecTouchpanelController : CiscoCodecUserInterface, IMcCiscoCodecUserInterfaceAppControl, IMobileControlTouchpanelController - { - private readonly McVideoCodecUserInterfaceConfig _props; - private IMobileControlRoomMessenger _bridge; - private IMobileControl Mc; - private string _appUrl; - - public StringFeedback AppUrlFeedback { get; private set; } - private readonly StringFeedback QrCodeUrlFeedback; - private readonly StringFeedback McServerUrlFeedback; - private readonly StringFeedback UserCodeFeedback; - - public FeedbackCollection Feedbacks { get; private set; } - - public string DefaultRoomKey => _props.DefaultRoomKey; - - public bool UseDirectServer => _props.UseDirectServer; - - bool IMobileControlTouchpanelController.ZoomRoomController => false; - - //public BoolFeedback WebViewOpenFeedback => throw new NotImplementedException(); - - private McVideoCodecUserInterfaceRouter _router; - - public McVideoCodecTouchpanelController(DeviceConfig config) : base(config) - { - Debug.LogMessage(LogEventLevel.Debug, "McTouchpanelController Constructor", this); - _props = ParseConfigProps(config); - - AddPostActivationAction(PostActivateSubscribeForMobileControlUpdates); - - AppUrlFeedback = new StringFeedback(() => _appUrl); - QrCodeUrlFeedback = new StringFeedback(() => _bridge?.QrCodeUrl); - McServerUrlFeedback = new StringFeedback(() => _bridge?.McServerUrl); - UserCodeFeedback = new StringFeedback(() => _bridge?.UserCode); - - Feedbacks = new FeedbackCollection - { - AppUrlFeedback, QrCodeUrlFeedback, McServerUrlFeedback, UserCodeFeedback - }; - } - public override bool CustomActivate() - { - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] Activate", this); - Mc = DeviceManager.AllDevices.OfType().FirstOrDefault(); - - if (Mc == null) - { - return base.CustomActivate(); - } - - var messenger = new McVideoCodecUserInterfaceControlMessenger(string.Format("appControlMessenger-{0}", Key), string.Format("/device/{0}", Key), this); - - Mc.AddDeviceMessenger(messenger); - - //Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, $"mc.ClientAppUrl: {Mc.ClientAppUrl.MaskQParamTokenInUrl()}", this); - - return base.CustomActivate(); - } - - private void PostActivateSubscribeForMobileControlUpdates() - { - try - { - - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] SubscribeForMobileControlUpdates", this); - //foreach (var dev in DeviceManager.AllDevices) - //{ - // Debug.Console(0, this, $"{dev.Key}:{dev.GetType().Name}"); - //} - - Debug.LogMessage(LogEventLevel.Debug, $"[McTouchpanelController] GetBridge. DefaultRoomKey: {_props.DefaultRoomKey}", this); - if (Mc == null) - { - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] Mc is null", this); - return; - } - var bridge = Mc.GetRoomMessenger(_props.DefaultRoomKey); - if (bridge == null) - { - Debug.LogMessage(LogEventLevel.Debug, $"[McTouchpanelController] No Mobile Control bridge for {_props.DefaultRoomKey} found ", this); - return; - } - Debug.LogMessage(LogEventLevel.Debug, $"[McTouchpanelController] Got Bridge: {bridge.RoomName}", this); + public class McVideoCodecTouchpanelController : CiscoCodecUserInterface, IMcCiscoCodecUserInterfaceAppControl, IMobileControlTouchpanelController + { + private readonly McVideoCodecUserInterfaceConfig _props; + private IMobileControlRoomMessenger _bridge; + private IMobileControl Mc; + private string _appUrl; + + public StringFeedback AppUrlFeedback { get; private set; } + private readonly StringFeedback QrCodeUrlFeedback; + private readonly StringFeedback McServerUrlFeedback; + private readonly StringFeedback UserCodeFeedback; + + public FeedbackCollection Feedbacks { get; private set; } + + public string DefaultRoomKey => _props.DefaultRoomKey; + + public bool UseDirectServer => _props.UseDirectServer; + + bool IMobileControlTouchpanelController.ZoomRoomController => false; + + //public BoolFeedback WebViewOpenFeedback => throw new NotImplementedException(); + + private McVideoCodecUserInterfaceRouter _router; + + public McVideoCodecTouchpanelController(DeviceConfig config) : base(config) + { + Debug.LogMessage(LogEventLevel.Debug, "McTouchpanelController Constructor", this); + _props = ParseConfigProps(config); + + AddPostActivationAction(PostActivateSubscribeForMobileControlUpdates); + + AppUrlFeedback = new StringFeedback(() => _appUrl); + QrCodeUrlFeedback = new StringFeedback(() => _bridge?.QrCodeUrl); + McServerUrlFeedback = new StringFeedback(() => _bridge?.McServerUrl); + UserCodeFeedback = new StringFeedback(() => _bridge?.UserCode); + + Feedbacks = new FeedbackCollection + { + AppUrlFeedback, QrCodeUrlFeedback, McServerUrlFeedback, UserCodeFeedback + }; + } + public override bool CustomActivate() + { + Debug.LogMessage(LogEventLevel.Debug, "Activate", this); + Mc = DeviceManager.AllDevices.OfType().FirstOrDefault(); + + if (Mc == null) + { + return base.CustomActivate(); + } + + var messenger = new McVideoCodecUserInterfaceControlMessenger(string.Format("appControlMessenger-{0}", Key), string.Format("/device/{0}", Key), this); + + Mc.AddDeviceMessenger(messenger); + + //Debug.LogMessage(Serilog.Events.LogEventLevel.Debug, $"mc.ClientAppUrl: {Mc.ClientAppUrl.MaskQParamTokenInUrl()}", this); + + return base.CustomActivate(); + } + + private void PostActivateSubscribeForMobileControlUpdates() + { + try + { + + Debug.LogMessage(LogEventLevel.Debug, "SubscribeForMobileControlUpdates", this); + + Debug.LogMessage(LogEventLevel.Debug, "GetBridge. DefaultRoomKey: {defaultRoomKey}", this, _props.DefaultRoomKey); + if (Mc == null) + { + Debug.LogMessage(LogEventLevel.Debug, "Mc is null", this); + return; + } + var bridge = Mc.GetRoomMessenger(_props.DefaultRoomKey); + if (bridge == null) + { + Debug.LogMessage(LogEventLevel.Debug, "No Mobile Control bridge for {defaultRoomKey} found ", this, _props.DefaultRoomKey); + return; + } + Debug.LogMessage(LogEventLevel.Debug, "Got Bridge: {roomName}", this, bridge.RoomName); _bridge = bridge; - Debug.LogMessage(LogEventLevel.Debug, $"[McTouchpanelController] Setting AppUrl", this); - - Debug.LogMessage(LogEventLevel.Debug, $"[McTouchpanelController] Mobile Control Room Bridge Found {_bridge.Key}", this); - - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] Subscribing to Mobile Control Events: UserCodeChanged", this); - _bridge.UserCodeChanged += UpdateFeedbacks; - - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] Subscribing to Mobile Control Events: AppUrlChanged", this); - - //SetAppUrl here fixing AppUrlFeedback.StringValue null after initial event - _bridge.AppUrlChanged += (s, a) => { Debug.Console(0, this, "[McTouchpanelController] AppURL changed"); UpdateFeedbacks(s, a); - SetAppUrl(_bridge.AppUrl); - }; - - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] Building McVideoCodecUserInterfaceRouter", this); - _router = new McVideoCodecUserInterfaceRouter(this, _bridge, _props); - _router.Activate(this); - Debug.LogMessage(LogEventLevel.Debug, "[McTouchpanelController] SubscribeForMobileControlUpdates success", this); - } - catch (Exception e) - { - Debug.LogMessage(e, "SubscribeForMobileControlUpdates Error", this); - Debug.LogMessage(LogEventLevel.Debug, e.StackTrace, this); - } - } - - public void SetAppUrl(string url) - { - try - { - Debug.LogMessage(LogEventLevel.Debug, $"Setting AppUrl to: {url}", this); - _appUrl = url; - AppUrlFeedback.FireUpdate(); - } - catch (Exception e) - { - Debug.LogMessage(e, "SetAppUrl Error", this); - } - } - - private void UpdateFeedbacks(object sender, EventArgs args) - { - UpdateFeedbacks(); - } - - private void UpdateFeedbacks() - { - foreach (var feedback in Feedbacks) { feedback.FireUpdate(); } - } - - public void CloseWebViewController() - { - _router.ClearCiscoCodecUiWebViewController(); - } - - public void CloseWebViewOsd() - { - _router.ClearCiscoCodecUiWebViewOsd(); - } - } + Debug.LogMessage(LogEventLevel.Debug, "Setting AppUrl", this); + + Debug.LogMessage(LogEventLevel.Debug, "Mobile Control Room Bridge Found {bridgeKey}", this, _bridge?.Key); + + Debug.LogMessage(LogEventLevel.Debug, "Subscribing to Mobile Control Events: UserCodeChanged", this); + _bridge.UserCodeChanged += UpdateFeedbacks; + + Debug.LogMessage(LogEventLevel.Debug, "Subscribing to Mobile Control Events: AppUrlChanged", this); + + //SetAppUrl here fixing AppUrlFeedback.StringValue null after initial event + _bridge.AppUrlChanged += (s, a) => + { + Debug.LogMessage(LogEventLevel.Information, "AppURL changed", this); UpdateFeedbacks(s, a); + SetAppUrl(_bridge.AppUrl); + }; + + Debug.LogMessage(LogEventLevel.Debug, "Building McVideoCodecUserInterfaceRouter", this); + _router = new McVideoCodecUserInterfaceRouter(this, _bridge, _props); + _router.Activate(this); + Debug.LogMessage(LogEventLevel.Debug, "SubscribeForMobileControlUpdates success", this); + } + catch (Exception e) + { + Debug.LogMessage(e, "SubscribeForMobileControlUpdates Error", this); + } + } + + public void SetAppUrl(string url) + { + try + { + Debug.LogMessage(LogEventLevel.Debug, "Setting AppUrl to: {url}", this, url); + _appUrl = url; + AppUrlFeedback.FireUpdate(); + } + catch (Exception e) + { + Debug.LogMessage(e, "SetAppUrl Error", this); + } + } + + private void UpdateFeedbacks(object sender, EventArgs args) + { + UpdateFeedbacks(); + } + + private void UpdateFeedbacks() + { + foreach (var feedback in Feedbacks) { feedback.FireUpdate(); } + } + + public void CloseWebViewController() + { + _router.ClearCiscoCodecUiWebViewController(); + } + + public void CloseWebViewOsd() + { + _router.ClearCiscoCodecUiWebViewOsd(); + } + } } diff --git a/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecUserInterfaceRouter.cs b/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecUserInterfaceRouter.cs index 5c5a807..e999215 100644 --- a/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecUserInterfaceRouter.cs +++ b/src/UserInterface/CiscoCodecUserInterface/MobileControl/McVideoCodecUserInterfaceRouter.cs @@ -1,162 +1,177 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Crestron.SimplSharp.Net; +using Crestron.SimplSharp.Net; using epi_videoCodec_ciscoExtended.UserInterface.CiscoCodecUserInterface.RoomCombiner; using epi_videoCodec_ciscoExtended.UserInterface.UserInterfaceExtensions; -using epi_videoCodec_ciscoExtended.UserInterface.UserInterfaceExtensions.Panels; using epi_videoCodec_ciscoExtended.UserInterface.UserInterfaceWebViewDisplay; -using Independentsoft.Json.Parser; -using Newtonsoft.Json; using PepperDash.Core; using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Devices; using PepperDash.Essentials.Core.DeviceTypeInterfaces; -using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; using Serilog.Events; +using System; +using System.Collections.Generic; +using System.Linq; namespace epi_videoCodec_ciscoExtended.UserInterface.CiscoCodecUserInterface.MobileControl { - internal class McVideoCodecUserInterfaceRouter : IKeyed - { - private McVideoCodecTouchpanelController _mcTpController; - - private ICiscoCodecUiExtensionsHandler _extensionsHandler; - - private IRoomCombinerHandler _combinerHandler; - private IMobileControlRoomMessenger _bridge; - - private McVideoCodecUserInterfaceConfig _props { get; } - - public string Key { get; } - - private System.Timers.Timer _lockoutPollTimer; - - private string _thisUisDefaultRoomKey; - private string _primaryRoomKey; - - private UiWebViewDisplayConfig _defaultUiWebViewDisplayConfig = new UiWebViewDisplayConfig() - { - Title = "Mobile Control", - Target = "Controller", - Mode = "Modal" - }; - - internal McVideoCodecUserInterfaceRouter( - McVideoCodecTouchpanelController ui, - IMobileControlRoomMessenger bridge, - McVideoCodecUserInterfaceConfig props - ) - { - _props = props; - _mcTpController = ui; - _bridge = bridge; - Key = ui.Key + "-McVcUiRouter"; - } - - internal void Activate(McVideoCodecTouchpanelController ui) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"Activating VideoCodecMobileControlRouter for {ui.Key}", - this - ); - //set private props after activation so everything is instantiated - if (ui == null) - { - Debug.LogMessage(LogEventLevel.Debug, $"Error: {ui.Key} is null", this); - return; - } - _mcTpController = ui; - _extensionsHandler = ui.CiscoCodecUiExtensionsHandler; - Debug.LogMessage( - LogEventLevel.Debug, - "VideoCodecUiExtensionsHandler null: {0}", - this, - ui.CiscoCodecUiExtensionsHandler == null - ); - - _combinerHandler = ui.RoomCombinerHandler; - Debug.LogMessage( - LogEventLevel.Debug, - "EssentialsRoomCombiner null: {0}", - this, - ui.RoomCombinerHandler.EssentialsRoomCombiner == null - ); - Debug.LogMessage( - LogEventLevel.Debug, - "MobileControlRoomBridge null: {0}", - this, - _bridge == null - ); - - if (_extensionsHandler == null) - { - Debug.LogMessage( - LogEventLevel.Debug, - "[Warning]: VideoCodecUiExtensionsHandler is null. Skipping VideoCodecMobileControlRouter Subscriptions", - this - ); - return; - } - Debug.LogMessage( - LogEventLevel.Debug, - "VideoCodecMobileControlRouter Registering for VideoCodecUiExtensionsHandler.UiExtensionsClickedEvent", - this - ); - - - _mcTpController.UisCiscoCodec.IsReadyChange += (s, a) => - { - if (!_mcTpController.UisCiscoCodec.IsReady) return; - + internal class McVideoCodecUserInterfaceRouter : IKeyed + { + private McVideoCodecTouchpanelController _mcTpController; + + private ICiscoCodecUiExtensionsHandler _extensionsHandler; + + private IRoomCombinerHandler _combinerHandler; + private IMobileControlRoomMessenger _bridge; + + private McVideoCodecUserInterfaceConfig _props { get; } + + public string Key { get; } + + private System.Timers.Timer _lockoutPollTimer; + + private string _thisUisDefaultRoomKey; + private string _primaryRoomKey; + + private UiWebViewDisplayConfig _defaultUiWebViewDisplayConfig = new UiWebViewDisplayConfig() + { + Title = "Mobile Control", + Target = "Controller", + Mode = "Modal" + }; + + internal McVideoCodecUserInterfaceRouter( + McVideoCodecTouchpanelController ui, + IMobileControlRoomMessenger bridge, + McVideoCodecUserInterfaceConfig props + ) + { + _props = props; + _mcTpController = ui; + _bridge = bridge; + Key = ui.Key + "-McVcUiRouter"; + + _lockoutPollTimer = new System.Timers.Timer( + _props?.Lockout?.PollIntervalMs > 0 ? _props.Lockout.PollIntervalMs : 5000 + ) + { + Enabled = false, + AutoReset = true + }; + + _lockoutPollTimer.Elapsed += (s, a) => + { + Debug.LogMessage(LogEventLevel.Verbose, "Lockout Poll Timer Elapsed", this); + if (!_mcTpController.LockedOut) + { + Debug.LogMessage(LogEventLevel.Verbose, $"_mcTpController.LockedOut: {_mcTpController.LockedOut}", this); + //if not in lockout state and was previously locked out + CancelLockoutTimer(); + return; + } + _mcTpController.UisCiscoCodec.EnqueueCommand(UiWebViewDisplay.xCommandStatus()); + }; + } + + internal void Activate(McVideoCodecTouchpanelController ui) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"Activating VideoCodecMobileControlRouter for {ui.Key}", + this + ); + //set private props after activation so everything is instantiated + if (ui == null) + { + Debug.LogMessage(LogEventLevel.Debug, $"Error: {ui.Key} is null", this); + return; + } + _mcTpController = ui; + _extensionsHandler = ui.CiscoCodecUiExtensionsHandler; + Debug.LogMessage( + LogEventLevel.Debug, + "VideoCodecUiExtensionsHandler null: {0}", + this, + ui.CiscoCodecUiExtensionsHandler == null + ); + + _combinerHandler = ui.RoomCombinerHandler; + Debug.LogMessage( + LogEventLevel.Debug, + "EssentialsRoomCombiner null: {0}", + this, + ui.RoomCombinerHandler.EssentialsRoomCombiner == null + ); + Debug.LogMessage( + LogEventLevel.Debug, + "MobileControlRoomBridge null: {0}", + this, + _bridge == null + ); + + if (_extensionsHandler == null) + { + Debug.LogMessage( + LogEventLevel.Debug, + "[Warning]: VideoCodecUiExtensionsHandler is null. Skipping VideoCodecMobileControlRouter Subscriptions", + this + ); + return; + } + Debug.LogMessage( + LogEventLevel.Debug, + "VideoCodecMobileControlRouter Registering for VideoCodecUiExtensionsHandler.UiExtensionsClickedEvent", + this + ); + + + _mcTpController.UisCiscoCodec.IsReadyChange += (s, a) => + { + if (!_mcTpController.UisCiscoCodec.IsReady) return; + //send lockout if in lockout state - HandleRoomCombineScenarioChanged(); + HandleRoomCombineScenarioChanged(); }; - if (_combinerHandler.EssentialsRoomCombiner != null) - { - //subscribe to events for routing buttons from codec ui to mobile control - _combinerHandler.EssentialsRoomCombiner.RoomCombinationScenarioChanged += - Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler; - } - - _extensionsHandler.UiExtensionsClickedEvent += - VideoCodecUiExtensionsClickedMcEventHandler; - - _thisUisDefaultRoomKey = _mcTpController?.DefaultRoomKey; - - Debug.LogMessage( - LogEventLevel.Debug, - "VideoCodecMobileControlRouter Registering for MobileControlRoomBridge.AppUrlChanged", - this - ); - - Debug.LogMessage( - LogEventLevel.Debug, - "VideoCodecMobileControlRouter initialized for {0}", - this, - ui.Key - ); - } - - private void Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler( - object sender, - EventArgs e - ) - { - HandleRoomCombineScenarioChanged(); - } - - private void HandleRoomCombineScenarioChanged() - { + if (_combinerHandler.EssentialsRoomCombiner != null) + { + //subscribe to events for routing buttons from codec ui to mobile control + _combinerHandler.EssentialsRoomCombiner.RoomCombinationScenarioChanged += + Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler; + } + + _extensionsHandler.UiExtensionsClickedEvent += + VideoCodecUiExtensionsClickedMcEventHandler; + + _thisUisDefaultRoomKey = _mcTpController?.DefaultRoomKey; + + Debug.LogMessage( + LogEventLevel.Debug, + "VideoCodecMobileControlRouter Registering for MobileControlRoomBridge.AppUrlChanged", + this + ); + + Debug.LogMessage( + LogEventLevel.Debug, + "VideoCodecMobileControlRouter initialized for {0}", + this, + ui.Key + ); + } + + private void Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler( + object sender, + EventArgs e + ) + { + HandleRoomCombineScenarioChanged(); + } + + private void HandleRoomCombineScenarioChanged() + { try { Debug.LogMessage( LogEventLevel.Debug, "Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler", - null, - null + this ); var combiner = _combinerHandler?.EssentialsRoomCombiner; @@ -170,8 +185,7 @@ private void HandleRoomCombineScenarioChanged() Debug.LogMessage( LogEventLevel.Debug, $"thisUisDefaultRoomKey: {_thisUisDefaultRoomKey}", - null, - null + this ); var thisUisUiMapRoomKeyValue = ( uimap?.FirstOrDefault((kv) => kv.Key == _thisUisDefaultRoomKey) @@ -179,15 +193,13 @@ private void HandleRoomCombineScenarioChanged() Debug.LogMessage( LogEventLevel.Debug, $"thisUisUiMapRoomKeyValue: {thisUisUiMapRoomKeyValue}", - null, - null + this ); var getPrimaryKeySuccess = uimap?.TryGetValue("primary", out _primaryRoomKey); Debug.LogMessage( LogEventLevel.Debug, $"primaryRoomKey done: {_primaryRoomKey}", - null, - null + this ); if (!getPrimaryKeySuccess.GetValueOrDefault()) @@ -195,8 +207,7 @@ private void HandleRoomCombineScenarioChanged() Debug.LogMessage( LogEventLevel.Debug, $"Primary room key not found in UiMap for scenario: {curScenario.Key}", - null, - null + this ); } if (thisUisUiMapRoomKeyValue == null) @@ -204,53 +215,31 @@ private void HandleRoomCombineScenarioChanged() Debug.LogMessage( LogEventLevel.Debug, $"[ERROR] UiMap default room key: {_thisUisDefaultRoomKey} Error: UiMap must have an entry keyed to default room key with value of room connection for room state {curScenario.Key} or lockout", - null, - null + this ); return; } if (thisUisUiMapRoomKeyValue == "lockout") { - Debug.LogMessage(LogEventLevel.Debug, $"UiMap default room key {_thisUisDefaultRoomKey} is in lockout state", null, null); + Debug.LogMessage(LogEventLevel.Debug, $"UiMap default room key {_thisUisDefaultRoomKey} is in lockout state", this); _mcTpController.LockedOut = true; //SendLockout(_thisUisDefaultRoomKey, _primaryRoomKey); _extensionsHandler.UiWebViewChanagedEvent += LockoutUiWebViewChanagedEventHandler; _mcTpController.UisCiscoCodec.EnqueueCommand(UiWebViewDisplay.xCommandStatus()); if (_mcTpController.EnableLockoutPoll) { - // Start the timer when lockout occurs - if (_lockoutPollTimer == null) - { - _lockoutPollTimer = new System.Timers.Timer( - _props?.Lockout?.PollIntervalMs > 0 ? _props.Lockout.PollIntervalMs : 5000 - ); - _lockoutPollTimer.Enabled = false; - _lockoutPollTimer.AutoReset = true; - } + // Start the timer when lockout occurs _lockoutPollTimer.Start(); - _lockoutPollTimer.Elapsed += (s, a) => - { - Debug.LogMessage(LogEventLevel.Verbose, "Lockout Poll Timer Elapsed", null, null); - if (!_mcTpController.LockedOut) - { - Debug.LogMessage(LogEventLevel.Verbose, $"_mcTpController.LockedOut: {_mcTpController.LockedOut}", null, null); - //if not in lockout state and was previously locked out - CancelLockoutTimer(); - return; - } - _mcTpController.UisCiscoCodec.EnqueueCommand(UiWebViewDisplay.xCommandStatus()); - }; return; } return; } - CancelLockoutTimer(); + CancelLockoutTimer(); Debug.LogMessage( LogEventLevel.Debug, $"ui with default room key {_thisUisDefaultRoomKey} is not locked out", - null, - null + this ); } catch (Exception ex) @@ -258,251 +247,242 @@ private void HandleRoomCombineScenarioChanged() Debug.LogMessage( ex, "Error in Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler", - null, - null - ); - Debug.LogMessage( - LogEventLevel.Debug, - $"Error in Combiner_RoomCombinationScenarioChanged_Lockout_EventHandler: {ex.Message}, {ex.StackTrace}", - null, - null + this ); } } - private void CancelLockoutTimer() - { - Debug.LogMessage(LogEventLevel.Verbose, $"Canceling Lockout Poll Timer for: {_mcTpController.Key}", null, _mcTpController.Key); + private void CancelLockoutTimer() + { + Debug.LogMessage(LogEventLevel.Verbose, $"Canceling Lockout Poll Timer for: {_mcTpController.Key}", this, _mcTpController.Key); _extensionsHandler.UiWebViewChanagedEvent -= LockoutUiWebViewChanagedEventHandler; _mcTpController.LockedOut = false; ClearCiscoCodecUiWebViewController(); _lockoutPollTimer.Stop(); - _lockoutPollTimer.Dispose(); } - public void LockoutUiWebViewChanagedEventHandler(object sender, UiWebViewChanagedEventArgs args) - { - bool isError = args?.UiWebViewStatus?.IsError ?? false; - if (isError) //isError means no webview open - { - Debug.LogMessage( - LogEventLevel.Debug, - $"Error in UiWebViewChanagedEventHandler. XPath: {args?.UiWebViewStatus?.ErrorStatus?.XPath?.Value}" + - $"Reason: {args?.UiWebViewStatus?.ErrorStatus?.Reason?.Value}", null, null); - - //if web view not open and in lockout send lockout to web view - if (_mcTpController.LockedOut == true) - { - SendLockout(_thisUisDefaultRoomKey, _primaryRoomKey); - } - return; - } - - if (_mcTpController.LockedOut == false) - { - UiWebView uiWebView = args?.UiWebViewStatus?.UiWebView; - _extensionsHandler.UiWebViewClearAction?.Invoke( - new UiWebViewDisplayClearActionArgs() { Target = "Controller" } - ); - } - } - - private void SendLockout(string thisUisDefaultRoomKey, string primaryRoomKey) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"UiMap default room key: {thisUisDefaultRoomKey} is in lockout state", - null, - null - ); - var path = _props?.Lockout?.MobileControlPath; - Debug.LogMessage(LogEventLevel.Debug, $"Lockout path: {path}", null, null); - if (path == null || path.Length == 0) - path = "/lockout"; - Debug.LogMessage(LogEventLevel.Debug, $"Lockout path: {path}", null, null); - var webViewConfig = - _props?.Lockout?.UiWebViewDisplay == null - ? _defaultUiWebViewDisplayConfig - : _props.Lockout.UiWebViewDisplay; - if (!string.IsNullOrEmpty(primaryRoomKey)) - { - var room = DeviceManager.GetDeviceForKey(primaryRoomKey) as IKeyName; - Debug.LogMessage(LogEventLevel.Debug, $"room: {room?.Name}", null, null); - if (webViewConfig.QueryParams == null) - { - webViewConfig.QueryParams = new Dictionary(); - } - - webViewConfig.QueryParams["primaryRoomName"] = - room != null ? room.Name : primaryRoomKey; - } - SendCiscoCodecUiToWebViewMcUrl(path, webViewConfig); - } - - private void VideoCodecUiExtensionsClickedMcEventHandler( - object sender, - UiExtensionsClickedEventArgs e - ) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"VideoCodecUiExtensionsClickedMcEventHandler: {e.Id}", - this - ); - try - { - //navigator button click build url and use VideoCodecUiExtensionsHandler action to send to mobile control - var panelId = e.Id; - var extensions = _props.Extensions; - if (extensions == null || !extensions.Panels.Any()) - { - Debug.LogMessage( - LogEventLevel.Debug, - "No extensions found for VideoCodecMobileControlRouter", - _mcTpController - ); - return; - } - var panels = extensions.Panels; - var mcPanel = panels.Find((pp) => pp.PanelId == panelId); - if (mcPanel == null) - { - Debug.LogMessage( - LogEventLevel.Debug, - "Panel not found for VideoCodecMobileControlRouter", - this - ); - return; - } - if (mcPanel.MobileControlPath == null || mcPanel.MobileControlPath.Length == 0) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"MobileControlPath not found for {mcPanel.Name}", - this - ); - return; - } - if (mcPanel.UiWebViewDisplay == null) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"[Warning] UiWebViewDisplay not found for {mcPanel.Name} using default Title: ${_defaultUiWebViewDisplayConfig.Title}, Mode: {_defaultUiWebViewDisplayConfig.Mode}, Target: {_defaultUiWebViewDisplayConfig}", - this - ); - } - SendCiscoCodecUiToWebViewMcUrl(mcPanel.MobileControlPath, mcPanel.UiWebViewDisplay); - } - catch (Exception ex) - { - Debug.LogMessage(ex, "Error Sending Mc URL to Cisco Ui", this); - Debug.LogMessage( - LogEventLevel.Debug, - $"Error Sending Mc URL to Cisco Ui: {ex.Message}", - this - ); - } - } - - /// - /// Send the cisco ui to a webview with mc app url + path using the webViewConfig - /// - /// - /// - public void SendCiscoCodecUiToWebViewMcUrl( - string mcPath, - UiWebViewDisplayConfig webViewConfig - ) - { - Debug.LogMessage( - LogEventLevel.Debug, - $"SendCiscoCodecUiToWebViewMcUrl: {mcPath}, webViewConfig null: {webViewConfig == null}, " - + $"_McTouchPanelController: {_mcTpController == null}, " - + $"AppUrlFeedback null: {_mcTpController?.AppUrlFeedback == null}, " - + $"appUrl: {_mcTpController?.AppUrlFeedback?.StringValue}", - this - ); - // Parse the _appUrl into a Uri object - var appUrl = _mcTpController.AppUrlFeedback.StringValue; - if (appUrl == null) - { - Debug.LogMessage( - LogEventLevel.Debug, - "AppUrl is null, cannot send to WebView", - this - ); - return; - } - //var printableAppUrl = _mcTpController?.AppUrlFeedback?.StringValue?.MaskQParamTokenInUrl(); - //Debug.LogMessage( - // LogEventLevel.Debug, - // $"SendCiscoCodecUiToWebViewMcUrl: {printableAppUrl}", - // this - //); - - UriBuilder uriBuilder = new UriBuilder(appUrl); - - //check for qparams - var qparams = webViewConfig.QueryParams; - if (qparams != null) - { - var parameters = HttpUtility.ParseQueryString(uriBuilder.Query); - foreach (var item in qparams) - { - parameters.Add(item.Key, item.Value); - } - uriBuilder.Query = parameters.ToString(); - } - - // Append suffix (i.e: "/lockout") to the path - uriBuilder.Path = uriBuilder.Path.TrimEnd('/') + mcPath; - - // Get the final URL - var url = uriBuilder.ToString(); - - var printableUrl = uriBuilder.ToString().MaskQParamTokenInUrl(); - - Debug.LogMessage( - LogEventLevel.Debug, - "[MobileControlClickedEvent] Sending Mobile Control URL: {0}", - this, - printableUrl - ); - - _extensionsHandler.UiWebViewDisplayAction?.Invoke( - new UiWebViewDisplayActionArgs() - { - Title = - webViewConfig.Title != null - ? webViewConfig.Title - : _defaultUiWebViewDisplayConfig.Title, - Url = url, - Target = - webViewConfig.Target != null - ? webViewConfig.Target - : _defaultUiWebViewDisplayConfig.Target, - Mode = - webViewConfig.Mode != null - ? webViewConfig.Mode - : _defaultUiWebViewDisplayConfig.Mode - } - ); - } - - public void ClearCiscoCodecUiWebViewController() - { - Debug.LogMessage(LogEventLevel.Debug, "ClearCiscoCodecUiWebViewController", this); - _extensionsHandler?.UiWebViewClearAction?.Invoke( - new UiWebViewDisplayClearActionArgs() { Target = "Controller" } - ); - } - - public void ClearCiscoCodecUiWebViewOsd() - { - Debug.LogMessage(LogEventLevel.Debug, "ClearCiscoCodecUiWebViewOsd", this); - _extensionsHandler?.UiWebViewClearAction?.Invoke( - new UiWebViewDisplayClearActionArgs() { Target = "OSD" } - ); - } - } + public void LockoutUiWebViewChanagedEventHandler(object sender, UiWebViewChanagedEventArgs args) + { + bool isError = args?.UiWebViewStatus?.IsError ?? false; + if (isError) //isError means no webview open + { + Debug.LogMessage( + LogEventLevel.Debug, + $"Error in UiWebViewChanagedEventHandler. XPath: {args?.UiWebViewStatus?.ErrorStatus?.XPath?.Value}" + + $"Reason: {args?.UiWebViewStatus?.ErrorStatus?.Reason?.Value}", this); + + //if web view not open and in lockout send lockout to web view + if (_mcTpController.LockedOut == true) + { + SendLockout(_thisUisDefaultRoomKey, _primaryRoomKey); + } + return; + } + + if (_mcTpController.LockedOut == false) + { + UiWebView uiWebView = args?.UiWebViewStatus?.UiWebView; + _extensionsHandler.UiWebViewClearAction?.Invoke( + new UiWebViewDisplayClearActionArgs() { Target = "Controller" } + ); + } + } + + private void SendLockout(string thisUisDefaultRoomKey, string primaryRoomKey) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"UiMap default room key: {thisUisDefaultRoomKey} is in lockout state", + this + ); + var path = _props?.Lockout?.MobileControlPath; + Debug.LogMessage(LogEventLevel.Debug, $"Lockout path: {path}", this); + if (path == null || path.Length == 0) + path = "/lockout"; + Debug.LogMessage(LogEventLevel.Debug, $"Lockout path: {path}", this); + var webViewConfig = + _props?.Lockout?.UiWebViewDisplay == null + ? _defaultUiWebViewDisplayConfig + : _props.Lockout.UiWebViewDisplay; + if (!string.IsNullOrEmpty(primaryRoomKey)) + { + var room = DeviceManager.GetDeviceForKey(primaryRoomKey) as IKeyName; + Debug.LogMessage(LogEventLevel.Debug, $"room: {room?.Name}", this); + if (webViewConfig.QueryParams == null) + { + webViewConfig.QueryParams = new Dictionary(); + } + + webViewConfig.QueryParams["primaryRoomName"] = + room != null ? room.Name : primaryRoomKey; + } + SendCiscoCodecUiToWebViewMcUrl(path, webViewConfig); + } + + private void VideoCodecUiExtensionsClickedMcEventHandler( + object sender, + UiExtensionsClickedEventArgs e + ) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"VideoCodecUiExtensionsClickedMcEventHandler: {e.Id}", + this + ); + try + { + //navigator button click build url and use VideoCodecUiExtensionsHandler action to send to mobile control + var panelId = e.Id; + var extensions = _props.Extensions; + if (extensions == null || !extensions.Panels.Any()) + { + Debug.LogMessage( + LogEventLevel.Debug, + "No extensions found for VideoCodecMobileControlRouter", + _mcTpController + ); + return; + } + var panels = extensions.Panels; + var mcPanel = panels.Find((pp) => pp.PanelId == panelId); + if (mcPanel == null) + { + Debug.LogMessage( + LogEventLevel.Debug, + "Panel not found for VideoCodecMobileControlRouter", + this + ); + return; + } + if (mcPanel.MobileControlPath == null || mcPanel.MobileControlPath.Length == 0) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"MobileControlPath not found for {mcPanel.Name}", + this + ); + return; + } + if (mcPanel.UiWebViewDisplay == null) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"[Warning] UiWebViewDisplay not found for {mcPanel.Name} using default Title: ${_defaultUiWebViewDisplayConfig.Title}, Mode: {_defaultUiWebViewDisplayConfig.Mode}, Target: {_defaultUiWebViewDisplayConfig}", + this + ); + } + SendCiscoCodecUiToWebViewMcUrl(mcPanel.MobileControlPath, mcPanel.UiWebViewDisplay); + } + catch (Exception ex) + { + Debug.LogMessage(ex, "Error Sending Mc URL to Cisco Ui", this); + Debug.LogMessage( + LogEventLevel.Debug, + $"Error Sending Mc URL to Cisco Ui: {ex.Message}", + this + ); + } + } + + /// + /// Send the cisco ui to a webview with mc app url + path using the webViewConfig + /// + /// + /// + public void SendCiscoCodecUiToWebViewMcUrl( + string mcPath, + UiWebViewDisplayConfig webViewConfig + ) + { + Debug.LogMessage( + LogEventLevel.Debug, + $"SendCiscoCodecUiToWebViewMcUrl: {mcPath}, webViewConfig null: {webViewConfig == null}, " + + $"_McTouchPanelController: {_mcTpController == null}, " + + $"AppUrlFeedback null: {_mcTpController?.AppUrlFeedback == null}, " + + $"appUrl: {_mcTpController?.AppUrlFeedback?.StringValue}", + this + ); + // Parse the _appUrl into a Uri object + var appUrl = _mcTpController.AppUrlFeedback.StringValue; + if (appUrl == null) + { + Debug.LogMessage( + LogEventLevel.Debug, + "AppUrl is null, cannot send to WebView", + this + ); + return; + } + //var printableAppUrl = _mcTpController?.AppUrlFeedback?.StringValue?.MaskQParamTokenInUrl(); + //Debug.LogMessage( + // LogEventLevel.Debug, + // $"SendCiscoCodecUiToWebViewMcUrl: {printableAppUrl}", + // this + //); + + UriBuilder uriBuilder = new UriBuilder(appUrl); + + //check for qparams + var qparams = webViewConfig.QueryParams; + if (qparams != null) + { + var parameters = HttpUtility.ParseQueryString(uriBuilder.Query); + foreach (var item in qparams) + { + parameters.Add(item.Key, item.Value); + } + uriBuilder.Query = parameters.ToString(); + } + + // Append suffix (i.e: "/lockout") to the path + uriBuilder.Path = uriBuilder.Path.TrimEnd('/') + mcPath; + + // Get the final URL + var url = uriBuilder.ToString(); + + var printableUrl = uriBuilder.ToString().MaskQParamTokenInUrl(); + + Debug.LogMessage( + LogEventLevel.Debug, + "[MobileControlClickedEvent] Sending Mobile Control URL: {0}", + this, + printableUrl + ); + + _extensionsHandler.UiWebViewDisplayAction?.Invoke( + new UiWebViewDisplayActionArgs() + { + Title = + webViewConfig.Title != null + ? webViewConfig.Title + : _defaultUiWebViewDisplayConfig.Title, + Url = url, + Target = + webViewConfig.Target != null + ? webViewConfig.Target + : _defaultUiWebViewDisplayConfig.Target, + Mode = + webViewConfig.Mode != null + ? webViewConfig.Mode + : _defaultUiWebViewDisplayConfig.Mode + } + ); + } + + public void ClearCiscoCodecUiWebViewController() + { + Debug.LogMessage(LogEventLevel.Debug, "ClearCiscoCodecUiWebViewController", this); + _extensionsHandler?.UiWebViewClearAction?.Invoke( + new UiWebViewDisplayClearActionArgs() { Target = "Controller" } + ); + } + + public void ClearCiscoCodecUiWebViewOsd() + { + Debug.LogMessage(LogEventLevel.Debug, "ClearCiscoCodecUiWebViewOsd", this); + _extensionsHandler?.UiWebViewClearAction?.Invoke( + new UiWebViewDisplayClearActionArgs() { Target = "OSD" } + ); + } + } }