Files
Essentials/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/CameraBaseMessenger.cs
Andrew Welker 9c9eaea928 feat: unique status requests for messengers
UI Applications can now request status for specific feature sets instead of full status for a device. This will hopefully cut down on the traffic and messages required to get the data for the UI.
2025-09-23 10:55:16 -05:00

213 lines
7.0 KiB
C#

using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Messenger for a CameraBase device
/// </summary>
public class CameraBaseMessenger : MessengerBase
{
/// <summary>
/// Gets or sets the Camera
/// </summary>
public CameraBase Camera { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="camera"></param>
/// <param name="messagePath"></param>
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
: base(key, messagePath, camera)
{
Camera = camera ?? throw new ArgumentNullException("camera");
if (Camera is IHasCameraPresets presetsCamera)
{
presetsCamera.PresetsListHasChanged += PresetsCamera_PresetsListHasChanged;
}
}
private void PresetsCamera_PresetsListHasChanged(object sender, EventArgs e)
{
var presetList = new List<CameraPreset>();
if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets;
PostStatusMessage(JToken.FromObject(new
{
presets = presetList
})
);
}
/// <summary>
/// Registers the actions for this messenger. This is called by the base class
/// </summary>
protected override void RegisterActions()
{
base.RegisterActions();
AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject(id));
AddAction("/cameraStatus", (id, content) => SendCameraFullMessageObject(id));
if (Camera is IHasCameraPtzControl ptzCamera)
{
// Need to evaluate how to pass through these P&H actions. Need a method that takes a bool maybe?
AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.TiltUp();
return;
}
ptzCamera.TiltStop();
}));
AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.TiltDown();
return;
}
ptzCamera.TiltStop();
}));
AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.PanLeft();
return;
}
ptzCamera.PanStop();
}));
AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.PanRight();
return;
}
ptzCamera.PanStop();
}));
AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.ZoomIn();
return;
}
ptzCamera.ZoomStop();
}));
AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
{
ptzCamera.ZoomOut();
return;
}
ptzCamera.ZoomStop();
}));
}
if (Camera is IHasCameraAutoMode)
{
AddAction("/cameraModeAuto", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOn());
AddAction("/cameraModeManual", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOff());
}
if (Camera is IHasPowerControl)
{
AddAction("/cameraModeOff", (id, content) => (Camera as IHasPowerControl).PowerOff());
AddAction("/cameraModeManual", (id, content) => (Camera as IHasPowerControl).PowerOn());
}
if (Camera is IHasCameraPresets presetsCamera)
{
AddAction("/recallPreset", (id, content) =>
{
var msg = content.ToObject<MobileControlSimpleContent<int>>();
presetsCamera.PresetSelect(msg.Value);
});
AddAction("/storePreset", (id, content) =>
{
var msg = content.ToObject<MobileControlSimpleContent<int>>();
presetsCamera.PresetStore(msg.Value, string.Empty);
});
}
}
private void HandleCameraPressAndHold(JToken content, Action<bool> cameraAction)
{
var state = content.ToObject<MobileControlSimpleContent<string>>();
var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
if (timerHandler == null)
{
return;
}
timerHandler(Camera.Key, cameraAction);
}
/// <summary>
/// Helper method to update the full status of the camera
/// </summary>
private void SendCameraFullMessageObject(string id = null)
{
var presetList = new List<CameraPreset>();
if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets;
PostStatusMessage(JToken.FromObject(new
{
cameraManualSupported = Camera is IHasCameraControls,
cameraAutoSupported = Camera is IHasCameraAutoMode,
cameraOffSupported = Camera is IHasCameraOff,
cameraMode = GetCameraMode(),
hasPresets = Camera is IHasCameraPresets,
presets = presetList
}), id
);
}
/// <summary>
/// Computes the current camera mode
/// </summary>
/// <returns></returns>
private string GetCameraMode()
{
string m;
if (Camera is IHasCameraAutoMode && (Camera as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.BoolValue)
m = eCameraControlMode.Auto.ToString().ToLower();
else if (Camera is IHasPowerControlWithFeedback && !(Camera as IHasPowerControlWithFeedback).PowerIsOnFeedback.BoolValue)
m = eCameraControlMode.Off.ToString().ToLower();
else
m = eCameraControlMode.Manual.ToString().ToLower();
return m;
}
}
}