using Ayay.SerilogLogs;
using Newtonsoft.Json.Linq;
using Serilog;
using SHH.CameraSdk;
using SHH.Contracts;
namespace SHH.CameraService;
///
/// 预置点控制指令处理器
/// 响应 gRpc 指令:ProtocolCodes.Preset_Control
///
public class PresetControlHandler : ICommandHandler
{
private readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);
private readonly CameraManager _cameraManager;
/// 指令名称(需与网关下发的 CmdCode 一致)
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();
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} 预置点操作失败");
}
}
}
/// PresetControlDto 参数
public class PresetControlDto
{
/// 设备ID
public int DeviceId { get; set; }
/// 预置点编号 (1-255)
public int PresetIndex { get; set; }
/// 动作:GOTO, SET, REMOVE
public string Action { get; set; } = string.Empty;
}