From 7f87b083cb60dd656ca57226115f8c0e52711d2d Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Thu, 16 Jan 2020 20:12:44 -0700 Subject: [PATCH] Adds improved camera messaging to VideoCodecBaseMessenger --- .../Messengers/VideoCodecBaseMessenger.cs | 225 +++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs index 29c80085..0ee943c9 100644 --- a/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs +++ b/PepperDashEssentials/AppServer/Messengers/VideoCodecBaseMessenger.cs @@ -7,6 +7,8 @@ using Crestron.SimplSharp; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using PepperDash.Core; + using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.Cameras; using PepperDash.Essentials.Devices.Common.VideoCodec; @@ -202,6 +204,59 @@ namespace PepperDash.Essentials.AppServer.Messengers { appServerController.AddAction(MessagePath + "/getCallHistory", new Action(GetCallHistory)); } + var cameraCodec = Codec as IHasCodecCameras; + if (cameraCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecCameras Actions"); + + cameraCodec.CameraSelected += new EventHandler(cameraCodec_CameraSelected); + + appServerController.AddAction(MessagePath + "/cameraSelect", new Action(s => cameraCodec.SelectCamera(s))); + + MapCameraActions(); + + var presetsCodec = Codec as IHasCodecRoomPresets; + if (presetsCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecRoomPresets Actions"); + + presetsCodec.CodecRoomPresetsListHasChanged += new EventHandler(presetsCodec_CameraPresetsListHasChanged); + + appServerController.AddAction(MessagePath + "/cameraPreset", new Action(u => presetsCodec.CodecRoomPresetSelect(u))); + appServerController.AddAction(MessagePath + "/cameraPresetStore", new Action(p => presetsCodec.CodecRoomPresetStore(p.ID, p.Description))); + } + + var speakerTrackCodec = Codec as IHasCameraAutoMode; + if (speakerTrackCodec != null) + { + Debug.Console(2, this, "Adding IHasCameraAutoMode Actions"); + + speakerTrackCodec.CameraAutoModeIsOnFeedback.OutputChange += new EventHandler(CameraAutoModeIsOnFeedback_OutputChange); + + appServerController.AddAction(MessagePath + "/cameraAuto", new Action(speakerTrackCodec.CameraAutoModeOn)); + appServerController.AddAction(MessagePath + "/cameraManual", new Action(speakerTrackCodec.CameraAutoModeOff)); + } + } + + var selfViewCodec = Codec as IHasCodecSelfView; + + if (selfViewCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecSelfView Actions"); + + appServerController.AddAction(MessagePath + "/cameraSelfView", new Action(selfViewCodec.SelfViewModeToggle)); + } + + var layoutsCodec = Codec as IHasCodecLayouts; + + if (layoutsCodec != null) + { + Debug.Console(2, this, "Adding IHasCodecLayouts Actions"); + + appServerController.AddAction(MessagePath + "/cameraRemoteView", new Action(layoutsCodec.LocalLayoutToggle)); + } + + Debug.Console(2, this, "Adding Privacy & Standby Actions"); appServerController.AddAction(MessagePath + "/privacyModeOn", new Action(Codec.PrivacyModeOn)); appServerController.AddAction(MessagePath + "/privacyModeOff", new Action(Codec.PrivacyModeOff)); @@ -212,6 +267,89 @@ namespace PepperDash.Essentials.AppServer.Messengers appServerController.AddAction(MessagePath + "/standbyOff", new Action(Codec.StandbyDeactivate)); } + void presetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e) + { + PostCameraPresets(); + } + + void CameraAutoModeIsOnFeedback_OutputChange(object sender, PepperDash.Essentials.Core.FeedbackEventArgs e) + { + PostCameraMode(); + } + + + void cameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e) + { + MapCameraActions(); + PostSelectedCamera(); + } + + /// + /// Maps the camera control actions to the current selected camera on the codec + /// + void MapCameraActions() + { + var cameraCodec = Codec as IHasCameras; + + if (cameraCodec != null && cameraCodec.SelectedCamera != null) + { + + AppServerController.RemoveAction(MessagePath + "/cameraUp"); + AppServerController.RemoveAction(MessagePath + "/cameraDown"); + AppServerController.RemoveAction(MessagePath + "/cameraLeft"); + AppServerController.RemoveAction(MessagePath + "/cameraRight"); + AppServerController.RemoveAction(MessagePath + "/cameraZoomIn"); + AppServerController.RemoveAction(MessagePath + "/cameraZoomOut"); + AppServerController.RemoveAction(MessagePath + "/cameraHome"); + + var camera = cameraCodec.SelectedCamera as IHasCameraPtzControl; + if (camera != null) + { + AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction(new Action(b => { if (b)camera.TiltUp(); else camera.TiltStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction(new Action(b => { if (b)camera.TiltDown(); else camera.TiltStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction(new Action(b => { if (b)camera.PanLeft(); else camera.PanStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction(new Action(b => { if (b)camera.PanRight(); else camera.PanStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction(new Action(b => { if (b)camera.ZoomIn(); else camera.ZoomStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction(new Action(b => { if (b)camera.ZoomOut(); else camera.ZoomStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraHome", new Action(camera.PositionHome)); + + var focusCamera = cameraCodec as IHasCameraFocusControl; + + AppServerController.RemoveAction(MessagePath + "/cameraAutoFocus"); + AppServerController.RemoveAction(MessagePath + "/cameraFocusNear"); + AppServerController.RemoveAction(MessagePath + "/cameraFocusFar"); + + if (focusCamera != null) + { + AppServerController.AddAction(MessagePath + "/cameraAutoFocus", new Action(focusCamera.TriggerAutoFocus)); + AppServerController.AddAction(MessagePath + "/cameraFocusNear", new PressAndHoldAction(new Action(b => { if (b)focusCamera.FocusNear(); else focusCamera.FocusStop(); }))); + AppServerController.AddAction(MessagePath + "/cameraFocusFar", new PressAndHoldAction(new Action(b => { if (b)focusCamera.FocusFar(); else focusCamera.FocusStop(); }))); + } + } + } + } + + string GetCameraMode() + { + string m = ""; + + var speakerTrackCodec = Codec as IHasCameraAutoMode; + if (speakerTrackCodec != null) + { + if (speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue) m = eCameraControlMode.Auto.ToString(); + else m = eCameraControlMode.Manual.ToString(); + } + + var cameraOffCodec = Codec as IHasCameraOff; + if (cameraOffCodec != null) + { + if (cameraOffCodec.CameraIsOffFeedback.BoolValue) + m = eCameraControlMode.Off.ToString(); + } + + return m; + } + void GetCallHistory() { var codec = (Codec as IHasCallHistory); @@ -344,6 +482,22 @@ namespace PepperDash.Essentials.AppServer.Messengers return; } + object cameraInfo = null; + + var camerasCodec = Codec as IHasCodecCameras; + if (camerasCodec != null) + { + cameraInfo = new + { + cameraManualSupported = true, // For now, we assume manual mode is supported and selectively hide controls based on camera selection + cameraAutoSupported = Codec is IHasCameraAutoMode, + cameraOffSupported = Codec is IHasCameraOff, + cameraMode = GetCameraMode(), + cameraList = camerasCodec.Cameras, + selectedCamera = GetSelectedCamera(camerasCodec) + }; + } + var info = Codec.CodecInfo; PostStatusMessage(new { @@ -366,8 +520,77 @@ namespace PepperDash.Essentials.AppServer.Messengers hasDirectory = Codec is IHasDirectory, hasDirectorySearch = true, hasRecents = Codec is IHasCallHistory, - hasCameras = Codec is IHasCodecCameras + hasCameras = Codec is IHasCameras, + cameras = cameraInfo, + presets = GetCurrentPresets() }); } + + /// + /// + /// + void PostCameraMode() + { + PostStatusMessage(new + { + cameras = new + { + cameraMode = GetCameraMode() + } + }); + } + + void PostSelectedCamera() + { + var camerasCodec = Codec as IHasCodecCameras; + + PostStatusMessage(new + { + cameras = new + { + selectedCamera = GetSelectedCamera(camerasCodec) + }, + presets = GetCurrentPresets() + }); + } + + void PostCameraPresets() + { + + PostStatusMessage(new + { + presets = GetCurrentPresets() + }); + } + + object GetSelectedCamera(IHasCodecCameras camerasCodec) + { + return new + { + key = camerasCodec.SelectedCameraFeedback.StringValue, + isFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue, + capabilites = new + { + canPan = camerasCodec.SelectedCamera.CanPan, + canTilt = camerasCodec.SelectedCamera.CanTilt, + canZoom = camerasCodec.SelectedCamera.CanZoom, + canFocus = camerasCodec.SelectedCamera.CanFocus + } + }; + } + + List GetCurrentPresets() + { + var presetsCodec = Codec as IHasCodecRoomPresets; + + List currentPresets = null; + + if (presetsCodec != null && Codec is IHasFarEndCameraControl && (Codec as IHasFarEndCameraControl).ControllingFarEndCameraFeedback.BoolValue) + currentPresets = presetsCodec.FarEndRoomPresets; + else + currentPresets = presetsCodec.NearEndPresets; + + return currentPresets; + } } } \ No newline at end of file