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; }