Files
Ayay/SHH.CameraSdk/Drivers/DaHua/Features/DahuaTimeSyncProvider.cs

101 lines
3.4 KiB
C#
Raw Normal View History

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