using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Cameras; namespace PepperDash.Essentials.AppServer.Messengers { /// /// Messenger for a CameraBase device /// public class CameraBaseMessenger : MessengerBase { /// /// Gets or sets the Camera /// public CameraBase Camera { get; set; } /// /// Constructor /// /// /// /// public CameraBaseMessenger(string key, CameraBase camera, string messagePath) : base(key, messagePath, camera) { Camera = camera ?? throw new ArgumentNullException("camera"); if (Camera is IHasCameraPresets presetsCamera) { presetsCamera.PresetsListHasChanged += PresetsCamera_PresetsListHasChanged; } } private void PresetsCamera_PresetsListHasChanged(object sender, EventArgs e) { var presetList = new List(); if (Camera is IHasCameraPresets presetsCamera) presetList = presetsCamera.Presets; PostStatusMessage(JToken.FromObject(new { presets = presetList }) ); } /// /// Registers the actions for this messenger. This is called by the base class /// protected override void RegisterActions() { base.RegisterActions(); AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id)); AddAction("/cameraStatus", (id, content) => SendCameraFullMessageObject(id)); if (Camera is IHasCameraPtzControl ptzCamera) { // Need to evaluate how to pass through these P&H actions. Need a method that takes a bool maybe? AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.TiltUp(); return; } ptzCamera.TiltStop(); })); AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.TiltDown(); return; } ptzCamera.TiltStop(); })); AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.PanLeft(); return; } ptzCamera.PanStop(); })); AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.PanRight(); return; } ptzCamera.PanStop(); })); AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.ZoomIn(); return; } ptzCamera.ZoomStop(); })); AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) => { if (b) { ptzCamera.ZoomOut(); return; } ptzCamera.ZoomStop(); })); } if (Camera is IHasCameraAutoMode) { AddAction("/cameraModeAuto", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOn()); AddAction("/cameraModeManual", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOff()); } if (Camera is IHasPowerControl) { AddAction("/cameraModeOff", (id, content) => (Camera as IHasPowerControl).PowerOff()); AddAction("/cameraModeManual", (id, content) => (Camera as IHasPowerControl).PowerOn()); } if (Camera is IHasCameraPresets presetsCamera) { AddAction("/recallPreset", (id, content) => { var msg = content.ToObject>(); presetsCamera.PresetSelect(msg.Value); }); AddAction("/storePreset", (id, content) => { var msg = content.ToObject>(); presetsCamera.PresetStore(msg.Value, string.Empty); }); } } private void HandleCameraPressAndHold(JToken content, Action cameraAction) { var state = content.ToObject>(); var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value); if (timerHandler == null) { return; } timerHandler(Camera.Key, cameraAction); } /// /// Helper method to update the full status of the camera /// private void SendCameraFullMessageObject(string id = null) { var presetList = new List(); if (Camera is IHasCameraPresets presetsCamera) presetList = presetsCamera.Presets; PostStatusMessage(JToken.FromObject(new { cameraManualSupported = Camera is IHasCameraControls, cameraAutoSupported = Camera is IHasCameraAutoMode, cameraOffSupported = Camera is IHasCameraOff, cameraMode = GetCameraMode(), hasPresets = Camera is IHasCameraPresets, presets = presetList }), id ); } /// /// Computes the current camera mode /// /// private string GetCameraMode() { string m; if (Camera is IHasCameraAutoMode && (Camera as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.BoolValue) m = eCameraControlMode.Auto.ToString().ToLower(); else if (Camera is IHasPowerControlWithFeedback && !(Camera as IHasPowerControlWithFeedback).PowerIsOnFeedback.BoolValue) m = eCameraControlMode.Off.ToString().ToLower(); else m = eCameraControlMode.Manual.ToString().ToLower(); return m; } } }