101 lines
3.4 KiB
C#
101 lines
3.4 KiB
C#
|
|
using System.Runtime.InteropServices;
|
|||
|
|
using Serilog;
|
|||
|
|
using Ayay.SerilogLogs;
|
|||
|
|
|
|||
|
|
namespace SHH.CameraSdk.DahuaFeatures;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// [大华功能组件] 时间同步实现
|
|||
|
|
/// <para>参照原代码逻辑重构,实现 EM_DEV_CFG_TYPE.TIMECFG 配置下发</para>
|
|||
|
|
/// </summary>
|
|||
|
|
public class DahuaTimeSyncProvider : ITimeSyncFeature
|
|||
|
|
{
|
|||
|
|
private readonly IDahuaContext _context;
|
|||
|
|
|
|||
|
|
public DahuaTimeSyncProvider(IDahuaContext context)
|
|||
|
|
{
|
|||
|
|
_context = context;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取设备当前时间
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<DateTime> GetTimeAsync()
|
|||
|
|
{
|
|||
|
|
IntPtr loginId = _context.GetUserId();
|
|||
|
|
if (loginId == IntPtr.Zero) throw new InvalidOperationException("大华设备未登录");
|
|||
|
|
|
|||
|
|
return await Task.Run(() =>
|
|||
|
|
{
|
|||
|
|
NET_TIME time = new NET_TIME();
|
|||
|
|
uint retLen = 0;
|
|||
|
|
int nSize = Marshal.SizeOf(typeof(NET_TIME));
|
|||
|
|
IntPtr inPtr = Marshal.AllocHGlobal(nSize);
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// Optimized: [原因] 沿用原代码的 GetDevConfig 逻辑与 TIMECFG 指令
|
|||
|
|
Marshal.StructureToPtr(time, inPtr, true);
|
|||
|
|
bool result = NETClient.GetDevConfig(loginId, EM_DEV_CFG_TYPE.TIMECFG, -1, inPtr, (uint)nSize, ref retLen, 5000);
|
|||
|
|
|
|||
|
|
if (result && retLen == (uint)nSize)
|
|||
|
|
{
|
|||
|
|
time = (NET_TIME)Marshal.PtrToStructure(inPtr, typeof(NET_TIME));
|
|||
|
|
// 使用你现有的 ToDateTime() 扩展方法
|
|||
|
|
return time.ToDateTime();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
string err = NETClient.GetLastError();
|
|||
|
|
throw new Exception($"[SDK] Dahua 获取时间失败: {err}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
Marshal.FreeHGlobal(inPtr);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 设置设备时间 (校时)
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task SetTimeAsync(DateTime targetTime)
|
|||
|
|
{
|
|||
|
|
IntPtr loginId = _context.GetUserId();
|
|||
|
|
if (loginId == IntPtr.Zero) throw new InvalidOperationException("大华设备未登录");
|
|||
|
|
|
|||
|
|
await Task.Run(() =>
|
|||
|
|
{
|
|||
|
|
// Modified: [原因] 使用你原有的 FromDateTime 静态方法进行结构体转换
|
|||
|
|
NET_TIME time = NET_TIME.FromDateTime(targetTime);
|
|||
|
|
int nSize = Marshal.SizeOf(typeof(NET_TIME));
|
|||
|
|
IntPtr inPtr = Marshal.AllocHGlobal(nSize);
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
Marshal.StructureToPtr(time, inPtr, true);
|
|||
|
|
|
|||
|
|
// Optimized: [原因] 沿用原代码的 SetDevConfig 逻辑
|
|||
|
|
bool result = NETClient.SetDevConfig(loginId, EM_DEV_CFG_TYPE.TIMECFG, -1, inPtr, (uint)nSize, 5000);
|
|||
|
|
|
|||
|
|
if (result)
|
|||
|
|
{
|
|||
|
|
Log.ForContext("SourceContext", LogModules.DaHuaSdk)
|
|||
|
|
.Information("[SDK] Dahua 校时成功 => {Time}", targetTime.ToString("yyyy-MM-dd HH:mm:ss"));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
string err = NETClient.GetLastError();
|
|||
|
|
Log.ForContext("SourceContext", LogModules.DaHuaSdk)
|
|||
|
|
.Error("[SDK] Dahua 校时指令失败. Error: {Error}", err);
|
|||
|
|
throw new Exception($"大华校时失败: {err}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
Marshal.FreeHGlobal(inPtr);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|