mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-16 05:05:00 +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 PepperDash.Essentials.Core;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of cameras on the device. This should be a list of IHasCameraControls objects
|
/// List of cameras on the device. This should be a list of IHasCameraControls objects
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
List<IHasCameraControls> Cameras { get; }
|
List<IHasCameraControls> Cameras { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
|
|
||||||
@@ -9,12 +11,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Messenger for a CameraBase device
|
/// Messenger for a CameraBase device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CameraBaseMessenger : MessengerBase
|
public class CameraBaseMessenger<T> : MessengerBase where T : IKeyed
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the Camera
|
/// Gets or sets the Camera
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CameraBase Camera { get; set; }
|
public T Camera { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
@@ -22,10 +24,13 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="camera"></param>
|
/// <param name="camera"></param>
|
||||||
/// <param name="messagePath"></param>
|
/// <param name="messagePath"></param>
|
||||||
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
|
public CameraBaseMessenger(string key, T camera, string messagePath)
|
||||||
: base(key, messagePath, camera)
|
: 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)
|
if (Camera is IHasCameraPresets presetsCamera)
|
||||||
@@ -178,19 +183,44 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
private void SendCameraFullMessageObject(string id = null)
|
private void SendCameraFullMessageObject(string id = null)
|
||||||
{
|
{
|
||||||
var presetList = new List<CameraPreset>();
|
var presetList = new List<CameraPreset>();
|
||||||
|
CameraCapabilities capabilities = null;
|
||||||
|
|
||||||
if (Camera is IHasCameraPresets presetsCamera)
|
if (Camera is IHasCameraPresets presetsCamera)
|
||||||
presetList = presetsCamera.Presets;
|
presetList = presetsCamera.Presets;
|
||||||
|
|
||||||
PostStatusMessage(JToken.FromObject(new
|
if (Camera is ICameraCapabilities cameraCapabilities)
|
||||||
|
capabilities = new CameraCapabilities
|
||||||
{
|
{
|
||||||
cameraManualSupported = Camera is IHasCameraControls,
|
CanPan = cameraCapabilities.CanPan,
|
||||||
cameraAutoSupported = Camera is IHasCameraAutoMode,
|
CanTilt = cameraCapabilities.CanTilt,
|
||||||
cameraOffSupported = Camera is IHasCameraOff,
|
CanZoom = cameraCapabilities.CanZoom,
|
||||||
cameraMode = GetCameraMode(),
|
CanFocus = cameraCapabilities.CanFocus
|
||||||
hasPresets = Camera is IHasCameraPresets,
|
|
||||||
presets = presetList
|
};
|
||||||
}), id
|
|
||||||
|
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 = (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;
|
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 Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
@@ -68,14 +70,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
{
|
{
|
||||||
var state = new IHasCamerasWithControlsStateMessage
|
var state = new IHasCamerasWithControlsStateMessage
|
||||||
{
|
{
|
||||||
CameraList = CameraController.Cameras,
|
CameraList = CameraController.Cameras.Cast<IKeyName>().ToList(),
|
||||||
SelectedCamera = CameraController.SelectedCamera
|
SelectedCamera = CameraController.SelectedCamera as IKeyName
|
||||||
};
|
};
|
||||||
|
|
||||||
PostStatusMessage(state, clientId);
|
PostStatusMessage(state, clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -87,13 +87,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
/// List of cameras available in the device.
|
/// List of cameras available in the device.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public List<IHasCameraControls> CameraList { get; set; }
|
public List<IKeyName> CameraList { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The currently selected camera on the device.
|
/// The currently selected camera on the device.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public IHasCameraControls SelectedCamera { get; set; }
|
public IKeyName SelectedCamera { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -405,14 +405,15 @@ namespace PepperDash.Essentials
|
|||||||
messengerAdded = true;
|
messengerAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device is CameraBase cameraDevice)
|
// Default to IHasCameraControls if CameraBase and IHasCameraControls
|
||||||
|
if (device is CameraBase cameraDevice && !(device is IHasCameraControls))
|
||||||
{
|
{
|
||||||
this.LogVerbose(
|
this.LogVerbose(
|
||||||
"Adding CameraBaseMessenger for {deviceKey}",
|
"Adding CameraBaseMessenger for {deviceKey}",
|
||||||
device.Key
|
device.Key
|
||||||
);
|
);
|
||||||
|
|
||||||
var cameraMessenger = new CameraBaseMessenger(
|
var cameraMessenger = new CameraBaseMessenger<CameraBase>(
|
||||||
$"{device.Key}-cameraBase-{Key}",
|
$"{device.Key}-cameraBase-{Key}",
|
||||||
cameraDevice,
|
cameraDevice,
|
||||||
$"/device/{device.Key}"
|
$"/device/{device.Key}"
|
||||||
@@ -423,6 +424,21 @@ namespace PepperDash.Essentials
|
|||||||
messengerAdded = true;
|
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)
|
if (device is BlueJeansPc)
|
||||||
{
|
{
|
||||||
this.LogVerbose(
|
this.LogVerbose(
|
||||||
@@ -977,7 +993,7 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
if (device is IHasCamerasWithControls cameras2)
|
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(
|
var messenger = new IHasCamerasWithControlMessenger(
|
||||||
$"{device.Key}-cameras-{Key}",
|
$"{device.Key}-cameras-{Key}",
|
||||||
|
|||||||
Reference in New Issue
Block a user