Files
Ayay/SHH.CameraService/GrpcImpls/Handlers/PtzControlHandler.cs

77 lines
2.9 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.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} 控制失败");
}
}
}