Files
Ayay/SHH.CameraService/GrpcImpls/Handlers/PresetControlHandler.cs
2026-03-03 13:55:37 +08:00

97 lines
3.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Ayay.SerilogLogs;
using Newtonsoft.Json.Linq;
using Serilog;
using SHH.CameraSdk;
using SHH.Contracts;
namespace SHH.CameraService;
/// <summary>
/// 预置点控制指令处理器
/// 响应 gRpc 指令ProtocolCodes.Preset_Control
/// </summary>
public class PresetControlHandler : ICommandHandler
{
private readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);
private readonly CameraManager _cameraManager;
/// <summary>指令名称(需与网关下发的 CmdCode 一致)</summary>
public string ActionName => ProtocolCodes.Device_Preset;
public PresetControlHandler(CameraManager cameraManager)
{
_cameraManager = cameraManager ?? throw new ArgumentNullException(nameof(cameraManager));
}
public async Task ExecuteAsync(JToken payload)
{
// 1. 解析预置点控制参数
// 假设 PresetControlDto 包含 DeviceId, PresetIndex, 和 Action (GOTO/SET/REMOVE)
var presetDto = payload.ToObject<PresetControlDto>();
if (presetDto == null || presetDto.DeviceId <= 0)
{
_sysLog.Warning("[Preset] 无效指令参数缺失或设备ID非法");
return;
}
// 2. 获取目标设备并校验能力
var device = _cameraManager.GetDevice(presetDto.DeviceId);
if (device == null)
{
_sysLog.Warning($"[Preset] 设备 {presetDto.DeviceId} 不存在");
return;
}
if (!device.IsPhysicalOnline)
{
_sysLog.Warning($"[Preset] 设备 {presetDto.DeviceId} 未在线,无法执行预置点控制");
return;
}
// Optimized: [原因] 检查设备是否实现了预置点功能接口
if (!(device is IPresetFeature presetFeature))
{
_sysLog.Warning($"[Preset] 设备 {presetDto.DeviceId} ({device.Config.Name}) 不支持预置点功能");
return;
}
// 3. 分发执行逻辑
try
{
switch (presetDto.Action.ToUpper())
{
case "GOTO":
await presetFeature.GotoPresetAsync(presetDto.PresetIndex);
_sysLog.Information($"[Preset] 设备 {presetDto.DeviceId} 跳转至预置点: {presetDto.PresetIndex}");
break;
case "SET":
await presetFeature.SetPresetAsync(presetDto.PresetIndex);
_sysLog.Information($"[Preset] 设备 {presetDto.DeviceId} 设置当前位置为预置点: {presetDto.PresetIndex}");
break;
case "REMOVE":
await presetFeature.RemovePresetAsync(presetDto.PresetIndex);
_sysLog.Information($"[Preset] 设备 {presetDto.DeviceId} 删除预置点: {presetDto.PresetIndex}");
break;
default:
_sysLog.Warning($"[Preset] 未知操作类型: {presetDto.Action}");
break;
}
}
catch (Exception ex)
{
_sysLog.Error(ex, $"[Preset] 设备 {presetDto.DeviceId} 预置点操作失败");
}
}
}
/// <summary>PresetControlDto 参数</summary>
public class PresetControlDto
{
/// <summary>设备ID</summary>
public int DeviceId { get; set; }
/// <summary>预置点编号 (1-255)</summary>
public int PresetIndex { get; set; }
/// <summary>动作GOTO, SET, REMOVE</summary>
public string Action { get; set; } = string.Empty;
}