diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs new file mode 100644 index 00000000..cf39a95c --- /dev/null +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/ICameraCapabilities.cs @@ -0,0 +1,86 @@ +using Newtonsoft.Json; +using PepperDash.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Interface for camera capabilities + /// + public interface ICameraCapabilities: IKeyName + { + /// + /// Indicates whether the camera can pan + /// + [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] + bool CanPan { get; } + + /// + /// Indicates whether the camera can tilt + /// + [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] + bool CanTilt { get; } + + /// + /// Indicates whether the camera can zoom + /// + [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] + bool CanZoom { get; } + + + /// + /// Indicates whether the camera can focus + /// + [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] + bool CanFocus { get; } + } + + /// + /// Indicates the capabilities of a camera + /// + public class CameraCapabilities : ICameraCapabilities + { + + /// + /// Unique Key + /// + [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)] + public string Key { get; set; } + + /// + /// Isn't it obvious :) + /// + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; set; } + + + /// + /// Indicates whether the camera can pan + /// + [JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)] + public bool CanPan { get; set; } + + /// + /// Indicates whether the camera can tilt + /// + [JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)] + public bool CanTilt { get; set; } + + /// + /// Indicates whether the camera can zoom + /// + [JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)] + public bool CanZoom { get; set; } + + + /// + /// Indicates whether the camera can focus + /// + [JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)] + public bool CanFocus { get; set; } + } +} diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs index f242f4f4..5a5962f8 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCameras.cs @@ -1,4 +1,5 @@ -using PepperDash.Core; +using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Essentials.Core; using System; using System.Collections.Generic; diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs index a842364d..f7aff6d2 100644 --- a/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs +++ b/src/PepperDash.Essentials.Devices.Common/Cameras/Interfaces/IHasCamerasWithControls.cs @@ -13,6 +13,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras /// /// List of cameras on the device. This should be a list of IHasCameraControls objects /// + List Cameras { get; } /// diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs index 7650b430..8c9f0451 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Devices.Common.Cameras; @@ -9,12 +11,12 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// Messenger for a CameraBase device /// - public class CameraBaseMessenger : MessengerBase + public class CameraBaseMessenger : MessengerBase where T : IKeyed { /// /// Gets or sets the Camera /// - public CameraBase Camera { get; set; } + public T Camera { get; set; } /// /// Constructor @@ -22,10 +24,13 @@ namespace PepperDash.Essentials.AppServer.Messengers /// /// /// - public CameraBaseMessenger(string key, CameraBase camera, string messagePath) - : base(key, messagePath, camera) + public CameraBaseMessenger(string key, T camera, string messagePath) + : base(key, messagePath, camera as IKeyName) { - Camera = camera ?? throw new ArgumentNullException("camera"); + if (camera == null) + throw new ArgumentNullException(nameof(camera)); + + Camera = camera; if (Camera is IHasCameraPresets presetsCamera) @@ -178,19 +183,44 @@ namespace PepperDash.Essentials.AppServer.Messengers private void SendCameraFullMessageObject(string id = null) { var presetList = new List(); + CameraCapabilities capabilities = null; if (Camera is IHasCameraPresets presetsCamera) presetList = presetsCamera.Presets; - PostStatusMessage(JToken.FromObject(new + if (Camera is ICameraCapabilities cameraCapabilities) + capabilities = new CameraCapabilities + { + CanPan = cameraCapabilities.CanPan, + CanTilt = cameraCapabilities.CanTilt, + CanZoom = cameraCapabilities.CanZoom, + CanFocus = cameraCapabilities.CanFocus + + }; + + if (Camera is CameraBase cameraBase) + capabilities = new CameraCapabilities + { + CanPan = cameraBase.CanPan, + CanTilt = cameraBase.CanTilt, + CanZoom = cameraBase.CanZoom, + CanFocus = cameraBase.CanFocus + + }; + + var message = new CameraStateMessage { - cameraManualSupported = Camera is IHasCameraControls, - cameraAutoSupported = Camera is IHasCameraAutoMode, - cameraOffSupported = Camera is IHasCameraOff, - cameraMode = GetCameraMode(), - hasPresets = Camera is IHasCameraPresets, - presets = presetList - }), id + CameraManualSupported = Camera is IHasCameraControls, + CameraAutoSupported = Camera is IHasCameraAutoMode, + CameraOffSupported = Camera is IHasCameraOff, + CameraMode = (eCameraControlMode)Enum.Parse(typeof(eCameraControlMode), GetCameraMode(), true), + HasPresets = Camera is IHasCameraPresets, + Presets = presetList, + Capabilities = capabilities, + IsFarEnd = Camera is IAmFarEndCamera + }; + + PostStatusMessage(message, id ); } @@ -210,4 +240,59 @@ namespace PepperDash.Essentials.AppServer.Messengers return m; } } + + /// + /// State message for a camera device + /// + public class CameraStateMessage : DeviceStateMessageBase + { + /// + /// Indicates whether the camera supports manual control + /// + [JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraManualSupported { get; set; } + + /// + /// Indicates whether the camera supports auto control + /// + [JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraAutoSupported { get; set; } + + /// + /// Indicates whether the camera supports off control + /// + [JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)] + public bool CameraOffSupported { get; set; } + + /// + /// Indicates the current camera control mode + /// + [JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public eCameraControlMode CameraMode { get; set; } + + /// + /// Indicates whether the camera has presets + /// + [JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)] + public bool HasPresets { get; set; } + + /// + /// List of presets if the camera supports them + /// + [JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)] + public List Presets { get; set; } + + /// + /// Indicates the capabilities of the camera + /// + [JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)] + public CameraCapabilities Capabilities { get; set; } + + /// + /// Indicates whether the camera is a far end camera + /// + [JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)] + public bool IsFarEnd { get; set; } + } } \ No newline at end of file diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs index d94cc4c4..e8c4a6a0 100644 --- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasWithControlMessenger.cs @@ -1,7 +1,9 @@ using Newtonsoft.Json; +using PepperDash.Core; using PepperDash.Essentials.Devices.Common.Cameras; using System; using System.Collections.Generic; +using System.Linq; namespace PepperDash.Essentials.AppServer.Messengers { @@ -68,14 +70,12 @@ namespace PepperDash.Essentials.AppServer.Messengers { var state = new IHasCamerasWithControlsStateMessage { - CameraList = CameraController.Cameras, - SelectedCamera = CameraController.SelectedCamera + CameraList = CameraController.Cameras.Cast().ToList(), + SelectedCamera = CameraController.SelectedCamera as IKeyName }; PostStatusMessage(state, clientId); } - - } /// @@ -87,13 +87,14 @@ namespace PepperDash.Essentials.AppServer.Messengers /// List of cameras available in the device. /// [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)] - public List CameraList { get; set; } + public List CameraList { get; set; } /// /// The currently selected camera on the device. /// [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)] - public IHasCameraControls SelectedCamera { get; set; } - + public IKeyName SelectedCamera { get; set; } } + + } diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs index a4914c10..d6a40ede 100644 --- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs +++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs @@ -405,14 +405,15 @@ namespace PepperDash.Essentials messengerAdded = true; } - if (device is CameraBase cameraDevice) + // Default to IHasCameraControls if CameraBase and IHasCameraControls + if (device is CameraBase cameraDevice && !(device is IHasCameraControls)) { this.LogVerbose( "Adding CameraBaseMessenger for {deviceKey}", device.Key ); - var cameraMessenger = new CameraBaseMessenger( + var cameraMessenger = new CameraBaseMessenger( $"{device.Key}-cameraBase-{Key}", cameraDevice, $"/device/{device.Key}" @@ -423,6 +424,21 @@ namespace PepperDash.Essentials messengerAdded = true; } + if (device is IHasCameraControls cameraControlDev) + { + this.LogVerbose( + "Adding IHasCamerasWithControlMessenger for {deviceKey}", + device.Key + ); + var cameraControlMessenger = new CameraBaseMessenger( + $"{device.Key}-hasCamerasWithControls-{Key}", + cameraControlDev, + $"/device/{device.Key}" + ); + AddDefaultDeviceMessenger(cameraControlMessenger); + messengerAdded = true; + } + if (device is BlueJeansPc) { this.LogVerbose( @@ -977,7 +993,7 @@ namespace PepperDash.Essentials if (device is IHasCamerasWithControls cameras2) { - this.LogVerbose("Adding IHasCamerasMessenger for {deviceKey}", device.Key + this.LogVerbose("Adding IHasCamerasWithControlsMessenger for {deviceKey}", device.Key ); var messenger = new IHasCamerasWithControlMessenger( $"{device.Key}-cameras-{Key}",