diff --git a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs
index cbf53476..883d6ca4 100644
--- a/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs
+++ b/src/PepperDash.Essentials.Devices.Common/Cameras/CameraControl.cs
@@ -3,29 +3,60 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
-
+using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Cameras
{
+ ///
+ /// Enum for camera control modes
+ ///
public enum eCameraControlMode
- {
+ {
+ ///
+ /// Manual control mode, where the camera is controlled directly by the user or system
+ ///
Manual = 0,
+ ///
+ /// Off control mode, where the camera is turned off or disabled
+ ///
Off,
+ ///
+ /// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
+ ///
Auto
}
- public interface IHasCameras
+ ///
+ /// Interface for devices that have cameras
+ ///
+ public interface IHasCameras : IKeyName
{
+ ///
+ /// Event that is raised when a camera is selected
+ ///
event EventHandler CameraSelected;
+ ///
+ /// List of cameras on the device. This should be a list of CameraBase objects
+ ///
List Cameras { get; }
+ ///
+ /// The currently selected camera. This should be a CameraBase object
+ ///
CameraBase SelectedCamera { get; }
+ ///
+ /// Feedback that indicates the currently selected camera
+ ///
StringFeedback SelectedCameraFeedback { get; }
+ ///
+ /// Selects a camera from the list of available cameras based on the provided key.
+ ///
+ /// The unique identifier or name of the camera to select.
void SelectCamera(string key);
}
@@ -42,7 +73,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraOff
{
+ ///
+ /// Feedback that indicates whether the camera is off
+ ///
BoolFeedback CameraIsOffFeedback { get; }
+
+ ///
+ /// Turns the camera off, blanking the near end video
+ ///
void CameraOff();
}
@@ -51,31 +89,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraMute
{
+ ///
+ /// Feedback that indicates whether the camera is muted
+ ///
BoolFeedback CameraIsMutedFeedback { get; }
+
+ ///
+ /// Mutes the camera video, preventing it from being sent to the far end
+ ///
void CameraMuteOn();
+
+ ///
+ /// Unmutes the camera video, allowing it to be sent to the far end
+ ///
void CameraMuteOff();
+
+ ///
+ /// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
+ ///
void CameraMuteToggle();
}
+ ///
+ /// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
+ ///
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
{
+ ///
+ /// Event that is raised when a video unmute is requested, typically by the far end
+ ///
event EventHandler VideoUnmuteRequested;
}
+ ///
+ /// Event arguments for the CameraSelected event
+ ///
public class CameraSelectedEventArgs : EventArgs
{
+ ///
+ /// The selected camera
+ ///
public CameraBase SelectedCamera { get; private set; }
+ ///
+ /// Constructor for CameraSelectedEventArgs
+ ///
+ ///
public CameraSelectedEventArgs(CameraBase camera)
{
SelectedCamera = camera;
}
}
+ ///
+ /// Interface for devices that have a far end camera control
+ ///
public interface IHasFarEndCameraControl
{
+ ///
+ /// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
+ ///
CameraBase FarEndCamera { get; }
+ ///
+ /// Feedback that indicates whether the far end camera is being controlled
+ ///
BoolFeedback ControllingFarEndCameraFeedback { get; }
}
@@ -88,6 +166,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}
+ ///
+ /// Interface for devices that have camera controls
+ ///
public interface IHasCameraControls
{
}
@@ -108,8 +189,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraPanControl : IHasCameraControls
{
+ ///
+ /// Pans the camera left
+ ///
void PanLeft();
+
+ ///
+ /// Pans the camera right
+ ///
void PanRight();
+
+ ///
+ /// Stops the camera pan movement
+ ///
void PanStop();
}
@@ -118,8 +210,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraTiltControl : IHasCameraControls
{
+ ///
+ /// Tilts the camera down
+ ///
void TiltDown();
+
+ ///
+ /// Tilts the camera up
+ ///
void TiltUp();
+
+ ///
+ /// Stops the camera tilt movement
+ ///
void TiltStop();
}
@@ -128,8 +231,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraZoomControl : IHasCameraControls
{
+ ///
+ /// Zooms the camera in
+ ///
void ZoomIn();
+
+ ///
+ /// Zooms the camera out
+ ///
void ZoomOut();
+
+ ///
+ /// Stops the camera zoom movement
+ ///
void ZoomStop();
}
@@ -138,25 +252,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
///
public interface IHasCameraFocusControl : IHasCameraControls
{
+ ///
+ /// Focuses the camera near
+ ///
void FocusNear();
+
+ ///
+ /// Focuses the camera far
+ ///
void FocusFar();
+
+ ///
+ /// Stops the camera focus movement
+ ///
void FocusStop();
+ ///
+ /// Triggers the camera's auto focus functionality, if available.
+ ///
void TriggerAutoFocus();
}
+ ///
+ /// Interface for devices that have auto focus mode control
+ ///
public interface IHasAutoFocusMode
{
+ ///
+ /// Sets the focus mode to auto or manual, or toggles between them.
+ ///
void SetFocusModeAuto();
+
+ ///
+ /// Sets the focus mode to manual, allowing for manual focus adjustments.
+ ///
void SetFocusModeManual();
+
+ ///
+ /// Toggles the focus mode between auto and manual.
+ ///
void ToggleFocusMode();
}
+ ///
+ /// Interface for devices that have camera auto mode control
+ ///
public interface IHasCameraAutoMode : IHasCameraControls
{
+ ///
+ /// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
+ ///
void CameraAutoModeOn();
+
+ ///
+ /// Disables the camera's auto mode, allowing for manual control of camera settings.
+ ///
void CameraAutoModeOff();
+
+ ///
+ /// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
+ ///
void CameraAutoModeToggle();
+
+ ///
+ /// Feedback that indicates whether the camera's auto mode is currently enabled.
+ ///
BoolFeedback CameraAutoModeIsOnFeedback { get; }
}
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs
index 36a94781..dd67a6fe 100644
--- a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs
@@ -6,11 +6,14 @@ using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
+ ///
+ /// Messenger for a CameraBase device
+ ///
public class CameraBaseMessenger : MessengerBase
{
///
/// Device being bridged
- ///
+ ///
public CameraBase Camera { get; set; }
///
@@ -45,6 +48,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
);
}
+ ///
+ /// Registers the actions for this messenger. This is called by the base class
+ ///
protected override void RegisterActions()
{
base.RegisterActions();
diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs
new file mode 100644
index 00000000..4fa0c5b1
--- /dev/null
+++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasCamerasMessenger.cs
@@ -0,0 +1,104 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Messenger for devices that implement the IHasCameras interface.
+ ///
+ public class IHasCamerasMessenger : MessengerBase
+ {
+ ///
+ /// Device being bridged that implements IHasCameras interface.
+ ///
+ public IHasCameras CameraController { get; private set; }
+
+ ///
+ /// Messenger for devices that implement IHasCameras interface.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IHasCamerasMessenger(string key, string messagePath , IHasCameras cameraController)
+ : base(key, messagePath, cameraController)
+ {
+ CameraController = cameraController ?? throw new ArgumentNullException("cameraController");
+ CameraController.CameraSelected += CameraController_CameraSelected;
+ }
+
+ private void CameraController_CameraSelected(object sender, CameraSelectedEventArgs e)
+ {
+ PostStatusMessage(new IHasCamerasStateMessage
+ {
+ SelectedCamera = e.SelectedCamera
+ });
+ }
+
+ ///
+ /// Registers the actions for this messenger.
+ ///
+ ///
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, context) =>
+ {
+ SendFullStatus(id);
+ });
+
+ AddAction("/selectCamera", (id, content) =>
+ {
+ var cameraKey = content?.ToObject();
+
+ if (!string.IsNullOrEmpty(cameraKey))
+ {
+ CameraController.SelectCamera(cameraKey);
+ }
+ else
+ {
+ throw new ArgumentException("Content must be a string representing the camera key");
+ }
+ });
+ }
+
+ private void SendFullStatus(string clientId)
+ {
+ var state = new IHasCamerasStateMessage
+ {
+ CameraList = CameraController.Cameras,
+ SelectedCamera = CameraController.SelectedCamera
+ };
+
+ PostStatusMessage(state, clientId);
+ }
+
+
+ }
+
+ ///
+ /// State message for devices that implement the IHasCameras interface.
+ ///
+ public class IHasCamerasStateMessage : DeviceStateMessageBase
+ {
+ ///
+ /// List of cameras available in the device.
+ ///
+ [JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
+ public List CameraList { get; set; }
+
+ ///
+ /// The currently selected camera on the device.
+ ///
+ [JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
+ public CameraBase SelectedCamera { get; set; }
+
+ }
+}
diff --git a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs
index b17e0490..9d2eaf96 100644
--- a/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs
+++ b/src/PepperDash.Essentials.MobileControl/MobileControlSystemController.cs
@@ -907,6 +907,19 @@ namespace PepperDash.Essentials
messengerAdded = true;
}
+ if (device is IHasCameras cameras)
+ {
+ this.LogVerbose("Adding IHasCamerasMessenger for {deviceKey}", device.Key
+ );
+ var messenger = new IHasCamerasMessenger(
+ $"{device.Key}-cameras-{Key}",
+ $"/device/{device.Key}",
+ cameras
+ );
+ AddDefaultDeviceMessenger(messenger);
+ messengerAdded = true;
+ }
+
this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
if (device is EssentialsDevice)