77 lines
2.9 KiB
C#
77 lines
2.9 KiB
C#
|
|
using Ayay.SerilogLogs;
|
|||
|
|
using Newtonsoft.Json.Linq;
|
|||
|
|
using Serilog;
|
|||
|
|
using SHH.CameraSdk;
|
|||
|
|
using SHH.Contracts;
|
|||
|
|
|
|||
|
|
namespace SHH.CameraService;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 云台控制指令处理器
|
|||
|
|
/// 响应 gRpc 指令:ProtocolCodes.Control_Ptz
|
|||
|
|
/// </summary>
|
|||
|
|
public class PtzControlHandler : ICommandHandler
|
|||
|
|
{
|
|||
|
|
private readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);
|
|||
|
|
private readonly CameraManager _cameraManager;
|
|||
|
|
|
|||
|
|
/// <summary>指令名称(需与网关下发的 CmdCode 一致)</summary>
|
|||
|
|
public string ActionName => ProtocolCodes.Ptz_Control; // 需在 ProtocolCodes 中新增该常量
|
|||
|
|
|
|||
|
|
public PtzControlHandler(CameraManager cameraManager)
|
|||
|
|
{
|
|||
|
|
_cameraManager = cameraManager ?? throw new ArgumentNullException(nameof(cameraManager));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task ExecuteAsync(JToken payload)
|
|||
|
|
{
|
|||
|
|
// 1. 解析 PTZ 控制参数(与网关下发的 JSON 结构匹配)
|
|||
|
|
var ptzDto = payload.ToObject<PtzControlDto>();
|
|||
|
|
if (ptzDto == null || ptzDto.DeviceId <= 0)
|
|||
|
|
{
|
|||
|
|
_sysLog.Warning("[PTZ] 无效指令:参数缺失或设备ID非法");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 2. 获取目标设备并校验能力
|
|||
|
|
var device = _cameraManager.GetDevice(ptzDto.DeviceId);
|
|||
|
|
if (device == null)
|
|||
|
|
{
|
|||
|
|
_sysLog.Warning($"[PTZ] 设备 {ptzDto.DeviceId} 不存在");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!device.IsPhysicalOnline)
|
|||
|
|
{
|
|||
|
|
_sysLog.Warning($"[PTZ] 设备 {ptzDto.DeviceId} 未在线,无法执行云台控制");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (!(device is IPtzFeature ptzFeature))
|
|||
|
|
{
|
|||
|
|
_sysLog.Warning($"[PTZ] 设备 {ptzDto.DeviceId} 不支持云台控制");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. 执行云台控制(根据指令类型选择手动/点动模式)
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
if (ptzDto.Duration > 0)
|
|||
|
|
{
|
|||
|
|
// 点动模式:自动复位(如持续300ms向上转动)
|
|||
|
|
int safeDuration = Math.Clamp(ptzDto.Duration, 50, 2000); // 限制单次最长2秒
|
|||
|
|
await ptzFeature.PtzStepAsync(ptzDto.Action, safeDuration, ptzDto.Speed);
|
|||
|
|
_sysLog.Information($"[PTZ] 设备 {ptzDto.DeviceId} 点动控制:{ptzDto.Action},时长 {safeDuration}ms,速度 {ptzDto.Speed}");
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 手动模式:按下/松开(如按住向上、松开停止)
|
|||
|
|
await ptzFeature.PtzControlAsync(ptzDto.Action, ptzDto.Stop, ptzDto.Speed);
|
|||
|
|
string actionDesc = ptzDto.Stop ? "停止" : "启动";
|
|||
|
|
_sysLog.Information($"[PTZ] 设备 {ptzDto.DeviceId} 手动控制:{ptzDto.Action} {actionDesc},速度 {ptzDto.Speed}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
_sysLog.Error(ex, $"[PTZ] 设备 {ptzDto.DeviceId} 控制失败");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|