mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 20:54:55 +00:00
Merge pull request #1296 from PepperDash/feature/add-IHasCamerasMessenger
This commit is contained in:
@@ -3,29 +3,60 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Cameras
|
namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enum for camera control modes
|
||||||
|
/// </summary>
|
||||||
public enum eCameraControlMode
|
public enum eCameraControlMode
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manual control mode, where the camera is controlled directly by the user or system
|
||||||
|
/// </summary>
|
||||||
Manual = 0,
|
Manual = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Off control mode, where the camera is turned off or disabled
|
||||||
|
/// </summary>
|
||||||
Off,
|
Off,
|
||||||
|
/// <summary>
|
||||||
|
/// Auto control mode, where the camera automatically adjusts settings based on the environment or conditions
|
||||||
|
/// </summary>
|
||||||
Auto
|
Auto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface IHasCameras
|
/// <summary>
|
||||||
|
/// Interface for devices that have cameras
|
||||||
|
/// </summary>
|
||||||
|
public interface IHasCameras : IKeyName
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a camera is selected
|
||||||
|
/// </summary>
|
||||||
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
event EventHandler<CameraSelectedEventArgs> CameraSelected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of cameras on the device. This should be a list of CameraBase objects
|
||||||
|
/// </summary>
|
||||||
List<CameraBase> Cameras { get; }
|
List<CameraBase> Cameras { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently selected camera. This should be a CameraBase object
|
||||||
|
/// </summary>
|
||||||
CameraBase SelectedCamera { get; }
|
CameraBase SelectedCamera { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates the currently selected camera
|
||||||
|
/// </summary>
|
||||||
StringFeedback SelectedCameraFeedback { get; }
|
StringFeedback SelectedCameraFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects a camera from the list of available cameras based on the provided key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The unique identifier or name of the camera to select.</param>
|
||||||
void SelectCamera(string key);
|
void SelectCamera(string key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +73,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraOff
|
public interface IHasCameraOff
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera is off
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraIsOffFeedback { get; }
|
BoolFeedback CameraIsOffFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turns the camera off, blanking the near end video
|
||||||
|
/// </summary>
|
||||||
void CameraOff();
|
void CameraOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,31 +89,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraMute
|
public interface IHasCameraMute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera is muted
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraIsMutedFeedback { get; }
|
BoolFeedback CameraIsMutedFeedback { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mutes the camera video, preventing it from being sent to the far end
|
||||||
|
/// </summary>
|
||||||
void CameraMuteOn();
|
void CameraMuteOn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unmutes the camera video, allowing it to be sent to the far end
|
||||||
|
/// </summary>
|
||||||
void CameraMuteOff();
|
void CameraMuteOff();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the camera mute state. If the camera is muted, it will be unmuted, and vice versa.
|
||||||
|
/// </summary>
|
||||||
void CameraMuteToggle();
|
void CameraMuteToggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that can mute and unmute their camera video, with an event for unmute requests
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
public interface IHasCameraMuteWithUnmuteReqeust : IHasCameraMute
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is raised when a video unmute is requested, typically by the far end
|
||||||
|
/// </summary>
|
||||||
event EventHandler VideoUnmuteRequested;
|
event EventHandler VideoUnmuteRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event arguments for the CameraSelected event
|
||||||
|
/// </summary>
|
||||||
public class CameraSelectedEventArgs : EventArgs
|
public class CameraSelectedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The selected camera
|
||||||
|
/// </summary>
|
||||||
public CameraBase SelectedCamera { get; private set; }
|
public CameraBase SelectedCamera { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for CameraSelectedEventArgs
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="camera"></param>
|
||||||
public CameraSelectedEventArgs(CameraBase camera)
|
public CameraSelectedEventArgs(CameraBase camera)
|
||||||
{
|
{
|
||||||
SelectedCamera = camera;
|
SelectedCamera = camera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have a far end camera control
|
||||||
|
/// </summary>
|
||||||
public interface IHasFarEndCameraControl
|
public interface IHasFarEndCameraControl
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the far end camera, which is typically a CameraBase object that represents the camera at the far end of a call
|
||||||
|
/// </summary>
|
||||||
CameraBase FarEndCamera { get; }
|
CameraBase FarEndCamera { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the far end camera is being controlled
|
||||||
|
/// </summary>
|
||||||
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
BoolFeedback ControllingFarEndCameraFeedback { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -88,6 +166,9 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have camera controls
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraControls
|
public interface IHasCameraControls
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -108,8 +189,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraPanControl : IHasCameraControls
|
public interface IHasCameraPanControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pans the camera left
|
||||||
|
/// </summary>
|
||||||
void PanLeft();
|
void PanLeft();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pans the camera right
|
||||||
|
/// </summary>
|
||||||
void PanRight();
|
void PanRight();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera pan movement
|
||||||
|
/// </summary>
|
||||||
void PanStop();
|
void PanStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,8 +210,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraTiltControl : IHasCameraControls
|
public interface IHasCameraTiltControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tilts the camera down
|
||||||
|
/// </summary>
|
||||||
void TiltDown();
|
void TiltDown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tilts the camera up
|
||||||
|
/// </summary>
|
||||||
void TiltUp();
|
void TiltUp();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera tilt movement
|
||||||
|
/// </summary>
|
||||||
void TiltStop();
|
void TiltStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +231,19 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraZoomControl : IHasCameraControls
|
public interface IHasCameraZoomControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Zooms the camera in
|
||||||
|
/// </summary>
|
||||||
void ZoomIn();
|
void ZoomIn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Zooms the camera out
|
||||||
|
/// </summary>
|
||||||
void ZoomOut();
|
void ZoomOut();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera zoom movement
|
||||||
|
/// </summary>
|
||||||
void ZoomStop();
|
void ZoomStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,25 +252,71 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasCameraFocusControl : IHasCameraControls
|
public interface IHasCameraFocusControl : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Focuses the camera near
|
||||||
|
/// </summary>
|
||||||
void FocusNear();
|
void FocusNear();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Focuses the camera far
|
||||||
|
/// </summary>
|
||||||
void FocusFar();
|
void FocusFar();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the camera focus movement
|
||||||
|
/// </summary>
|
||||||
void FocusStop();
|
void FocusStop();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers the camera's auto focus functionality, if available.
|
||||||
|
/// </summary>
|
||||||
void TriggerAutoFocus();
|
void TriggerAutoFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have auto focus mode control
|
||||||
|
/// </summary>
|
||||||
public interface IHasAutoFocusMode
|
public interface IHasAutoFocusMode
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus mode to auto or manual, or toggles between them.
|
||||||
|
/// </summary>
|
||||||
void SetFocusModeAuto();
|
void SetFocusModeAuto();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus mode to manual, allowing for manual focus adjustments.
|
||||||
|
/// </summary>
|
||||||
void SetFocusModeManual();
|
void SetFocusModeManual();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the focus mode between auto and manual.
|
||||||
|
/// </summary>
|
||||||
void ToggleFocusMode();
|
void ToggleFocusMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for devices that have camera auto mode control
|
||||||
|
/// </summary>
|
||||||
public interface IHasCameraAutoMode : IHasCameraControls
|
public interface IHasCameraAutoMode : IHasCameraControls
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables the camera's auto mode, which may include automatic adjustments for focus, exposure, and other settings.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeOn();
|
void CameraAutoModeOn();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the camera's auto mode, allowing for manual control of camera settings.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeOff();
|
void CameraAutoModeOff();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the camera's auto mode state. If the camera is in auto mode, it will switch to manual mode, and vice versa.
|
||||||
|
/// </summary>
|
||||||
void CameraAutoModeToggle();
|
void CameraAutoModeToggle();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Feedback that indicates whether the camera's auto mode is currently enabled.
|
||||||
|
/// </summary>
|
||||||
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
BoolFeedback CameraAutoModeIsOnFeedback { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.AppServer.Messengers
|
namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for a CameraBase device
|
||||||
|
/// </summary>
|
||||||
public class CameraBaseMessenger : MessengerBase
|
public class CameraBaseMessenger : MessengerBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -45,6 +48,9 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers the actions for this messenger. This is called by the base class
|
||||||
|
/// </summary>
|
||||||
protected override void RegisterActions()
|
protected override void RegisterActions()
|
||||||
{
|
{
|
||||||
base.RegisterActions();
|
base.RegisterActions();
|
||||||
|
|||||||
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for devices that implement the IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public class IHasCamerasMessenger : MessengerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Device being bridged that implements IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public IHasCameras CameraController { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Messenger for devices that implement IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="cameraController"></param>
|
||||||
|
/// <param name="messagePath"></param>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers the actions for this messenger.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentException"></exception>
|
||||||
|
protected override void RegisterActions()
|
||||||
|
{
|
||||||
|
base.RegisterActions();
|
||||||
|
|
||||||
|
AddAction("/fullStatus", (id, context) =>
|
||||||
|
{
|
||||||
|
SendFullStatus(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAction("/selectCamera", (id, content) =>
|
||||||
|
{
|
||||||
|
var cameraKey = content?.ToObject<string>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State message for devices that implement the IHasCameras interface.
|
||||||
|
/// </summary>
|
||||||
|
public class IHasCamerasStateMessage : DeviceStateMessageBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of cameras available in the device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("cameraList", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public List<CameraBase> CameraList { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently selected camera on the device.
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("selectedCamera", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public CameraBase SelectedCamera { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -907,6 +907,19 @@ namespace PepperDash.Essentials
|
|||||||
messengerAdded = true;
|
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);
|
this.LogVerbose("Trying to cast to generic device for device: {key}", device.Key);
|
||||||
|
|
||||||
if (device is EssentialsDevice)
|
if (device is EssentialsDevice)
|
||||||
|
|||||||
Reference in New Issue
Block a user