mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-11 19:44:52 +00:00
feat: Enhance camera capabilities and messaging structure
- Introduced `ICameraCapabilities` interface and `CameraCapabilities` class for defining camera features like pan, tilt, zoom, and focus. - Modified `IHasCameras` interface to include a list of `IHasCameraControls` objects for improved camera management. - Refactored `CameraBaseMessenger` to be generic, enhancing flexibility and type safety. - Updated `SendCameraFullMessageObject` to include detailed camera capabilities in status messages. - Added `CameraStateMessage` class to encapsulate camera state, including control support and capabilities. - Updated `IHasCamerasWithControlMessenger` to use `IKeyName` for camera list and selected camera properties, improving type consistency. - Enhanced `MobileControlSystemController` to manage devices implementing `IHasCameraControls`, creating appropriate messengers for different device types.
This commit is contained in:
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for camera capabilities
|
||||
/// </summary>
|
||||
public interface ICameraCapabilities: IKeyName
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can pan
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanPan { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can tilt
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanTilt { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can zoom
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanZoom { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can focus
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
bool CanFocus { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the capabilities of a camera
|
||||
/// </summary>
|
||||
public class CameraCapabilities : ICameraCapabilities
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Unique Key
|
||||
/// </summary>
|
||||
[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Isn't it obvious :)
|
||||
/// </summary>
|
||||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can pan
|
||||
/// </summary>
|
||||
[JsonProperty("canPan", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanPan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can tilt
|
||||
/// </summary>
|
||||
[JsonProperty("canTilt", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanTilt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can zoom
|
||||
/// </summary>
|
||||
[JsonProperty("canZoom", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanZoom { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera can focus
|
||||
/// </summary>
|
||||
[JsonProperty("canFocus", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CanFocus { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
/// <summary>
|
||||
/// List of cameras on the device. This should be a list of IHasCameraControls objects
|
||||
/// </summary>
|
||||
|
||||
List<IHasCameraControls> Cameras { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Messenger for a CameraBase device
|
||||
/// </summary>
|
||||
public class CameraBaseMessenger : MessengerBase
|
||||
public class CameraBaseMessenger<T> : MessengerBase where T : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Camera
|
||||
/// </summary>
|
||||
public CameraBase Camera { get; set; }
|
||||
public T Camera { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -22,10 +24,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// <param name="key"></param>
|
||||
/// <param name="camera"></param>
|
||||
/// <param name="messagePath"></param>
|
||||
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<CameraPreset>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State message for a camera device
|
||||
/// </summary>
|
||||
public class CameraStateMessage : DeviceStateMessageBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether the camera supports manual control
|
||||
/// </summary>
|
||||
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CameraManualSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera supports auto control
|
||||
/// </summary>
|
||||
[JsonProperty("cameraAutoSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CameraAutoSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera supports off control
|
||||
/// </summary>
|
||||
[JsonProperty("cameraOffSupported", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool CameraOffSupported { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the current camera control mode
|
||||
/// </summary>
|
||||
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
|
||||
public eCameraControlMode CameraMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera has presets
|
||||
/// </summary>
|
||||
[JsonProperty("hasPresets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool HasPresets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of presets if the camera supports them
|
||||
/// </summary>
|
||||
[JsonProperty("presets", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<CameraPreset> Presets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the capabilities of the camera
|
||||
/// </summary>
|
||||
[JsonProperty("capabilities", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CameraCapabilities Capabilities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the camera is a far end camera
|
||||
/// </summary>
|
||||
[JsonProperty("isFarEnd", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool IsFarEnd { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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<IKeyName>().ToList(),
|
||||
SelectedCamera = CameraController.SelectedCamera as IKeyName
|
||||
};
|
||||
|
||||
PostStatusMessage(state, clientId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -87,13 +87,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||
/// List of cameras available in the device.
|
||||
/// </summary>
|
||||
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<IHasCameraControls> CameraList { get; set; }
|
||||
public List<IKeyName> CameraList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected camera on the device.
|
||||
/// </summary>
|
||||
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public IHasCameraControls SelectedCamera { get; set; }
|
||||
|
||||
public IKeyName SelectedCamera { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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<CameraBase>(
|
||||
$"{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<IHasCameraControls>(
|
||||
$"{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}",
|
||||
|
||||
Reference in New Issue
Block a user