增加大华设备对云台移动、缩放、聚集、光圈、校时、重启的支持

增加海康、大华对预置点的支持
This commit is contained in:
2026-03-03 13:55:37 +08:00
parent 0399871467
commit d1fc94be1c
15 changed files with 683 additions and 65 deletions

View File

@@ -0,0 +1,81 @@
using Serilog;
using Ayay.SerilogLogs;
namespace SHH.CameraSdk.HikFeatures;
/// <summary>
/// [海康功能组件] 预置点管理实现
/// <para>适配说明:使用 NET_DVR_PTZPreset_Other 接口</para>
/// </summary>
public class HikPresetProvider : IPresetFeature
{
private readonly IHikContext _context;
#region --- PTZ ---
private const uint SET_PRESET = 8; // 设置预置点
private const uint CLE_PRESET = 9; // 清除预置点
private const uint GOTO_PRESET = 39; // 转到预置点
#endregion
public HikPresetProvider(IHikContext context)
{
_context = context;
}
/// <summary>跳转到指定预置点</summary>
public async Task GotoPresetAsync(int presetIndex)
{
await ExecutePresetAction(presetIndex, GOTO_PRESET, "调用");
}
/// <summary>将当前位置保存为预置点</summary>
public async Task SetPresetAsync(int presetIndex)
{
await ExecutePresetAction(presetIndex, SET_PRESET, "保存");
}
/// <summary>删除指定的预置点</summary>
public async Task RemovePresetAsync(int presetIndex)
{
await ExecutePresetAction(presetIndex, CLE_PRESET, "删除");
}
/// <summary>统一执行海康预置点 SDK 调用</summary>
private async Task ExecutePresetAction(int index, uint command, string actionName)
{
int userId = _context.GetUserId();
if (userId < 0) return;
// 位置是从 1 开始, 调用 0 会导致设备重启
if (index == 0) return;
// 海康工业相机通道号通常为 1
int channel = 1;
await Task.Run(() =>
{
// Optimized: [原因] 使用 _Other 接口确保在单机多路并发下通道句柄准确
bool result = HikNativeMethods.NET_DVR_PTZPreset_Other(
userId,
channel,
command,
(uint)index
);
if (!result)
{
uint err = HikNativeMethods.NET_DVR_GetLastError();
Log.ForContext("SourceContext", LogModules.HikVisionSdk)
.Warning("[SDK] Hik 预置点{Action}失败. Index: {Index}, Error: {Error}",
actionName, index, err);
}
else
{
Log.ForContext("SourceContext", LogModules.HikVisionSdk)
.Debug("[SDK] Hik 预置点{Action}成功. Index: {Index}", actionName, index);
}
});
}
}

View File

@@ -1,7 +1,12 @@
namespace SHH.CameraSdk.HikFeatures;
using Ayay.SerilogLogs;
using Serilog;
namespace SHH.CameraSdk.HikFeatures;
public class HikRebootProvider : IRebootFeature
{
private ILogger _sdkLog = Log.ForContext("SourceContext", LogModules.HikVisionSdk);
private readonly IHikContext _context;
public HikRebootProvider(IHikContext context)
@@ -9,6 +14,7 @@ public class HikRebootProvider : IRebootFeature
_context = context;
}
/// <summary>执行异步重启</summary>
public async Task RebootAsync()
{
// 1. 检查登录状态
@@ -23,14 +29,12 @@ public class HikRebootProvider : IRebootFeature
if (!result)
{
uint err = HikNativeMethods.NET_DVR_GetLastError();
_sdkLog.Error("[SDK] Hik 重启指令下发失败. Error: {Error}", err);
throw new Exception($"重启指令发送失败,错误码: {err}");
}
});
// 3. 注意:
// 重启指令发送成功后,设备会断开网络。
// 宿主类(HikVideoSource)的保活机制(KeepAlive)会检测到断线,
// 并自动开始尝试重连,直到设备重启完成上线。
// 所以这里我们不需要手动断开连接,交给底层自愈机制即可。
_sdkLog.Information("[SDK] Hik 重启指令下发成功,设备即将断开连接。");
});
}
}