using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Extensions.DependencyInjection; using SlnMesnac.Business; using SlnMesnac.Business.@base; using SlnMesnac.Config; using SlnMesnac.Model.dto; using SlnMesnac.Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static SlnMesnac.WPF.CHCNetSDK; #region << 版 本 注 释 >> /*-------------------------------------------------------------------- * 版权所有 (c) 2024 WenJY 保留所有权利。 * CLR版本:4.0.30319.42000 * 机器名称:T14-GEN3-7895 * 命名空间:SlnMesnac.WPF.ViewModel * 唯一标识:018cae17-522c-47d7-be8b-558e6ddda75f * * 创建者:WenJY * 电子邮箱: * 创建时间:2024-10-31 9:40:56 * 版本:V1.0.0 * 描述: * *-------------------------------------------------------------------- * 修改人: * 时间: * 修改说明: * * 版本:V1.0.0 *--------------------------------------------------------------------*/ #endregion << 版 本 注 释 >> namespace SlnMesnac.WPF.ViewModel { public partial class IndexControlViewModel : ObservableObject { private SerilogHelper _log; private AutoModeBusiness autoModeBusiness; private InspModeBusiness inspModeBusiness; private FixedPointBusiness fixedPointBusiness; private AppConfig _appConfig; private CHCNetSDK.RemoteConfigCallback _callback; public CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo; private bool m_bInitSDK = false; private Int32 m_lUserID = -1; public Int32 Scenery_RealHandle = -1; public Int32 Thermal_RealHandle = -1; //private const string DVRIPAddress = "192.168.2.64"; //设备IP地址或者域名 Device IP //private const Int16 DVRPortNumber = 8000; //设备服务端口号 Device Port //private const string DVRUserName = "admin"; //设备登录用户名 User name to login //private const string DVRPassword = "haiwei@2024"; //设备登录密码 Password to login public IndexControlViewModel() { try { _log = App.ServiceProvider.GetService(); _callback = new CHCNetSDK.RemoteConfigCallback(GetThermInfoCallback); _appConfig = App.ServiceProvider.GetService(); autoModeBusiness = App.ServiceProvider.GetService(); inspModeBusiness = App.ServiceProvider.GetService(); fixedPointBusiness = App.ServiceProvider.GetService(); autoModeBusiness.CaptureAlarmPictureEvent += CapturePicture; autoModeBusiness.GimbaRotationControlEvent += GimbaRotationControl; fixedPointBusiness.CaptureAlarmPictureEvent += CapturePicture; fixedPointBusiness.GimbaRotationControlEvent += GimbaRotationControl; inspModeBusiness.CaptureAlarmPictureEvent += CapturePicture; inspModeBusiness.GimbaRotationControlEvent += GimbaRotationControl; RefreshTrackMotorAddress(); }catch (Exception ex) { _log.Error("巡检控制系统初始化失败",ex); MessageBox.Show($"巡检控制系统初始化失败:{ex.Message}"); } } #region 参数定义 private string _gimbalAutoRunText = "Auto"; public string GimbalAutoRunText { get => _gimbalAutoRunText; set => SetProperty(ref _gimbalAutoRunText, value); } private int _realPlcAddress = 0; public int RealPlcAddress { get => _realPlcAddress; set => SetProperty(ref _realPlcAddress, value); } private double _realDeviceSpeed = 0.0; public double RealDeviceSpeed { get => _realDeviceSpeed; set => SetProperty(ref _realDeviceSpeed, value); } private string _realDeviceStatus = "未连接"; public string RealDeviceStatus { get => _realDeviceStatus; set => SetProperty(ref _realDeviceStatus, value); } public RealTemperatureInfo _realTemperature; public RealTemperatureInfo RealTemperature { get => _realTemperature; set => SetProperty(ref _realTemperature, value); } #endregion #region 事件定义 public delegate void RefreshHighlightStation(int cabinetCode); public event RefreshHighlightStation RefreshHighlightStationEvent; #endregion public void Login(PictureBox SceneryPreviewWnd, PictureBox ThermalPreviewWnd) { try { Task.Run(() => { m_bInitSDK = CHCNetSDK.NET_DVR_Init(); if (m_bInitSDK == false) { _log.Info("热成像双光谱微型云台初始化失败 error!"); return; } else { //保存SDK日志 To save the SDK log CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true); _log.Info("热成像双光谱微型云台初始化成功!"); } m_lUserID = CHCNetSDK.NET_DVR_Login_V30(_appConfig.cameraIp, _appConfig.cameraPort, _appConfig.cameraUserName, _appConfig.cameraPassword, ref DeviceInfo); if (m_lUserID < 0) { string str = "热成像双光谱微型云台打开失败, error code= " + CHCNetSDK.NET_DVR_GetLastError(); ; //登录失败,输出错误号 Failed to login and output the error code _log.Info(str); } else { //登录成功 _log.Info("热成像双光谱微型云台打开成功!"); SceneryPreview(SceneryPreviewWnd); ThermalPreview(ThermalPreviewWnd); /// /// 加载实时温度数据 /// var size = Marshal.SizeOf(typeof(CHCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND)); CHCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = new CHCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND(); struThermCond.dwSize = (uint)size; struThermCond.byRuleID = 0; //规则ID,0代表获取全部规则,具体规则ID从1开始 struThermCond.dwChan = 2;// dwChannel; //从1开始,0xffffffff代表获取全部通道 IntPtr pCond = Marshal.AllocCoTaskMem(size); Marshal.StructureToPtr(struThermCond, pCond, false); var ret = CHCNetSDK.NET_DVR_StartRemoteConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, pCond, size, _callback, IntPtr.Zero); if (ret < 0) { _log.Info("配置测温失败, 错误代码:" + CHCNetSDK.NET_DVR_GetLastError()); //登录失败,输出错误号 return; } } }); } catch (Exception ex) { _log.Info($"热成像双光谱微型云台加载异常: {ex.Message}"); } } /// /// 测温回调函数 /// /// /// /// /// public void GetThermInfoCallback(uint dwType, IntPtr lpBuffer, uint dwBufLen, IntPtr pUserData) { var ret = Marshal.PtrToStructure(lpBuffer); if (autoModeBusiness != null) { autoModeBusiness._realTemperatureInfo.fMaxTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fMaxTemperature, 1); autoModeBusiness._realTemperatureInfo.fMinTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fMinTemperature); autoModeBusiness._realTemperatureInfo.fAverageTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fAverageTemperature, 1); autoModeBusiness._realTemperatureInfo.fTemperatureDiff = (float)Math.Round(ret.struLinePolygonThermCfg.fTemperatureDiff, 1); fixedPointBusiness._realTemperatureInfo.fMaxTemperature = autoModeBusiness._realTemperatureInfo.fMaxTemperature; fixedPointBusiness._realTemperatureInfo.fMinTemperature = autoModeBusiness._realTemperatureInfo.fMinTemperature; fixedPointBusiness._realTemperatureInfo.fAverageTemperature = autoModeBusiness._realTemperatureInfo.fAverageTemperature; fixedPointBusiness._realTemperatureInfo.fTemperatureDiff = autoModeBusiness._realTemperatureInfo.fTemperatureDiff; inspModeBusiness._realTemperatureInfo.fMaxTemperature = autoModeBusiness._realTemperatureInfo.fMaxTemperature; inspModeBusiness._realTemperatureInfo.fMinTemperature = autoModeBusiness._realTemperatureInfo.fMinTemperature; inspModeBusiness._realTemperatureInfo.fAverageTemperature = autoModeBusiness._realTemperatureInfo.fAverageTemperature; inspModeBusiness._realTemperatureInfo.fTemperatureDiff = autoModeBusiness._realTemperatureInfo.fTemperatureDiff; } this.RealTemperature = new RealTemperatureInfo() { fMaxTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fMaxTemperature, 1), fMinTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fMinTemperature, 1), fAverageTemperature = (float)Math.Round(ret.struLinePolygonThermCfg.fAverageTemperature, 1), fTemperatureDiff = (float)Math.Round(ret.struLinePolygonThermCfg.fTemperatureDiff, 1), }; } /// /// 抓拍图像 /// /// public void CapturePicture(string sJpegPicFileName) { for (int i = 1; i < 3; i++) { CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA(); lpJpegPara.wPicQuality = 0; lpJpegPara.wPicSize = 0xff; var path = string.Empty; if (i == 1) { path = $"{_appConfig.visibleRangePath}\\{sJpegPicFileName}"; } else { path = $"{_appConfig.infraredImagePath}\\{sJpegPicFileName}"; } if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, i, ref lpJpegPara, path)) { _log.Info("图像信息保存失败, error code= " + NET_DVR_GetLastError()); return; } else { _log.Info("图像信息保存成功: " + path); } } } /// /// 可见光景预览加载 /// /// public void SceneryPreview(PictureBox SceneryPreviewWnd) { try { App.Current.Dispatcher.Invoke(() => { CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); lpPreviewInfo.hPlayWnd = SceneryPreviewWnd.Handle;//预览窗口 live view window lpPreviewInfo.lChannel = 1;//预览的设备通道 the device channel number lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流 lpPreviewInfo.dwDisplayBufNum = 15; //播放库显示缓冲区最大帧数 IntPtr pUser = IntPtr.Zero;//用户数据 user data Scenery_RealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser); if (Scenery_RealHandle < 0) { _log.Info("光景图像预览加载失败, error code= " + CHCNetSDK.NET_DVR_GetLastError()); } else { //预览成功 _log.Info("光景图像预览加载成功 "); } }); } catch (Exception ex) { _log.Camera($"光景图像预览加载异常:{ex.Message}"); } } /// /// 热成像预览加载 /// /// public void ThermalPreview(PictureBox ThermalPreviewWnd) { try { App.Current.Dispatcher.Invoke(() => { CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); lpPreviewInfo.hPlayWnd = ThermalPreviewWnd.Handle;//预览窗口 live view window lpPreviewInfo.lChannel = 2;//预览的设备通道 the device channel number lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流 lpPreviewInfo.dwDisplayBufNum = 15; //播放库显示缓冲区最大帧数 IntPtr pUser = IntPtr.Zero;//用户数据 user data Thermal_RealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser); if (Thermal_RealHandle < 0) { _log.Info("热成像预览加载失败, error code= " + CHCNetSDK.NET_DVR_GetLastError()); } else { //预览成功 _log.Info("热成像预览加载成功"); } }); } catch (Exception ex) { _log.Camera($"热成像图像预览加载异常:{ex.Message}"); } } /// /// 关闭预览 /// /// /// public void ClosePreview(PictureBox SceneryPreviewWnd, PictureBox ThermalPreviewWnd) { if (!CHCNetSDK.NET_DVR_StopRealPlay(Scenery_RealHandle)) { var str = "NET_DVR_StopRealPlay failed, error code= " + CHCNetSDK.NET_DVR_GetLastError(); ; _log.Info(str); return; } else { _log.Info("NET_DVR_StopRealPlay succ!"); SceneryPreviewWnd.Invalidate();//刷新窗口 refresh the window } if (!CHCNetSDK.NET_DVR_StopRealPlay(Thermal_RealHandle)) { var str = "NET_DVR_StopRealPlay failed, error code= " + CHCNetSDK.NET_DVR_GetLastError(); ; _log.Info(str); return; } else { _log.Info("NET_DVR_StopRealPlay succ!"); ThermalPreviewWnd.Invalidate();//刷新窗口 refresh the window Thermal_RealHandle = 0; } } /// /// 退出设备 /// public void Logout() { if (!CHCNetSDK.NET_DVR_Logout(m_lUserID)) { _log.Info("NET_DVR_Logout failed, error code= " + CHCNetSDK.NET_DVR_GetLastError()); return; } if (!CHCNetSDK.NET_DVR_Cleanup()) { _log.Info("NET_DVR_Cleanup failed, error code= " + CHCNetSDK.NET_DVR_GetLastError()); return; } else { this.RealTemperature = new RealTemperatureInfo() { fMaxTemperature = 0, fMinTemperature = 0, fAverageTemperature = 0, fTemperatureDiff = 0, }; } _log.Info("NET_DVR_Logout succ!"); } /// /// 云台控制 /// /// /// public void GimbalOperate(string direction, bool is_MouseDown) { if (is_MouseDown) { switch (direction) { case "left": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, (uint)CHCNetSDK.PAN_LEFT, 0, 4); break; case "right": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_RIGHT, 0, 4); break; case "up": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.TILT_UP, 0, 4); break; case "down": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.TILT_DOWN, 0, 4); break; case "zoomIn": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.ZOOM_IN, 0); break; case "zoomOut": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.ZOOM_OUT, 0); break; case "focusNear": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.FOCUS_NEAR, 0); break; case "focusFar": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.FOCUS_FAR, 0); break; default: break; } } else { switch (direction) { case "left": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_LEFT, 1, 4); break; case "right": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_RIGHT, 1, 4); break; case "up": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.TILT_UP, 1, 4); break; case "down": CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.TILT_DOWN, 1, 4); break; case "zoomIn": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.ZOOM_IN, 1); break; case "zoomOut": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.ZOOM_OUT, 1); break; case "focusNear": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.FOCUS_NEAR, 1); break; case "focusFar": CHCNetSDK.NET_DVR_PTZControl(Scenery_RealHandle, CHCNetSDK.FOCUS_FAR, 1); break; default: break; } } } private bool gimbalAuto = false; public CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg; /// /// 云台回原点 /// [RelayCommand] private void GimbalOrigin() { if (gimbalAuto) { CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_AUTO, 1, 4); this.GimbalAutoRunText = "Auto"; gimbalAuto = false; } float wPanPos, wTiltPos, wZoomPos; var flag = 0; m_struPtzCfg.wAction = 1; m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16("20", 16)); m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16("4", 16)); m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16("10", 16)); while (flag == 0) { Int32 nSize = Marshal.SizeOf(m_struPtzCfg); IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); if (!CHCNetSDK.NET_DVR_SetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_SET_PTZPOS, 1, ptrPtzCfg, (UInt32)nSize)) { var str = "云台回零加载异常, error code= " + CHCNetSDK.NET_DVR_GetLastError(); //设置POS参数失败 _log.Info(str); return; } else { _log.Info("云台回零加载成功!"); break; } Marshal.FreeHGlobal(ptrPtzCfg); } } public void GimbaRotationControl(string wPanPos,string wTiltPos,string wZoomPos) { try { var flag = 0; m_struPtzCfg.wAction = 1; m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(wPanPos, 16)); m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(wTiltPos, 16)); m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16(wZoomPos, 16)); while (flag == 0) { Int32 nSize = Marshal.SizeOf(m_struPtzCfg); IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); if (!CHCNetSDK.NET_DVR_SetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_SET_PTZPOS, 1, ptrPtzCfg, (UInt32)nSize)) { var str = "云台旋转控制异常, error code= " + CHCNetSDK.NET_DVR_GetLastError(); //设置POS参数失败 _log.Info(str); return; } else { _log.Info("云台旋转控制成功!"); break; } //Marshal.FreeHGlobal(ptrPtzCfg); } }catch(Exception ex) { _log.Info($"云台旋转控制异常:{ex.Message}"); } } /// /// 云台自动运行模式 /// public void GimbalAutoRun() { if (!gimbalAuto) { CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_AUTO, 0, 4); this.GimbalAutoRunText = "Stop"; gimbalAuto = true; } else { CHCNetSDK.NET_DVR_PTZControlWithSpeed(Scenery_RealHandle, CHCNetSDK.PAN_AUTO, 1, 4); this.GimbalAutoRunText = "Auto"; gimbalAuto = false; } } /// /// 开启自动模式 /// public void Start_AutoMode() { autoModeBusiness.Start(); } /// /// 关闭自动模式 /// public void Stop_AutoMode() { autoModeBusiness.Stop(); } /// /// 开启巡检模式 /// public void Start_InspMode() { string taskCode = DateTime.Now.ToString("yyyyMMddHHmmssffff"); string fileName = $"{taskCode}.mp4"; //Task.Run(() => //{ // var url = $"{_appConfig.videoFilePath}\\可见光\\{fileName}"; // CHCNetSDK.NET_DVR_MakeKeyFrame(m_lUserID, 1); // if (!CHCNetSDK.NET_DVR_SaveRealData(Scenery_RealHandle, url)) // { // var str = "可见光通道开启巡检录像失败, error code= " + NET_DVR_GetLastError(); // _log.Info(str); // return; // } // else // { // _log.Info($"可见光通道开启巡检录像成功"); // } //}); //Task.Run(() => //{ // var url = $"{_appConfig.videoFilePath}\\热成像\\{fileName}"; // CHCNetSDK.NET_DVR_MakeKeyFrame(m_lUserID, 2); // if (!CHCNetSDK.NET_DVR_SaveRealData(Thermal_RealHandle, url)) // { // var str = "热成像通道开启巡检录像失败, error code= " + NET_DVR_GetLastError(); // _log.Info(str); // return; // } // else // { // _log.Info($"热成像通道开启巡检录像成功"); // } //}); inspModeBusiness.Start(taskCode, fileName); } /// /// 关闭巡检模式 /// public void Stop_InspMode() { //Task.Run(() => //{ // if (!CHCNetSDK.NET_DVR_StopSaveRealData(Scenery_RealHandle)) // { // var str = "可见光通道关闭巡检录像失败, error code= " + NET_DVR_GetLastError(); // _log.Info(str); // return; // } // else // { // _log.Info($"可见光通道关闭巡检录像成功"); // } //}); //Task.Run(() => //{ // if (!CHCNetSDK.NET_DVR_StopSaveRealData(Thermal_RealHandle)) // { // var str = "热成像通道关闭巡检录像失败, error code= " + NET_DVR_GetLastError(); // _log.Info(str); // return; // } // else // { // _log.Info($"热成像通道关闭巡检录像成功"); // } //}); inspModeBusiness.Stop(); } private int lastTrackMotorAddress = 0; private void RefreshTrackMotorAddress() { Task.Run(() => { while (true) { int trackMotorAddress = autoModeBusiness.GetTrackMotorAddress(); if (trackMotorAddress != lastTrackMotorAddress) { RealPlcAddress = trackMotorAddress; RefreshHighlightStationEvent?.Invoke(trackMotorAddress); } double speed = autoModeBusiness.GetDeviceSpeed(); RealDeviceSpeed = Math.Round(speed,2); string deviceStatus = autoModeBusiness.GetDeviceStatus(); RealDeviceStatus = deviceStatus; Task.Delay(1000).Wait(); } }); } } }