diff --git a/EC.Util/CameraSDK/Common/CameraException.cs b/EC.Util/CameraSDK/Common/CameraException.cs index b65cfec..c33a62d 100644 --- a/EC.Util/CameraSDK/Common/CameraException.cs +++ b/EC.Util/CameraSDK/Common/CameraException.cs @@ -21,7 +21,7 @@ public class CameraException : Exception protected class CameraExceptionObj { - public CameraManufactor Manufactor { get; set; } + public CameraInfo? CameraInfo { get; set; } public int Code { get; set; } @@ -30,27 +30,27 @@ public class CameraException : Exception public override string? ToString() { StringBuilder builder = new(); - builder.Append($"Manufactor:{Manufactor}, Code:{Code}"); + builder.Append($"Ip:{CameraInfo?.Ip}, Manufactor:{CameraInfo?.GetManufactor}, Code:{Code}"); if (!string.IsNullOrEmpty(Msg)) builder.Append($", Msg:{Msg}"); return builder.ToString(); } } - public static CameraException New(CameraManufactor manufactor, int code) + public static CameraException New(CameraInfo cameraInfo, int code) { CameraExceptionObj obj = new() { - Manufactor = manufactor, + CameraInfo = cameraInfo, Code = code }; return new CameraException(obj.ToString()); } - public static CameraException New(CameraManufactor manufactor, int code, string msg) + public static CameraException New(CameraInfo cameraInfo, int code, string msg) { CameraExceptionObj obj = new() { - Manufactor = manufactor, + CameraInfo = cameraInfo, Code = code, Msg = msg }; diff --git a/EC.Util/CameraSDK/Common/CameraStruct.cs b/EC.Util/CameraSDK/Common/CameraStruct.cs index 40a9ce9..42ebda1 100644 --- a/EC.Util/CameraSDK/Common/CameraStruct.cs +++ b/EC.Util/CameraSDK/Common/CameraStruct.cs @@ -12,6 +12,14 @@ public class CameraInfo /// public int Manufactor { get; set; } + public CameraManufactor GetManufactor + { + get + { + return (CameraManufactor)Manufactor; + } + } + /// /// ip 地址 /// @@ -37,8 +45,7 @@ public class CameraInfo public static CameraInfo New(int manufactor, string ip, int port, string userName, string password) { CameraInfo info = new() { Manufactor = manufactor, Ip = ip, Port = port, UserName = userName, Password = password }; - if (port <= 0) - throw new Exception("Camera manufactor not support."); + if (port <= 0) throw new Exception("Camera manufactor not support."); return info; } @@ -52,9 +59,8 @@ public class CameraInfo CameraManufactor.YuShi => (int)CameraPort.YuShi, _ => -1, }; + if (port <= 0) throw new Exception("Camera manufactor not support."); info.Port = port; - if (port <= 0) - throw new Exception("Camera manufactor not support."); return info; } } @@ -65,8 +71,8 @@ public class CameraInfo public enum CameraManufactor : int { HiK = 1, - DaHua, - YuShi, + DaHua = 2, + YuShi = 3, } /// @@ -108,4 +114,4 @@ public class PtzInfo { return new PtzInfo(pan, tilt, zoom); } -} +} \ No newline at end of file diff --git a/EC.Util/CameraSDK/Common/ICameraSDK.cs b/EC.Util/CameraSDK/Common/ICameraSDK.cs index 90f2370..aea8e44 100644 --- a/EC.Util/CameraSDK/Common/ICameraSDK.cs +++ b/EC.Util/CameraSDK/Common/ICameraSDK.cs @@ -4,7 +4,7 @@ public abstract class ICameraSDK { #region Attr - protected CameraInfo CameraInfo { get; set; } + public CameraInfo CameraInfo { get; } #endregion Attr @@ -40,7 +40,7 @@ public abstract class ICameraSDK #endregion Base Method - #region Main Method + #region Ptz Method /// /// 获取 ptz @@ -54,5 +54,19 @@ public abstract class ICameraSDK /// public abstract bool TryGetPtzInfo(out PtzInfo ptzInfo); - #endregion Main Method + public abstract bool PtzMove(int cmd, int stop, int speed); + + public abstract bool PtzPreset(int cmd, int presetId); + + #endregion Ptz Method + + #region Video Method + + public abstract void StartPlay(IntPtr hwnd); + + public abstract void StopPlay(); + + public abstract bool IsPlaying(); + + #endregion Video Method } \ No newline at end of file diff --git a/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs b/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs new file mode 100644 index 0000000..7b43898 --- /dev/null +++ b/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs @@ -0,0 +1,1512 @@ +using System.Runtime.InteropServices; + +namespace EC.Util.CameraSDK; + +public static class DaHuaOriSDK +{ + #region Lib Attr + + private const string LibDhNetSDK = @"./libs/dh-win64/dhnetsdk.dll"; + + #endregion Lib Attr + + static DaHuaOriSDK() + { + GlobalInit(); + } + + #region Global + + public static bool InitSuccess { get; private set; } + + public static bool GlobalInit() + { + if (InitSuccess) return true; + bool ret = CLIENT_InitEx(null, IntPtr.Zero, IntPtr.Zero); + InitSuccess = ret; + if (!ret) throw new Exception("DaHuaOriSDK global init failure."); + return ret; + } + + public static bool GlobalDestory() + { + if (!InitSuccess) return true; + CLIENT_Cleanup(); + InitSuccess = false; + return true; + } + + #endregion Global + + #region SDK Const + + public const int PtzSpeedMin = 1; + public const int PtzSpeedMax = 8; + + #endregion SDK Const + + #region SDK Enum + + /// + /// login device mode enumeration + /// 登陆设备方式枚举 + /// + public enum EM_LOGIN_SPAC_CAP_TYPE + { + /// + /// TCP login, default + /// TCP登陆, 默认方式 + /// + TCP = 0, + + /// + /// No criteria login + /// 无条件登陆 + /// + ANY = 1, + + /// + /// auto sign up login + /// 主动注册的登入 + /// + SERVER_CONN = 2, + + /// + /// multicast login, default + /// 组播登陆 + /// + MULTICAST = 3, + + /// + /// UDP method login + /// UDP方式下的登入 + /// + UDP = 4, + + /// + /// only main connection login + /// 只建主连接下的登入 + /// + MAIN_CONN_ONLY = 6, + + /// + /// SSL encryption login + /// SSL加密方式登陆 + /// + SSL = 7, + + /// + /// login IVS box remote device + /// 登录智能盒远程设备 + /// + INTELLIGENT_BOX = 9, + + /// + /// login device do not config + /// 登录设备后不做取配置操作 + /// + NO_CONFIG = 10, + + /// + /// USB key device login + /// 用U盾设备的登入 + /// + U_LOGIN = 11, + + /// + /// LDAP login + /// LDAP方式登录 + /// + LDAP = 12, + + /// + /// AD login + /// AD(ActiveDirectory)登录方式 + /// + AD = 13, + + /// + /// Radius login + /// Radius 登录方式 + /// + RADIUS = 14, + + /// + /// Socks5 login + /// Socks5登陆方式 + /// + SOCKET_5 = 15, + + /// + /// cloud login + /// 云登陆方式 + /// + CLOUD = 16, + + /// + /// dual authentication loin + /// 二次鉴权登陆方式 + /// + AUTH_TWICE = 17, + + /// + /// TS stream client login + /// TS码流客户端登陆方式 + /// + TS = 18, + + /// + /// web private login + /// 为P2P登陆方式 + /// + P2P = 19, + + /// + /// mobile client login + /// 手机客户端登陆 + /// + MOBILE = 20, + + /// + /// invalid login + /// 无效的登陆方式 + /// + INVALID = 21, + } + + /// + /// device type enumeration + /// 设备类型枚举 + /// + public enum EM_NET_DEVICE_TYPE + { + /// + /// Unknow + // 未知 + /// + NET_PRODUCT_NONE = 0, + + /// + /// Non real-time MACE + /// 非实时MACE + /// + NET_DVR_NONREALTIME_MACE, + + /// + /// Non real-time + /// 非实时 + /// + NET_DVR_NONREALTIME, + + /// + /// Network video server + /// 网络视频服务器 + /// + NET_NVS_MPEG1, + + /// + /// MPEG1 2-ch DVR + /// MPEG1二路录像机 + /// + NET_DVR_MPEG1_2, + + /// + /// MPEG1 8-ch DVR + /// MPEG1八路录像机 + /// + NET_DVR_MPEG1_8, + + /// + /// MPEG4 8-ch DVR + /// MPEG4八路录像机 + /// + NET_DVR_MPEG4_8, + + /// + /// MPEG4 16-ch DVR + /// MPEG4 十六路录像机 + /// + NET_DVR_MPEG4_16, + + /// + /// LB series DVR + /// LB系列录像机 + /// + NET_DVR_MPEG4_SX2, + + /// + /// GB series DVR + /// GB系列录像机 + /// + NET_DVR_MEPG4_ST2, + + /// + /// HB series DVR + /// HB系列录像机 + /// + NET_DVR_MEPG4_SH2, + + /// + /// GBE series DVR + /// GBE系列录像机 + /// + NET_DVR_MPEG4_GBE, + + /// + /// II network video server + /// II代网络视频服务器 + /// + NET_DVR_MPEG4_NVSII, + + /// + /// New standard configuration protocol + /// 新标准配置协议 + /// + NET_DVR_STD_NEW, + + /// + /// DDNS server + /// DDNS服务器 + /// + NET_DVR_DDNS, + + /// + /// ATM series + /// ATM机 + /// + NET_DVR_ATM, + + /// + /// 2nd non real-time NB series DVR + /// 二代非实时NB系列机器 + /// + NET_NB_SERIAL, + + /// + /// LN series + /// LN系列产品 + /// + NET_LN_SERIAL, + + /// + /// BAV series + /// BAV系列产品 + /// + NET_BAV_SERIAL, + + /// + /// SDIP series + /// SDIP系列产品 + /// + NET_SDIP_SERIAL, + + /// + /// IPC series + /// IPC系列产品 + /// + NET_IPC_SERIAL, + + /// + /// NVS B series + /// NVS B系列 + /// + NET_NVS_B, + + /// + /// NVS H series + /// NVS H系列 + /// + NET_NVS_C, + + /// + /// NVS S series + /// NVS S系列 + /// + NET_NVS_S, + + /// + /// NVS E series + /// NVS E系列 + /// + NET_NVS_E, + + /// + /// Search device type from QueryDevState. it is in string format + /// 从QueryDevState中查询设备类型,以字符串格式 + /// + NET_DVR_NEW_PROTOCOL, + + /// + /// NVD + /// 解码器 + /// + NET_NVD_SERIAL, + + /// + /// N5 + /// N5 + /// + NET_DVR_N5, + + /// + /// HDVR + /// 混合DVR + /// + NET_DVR_MIX_DVR, + + /// + /// SVR series + /// SVR系列 + /// + NET_SVR_SERIAL, + + /// + /// SVR-BS + /// SVR-BS + /// + NET_SVR_BS, + + /// + /// NVR series + /// NVR系列 + /// + NET_NVR_SERIAL, + + /// + /// N51 + /// N51 + /// + NET_DVR_N51, + + /// + /// ITSE Intelligent Analysis Box + /// ITSE 智能分析盒 + /// + NET_ITSE_SERIAL, + + /// + /// Intelligent traffic camera equipment + /// 智能交通像机设备 + /// + NET_ITC_SERIAL, + + /// + /// radar speedometer HWS + /// 雷达测速仪HWS + /// + NET_HWS_SERIAL, + + /// + /// portable video record + /// 便携式音视频录像机 + /// + NET_PVR_SERIAL, + + /// + /// IVS(intelligent video server series) + /// IVS(智能视频服务器系列) + /// + NET_IVS_SERIAL, + + /// + /// universal intelligent detect video server series + /// 通用智能视频侦测服务器 + /// + NET_IVS_B, + + /// + /// face recognisation server + /// 人脸识别服务器 + /// + NET_IVS_F, + + /// + /// video quality diagnosis server + /// 视频质量诊断服务器 + /// + NET_IVS_V, + + /// + /// matrix + /// 矩阵 + /// + NET_MATRIX_SERIAL, + + /// + /// N52 + /// N52 + /// + NET_DVR_N52, + + /// + /// N56 + /// N56 + /// + NET_DVR_N56, + + /// + /// ESS + /// ESS + /// + NET_ESS_SERIAL, + + /// + /// 人数统计服务器 + /// + NET_IVS_PC, + + /// + /// pc-nvr + /// pc-nvr + /// + NET_PC_NVR, + + /// + /// screen controller + /// 大屏控制器 + /// + NET_DSCON, + + /// + /// network video storage server + /// 网络视频存储服务器 + /// + NET_EVS, + + /// + /// an embedded intelligent video analysis system + /// 嵌入式智能分析视频系统 + /// + NET_EIVS, + + /// + /// DVR-N6 + /// DVR-N6 + /// + NET_DVR_N6, + + /// + /// K-Lite Codec Pack + /// 万能解码器 + /// + NET_UDS, + + /// + /// Bank alarm host + /// 银行报警主机 + /// + NET_AF6016, + + /// + /// Video network alarm host + /// 视频网络报警主机 + /// + NET_AS5008, + + /// + /// Network alarm host + /// 网络报警主机 + /// + NET_AH2008, + + /// + /// Alarm host series + /// 报警主机系列 + /// + NET_A_SERIAL, + + /// + /// Access control series of products + /// 门禁系列产品 + /// + NET_BSC_SERIAL, + + /// + /// NVS series product + /// NVS系列产品 + /// + NET_NVS_SERIAL, + + /// + /// VTO series product + /// VTO系列产品 + /// + NET_VTO_SERIAL, + + /// + /// VTNC series product + /// VTNC系列产品 + /// + NET_VTNC_SERIAL, + + /// + /// TPC series product, it is the thermal device + /// TPC系列产品, 即热成像设备 + /// + NET_TPC_SERIAL, + + /// + /// ASM series product + /// 无线中继设备 + /// + NET_ASM_SERIAL, + + /// + /// VTS series product + /// 管理机 + /// + NET_VTS_SERIAL, + + /// + /// Alarm host-ARC2016C + /// 报警主机ARC2016C + /// + NET_ARC2016C, + + /// + /// ASA Attendance machine + /// 考勤机 + /// + NET_ASA, + + /// + /// Industry terminal walkie-talkie + /// 行业对讲终端 + /// + NET_VTT_SERIAL, + + /// + /// Alarm column + /// 报警柱 + /// + NET_VTA_SERIAL, + + /// + /// SIP Server + /// SIP服务器 + /// + NET_VTNS_SERIAL, + + /// + /// Indoor unit + /// 室内机 + /// + NET_VTH_SERIAL, + } + + /// + /// 查询设备信息参数 + /// + public enum EM_DEVICE_STATE + { + /// + /// Query device online state(return a DWORD value, 1-online, 0-offline) + /// 查询设备的在线状态(返回一个DWORD, 1表示在线, 0表示断线) + /// + ONLINE = 0x0035, + + /// + /// Query ptz state(struct DH_PTZ_LOCATION_INFO) + /// 查询云台状态信息(对应结构体 DH_PTZ_LOCATION_INFO) + /// + PTZ_LOCATION = 0x0036, + } + + /// + /// PTZ control command enumeration + /// 云台控制命令 + /// + public enum EM_EXTPTZ_ControlType : int + { + /// + /// Up + /// 上 + /// + UP_CONTROL = 0, + + /// + /// Down + /// 下 + /// + DOWN_CONTROL, + + /// + /// Left + /// 左 + /// + LEFT_CONTROL, + + /// + /// Right + /// 右 + /// + RIGHT_CONTROL, + + /// + /// +Zoom in + /// 变倍+ + /// + ZOOM_ADD_CONTROL, + + /// + /// -Zoom out + /// 变倍- + /// + ZOOM_DEC_CONTROL, + + /// + /// +Focus + /// 调焦+ + /// + FOCUS_ADD_CONTROL, + + /// + /// -Focus + /// 调焦- + /// + FOCUS_DEC_CONTROL, + + /// + /// + Aperture + /// 光圈+ + /// + APERTURE_ADD_CONTROL, + + /// + /// -Aperture + /// 光圈- + /// + APERTURE_DEC_CONTROL, + + /// + /// Go to preset + /// 转至预置点 + /// + POINT_MOVE_CONTROL, + + /// + /// Set + /// 设置 + /// + POINT_SET_CONTROL, + + /// + /// Delete + /// 删除 + /// + POINT_DEL_CONTROL, + + /// + /// Tour + /// 点间巡航 + /// + POINT_LOOP_CONTROL, + + /// + /// Light and wiper + /// 灯光雨刷 + /// + LAMP_CONTROL, + + /// + /// Upper left + /// 左上 + /// + LEFTTOP = 0x20, + + /// + /// Upper right + /// 右上 + /// + RIGHTTOP, + + /// + /// Down left + /// 左下 + /// + LEFTDOWN, + + /// + /// Down right + /// 右下 + /// + RIGHTDOWN, + + /// + /// Add preset to tour tour preset value + /// 加入预置点到巡航 巡航线路 预置点值 + /// + ADDTOLOOP, + + /// + /// Delete preset in tour tour preset value + /// 删除巡航中预置点 巡航线路 预置点值 + /// + DELFROMLOOP, + + /// + /// Delete tour tour + /// 清除巡航 巡航线路 + /// + CLOSELOOP, + + /// + /// Begin pan rotation + /// 开始水平旋转 + /// + STARTPANCRUISE, + + /// + /// Stop pan rotation + /// 停止水平旋转 + /// + STOPPANCRUISE, + + /// + /// Set left limit + /// 设置左边界 + /// + SETLEFTBORDER, + + /// + /// Set right limit + /// 设置右边界 + /// + SETRIGHTBORDER, + + /// + /// Begin scanning + /// 开始线扫 + /// + STARTLINESCAN, + + /// + /// Stop scanning + /// 停止线扫 + /// + CLOSELINESCAN, + + /// + /// Start mode mode line + /// 设置模式开始 模式线路 + /// + SETMODESTART, + + /// + /// Stop mode mode line + /// 设置模式结束 模式线路 + /// + SETMODESTOP, + + /// + /// Enable mode Mode line + /// 运行模式 模式线路 + /// + RUNMODE, + + /// + /// Disable mode Mode line + /// 停止模式 模式线路 + /// + STOPMODE, + + /// + /// Delete mode Mode line + /// 清除模式 模式线路 + /// + DELETEMODE, + + /// + /// Flip + /// 翻转命令 + /// + REVERSECOMM, + + /// + /// 3D position X address(8192) Y address(8192) zoom(4) + /// 快速定位 水平坐标(8192) 垂直坐标(8192) 变倍(4) + /// + FASTGOTO, + + /// + /// auxiliary open Auxiliary point(param4 corresponding struct PTZ_CONTROL_AUXILIARY,param1、param2、param3 is invalid,dwStop set to FALSE) + /// 辅助开关开 辅助点(param4对应 PTZ_CONTROL_AUXILIARY,param1、param2、param3无效,dwStop设置为FALSE) + /// + AUXIOPEN, + + /// + /// Auxiliary close Auxiliary point(param4 corresponding struct PTZ_CONTROL_AUXILIARY,param1、param2、param3 is invalid,dwStop set to FALSE) + /// 辅助开关关 辅助点(param4对应 PTZ_CONTROL_AUXILIARY,param1、param2、param3无效,dwStop设置为FALSE) + /// + AUXICLOSE, + + /// + /// Open dome menu + /// 打开球机菜单 + /// + OPENMENU = 0x36, + + /// + /// Close menu + /// 关闭菜单 + /// + CLOSEMENU, + + /// + /// Confirm menu + /// 菜单确定 + /// + MENUOK, + + /// + /// Cancel menu + /// 菜单取消 + /// + MENUCANCEL, + + /// + /// menu up + /// 菜单上 + /// + MENUUP, + + /// + /// menu down + /// 菜单下 + /// + MENUDOWN, + + /// + /// menu left + /// 菜单左 + /// + MENULEFT, + + /// + /// Menu right + /// 菜单右 + /// + MENURIGHT, + + /// + /// Alarm activate PTZ parm1:Alarm input channel;parm2:Alarm activation type 1-preset 2-scan 3-tour;parm 3:activation value,such as preset value. + /// 报警联动云台 parm1:报警输入通道;parm2:报警联动类型1-预置点2-线扫3-巡航;parm3:联动值,如预置点号 + /// + ALARMHANDLE = 0x40, + + /// + /// Matrix switch parm1:monitor number(video output number);parm2:video input number;parm3:matrix number + /// 矩阵切换 parm1:监视器号(视频输出号);parm2:视频输入号;parm3:矩阵号 + /// + MATRIXSWITCH = 0x41, + + /// + /// Light controller + /// 灯光控制器 + /// + LIGHTCONTROL, + + /// + /// 3D accurately positioning parm1:Pan degree(0~3600); parm2: tilt coordinates(0~900); parm3:zoom(1~128) + /// 三维精确定位 parm1:水平角度(0~3600);parm2:垂直坐标(0~900);parm3:变倍(1~128) + /// + EXACTGOTO, + + /// + /// Reset 3D positioning as zero + /// 三维定位重设零位 + /// + RESETZERO, + + /// + /// Absolute motion control command,param4 corresponding struct NET_PTZ_CONTROL_ABSOLUTELY + /// 绝对移动控制命令,param4对应结构 NET_PTZ_CONTROL_ABSOLUTELY + /// + MOVE_ABSOLUTELY, + + /// + /// Continuous motion control command,param4 corresponding struct NET_PTZ_CONTROL_CONTINUOUSLY + /// 持续移动控制命令,param4对应结构 NET_PTZ_CONTROL_CONTINUOUSLY + /// + MOVE_CONTINUOUSLY, + + /// + /// PTZ control command, at a certain speed to preset locu,parm4 corresponding struct NET_PTZ_CONTROL_GOTOPRESET + /// 云台控制命令,以一定速度转到预置位点,parm4对应结构NET_PTZ_CONTROL_GOTOPRESET + /// + GOTOPRESET, + + /// + /// Set to horizon(param4 corresponding struct NET_PTZ_VIEW_RANGE_INFO) + /// 设置可视域(param4对应结构 NET_PTZ_VIEW_RANGE_INFO) + /// + SET_VIEW_RANGE = 0x49, + + /// + /// Absolute focus(param4 corresponding struct NET_PTZ_FOCUS_ABSOLUTELY) + /// 绝对聚焦(param4对应结构NET_PTZ_FOCUS_ABSOLUTELY) + /// + FOCUS_ABSOLUTELY = 0x4A, + + /// + /// Level fan sweep(param4 corresponding NET_PTZ_CONTROL_SECTORSCAN,param1,param2,param3 is invalid) + /// 水平扇扫(param4对应PTZ_CONTROL_SECTORSCAN,param1、param2、param3无效) + /// + HORSECTORSCAN = 0x4B, + + /// + /// Vertical sweep fan(param4 corresponding NET_PTZ_CONTROL_SECTORSCAN,param1,param2,param3 is invalid) + /// 垂直扇扫(param4对应PTZ_CONTROL_SECTORSCAN,param1、param2、param3无效) + /// + VERSECTORSCAN = 0x4C, + + /// + /// Set absolute focus, focus on value, param1 for focal length, range: [0255], param2 as the focus, scope: [0255], param3, param4 is invalid + /// 设定绝对焦距、聚焦值,param1为焦距,范围:[0,255],param2为聚焦,范围:[0,255],param3、param4无效 + /// + SET_ABS_ZOOMFOCUS = 0x4D, + + /// + /// Control fish eye PTZ,param4corresponding to structure NET_PTZ_CONTROL_SET_FISHEYE_EPTZ + /// 控制鱼眼电子云台,param4对应结构 PTZ_CONTROL_SET_FISHEYE_EPTZ + /// + SET_FISHEYE_EPTZ = 0x4E, + + /// + /// Track start control(param4 corresponding to structure NET_PTZ_CONTROL_SET_TRACK_CONTROL,dwStop set as FALSE, param1、param2、param3 is invalid) + /// 轨道机开始控制(param4对应结构体为 PTZ_CONTROL_SET_TRACK_CONTROL,dwStop传FALSE, param1、param2、param3无效) + /// + SET_TRACK_START = 0x4F, + + /// + /// Track stop control (param4 corresponding to structure NET_PTZ_CONTROL_SET_TRACK_CONTROL,dwStop set as FALSE,param1、param2、param3 is invalid) + /// 轨道机停止控制(param4对应结构体为 PTZ_CONTROL_SET_TRACK_CONTROL,dwStop传FALSE,param1、param2、param3无效) + /// + SET_TRACK_STOP = 0x50, + + /// + /// Up + TELE param1=speed (1-8) + /// 上 + TELE param1=速度(1-8),下同 + /// + UP_TELE = 0x70, + + /// + /// Down + TELE + /// 下 + TELE + /// + DOWN_TELE, + + /// + /// Left + TELE + /// 左 + TELE + /// + LEFT_TELE, + + /// + /// Right + TELE + /// 右 + TELE + /// + RIGHT_TELE, + + /// + /// Upper left + TELE + /// 左上 + TELE + /// + LEFTUP_TELE, + + /// + /// Down left + TELE + /// 左下 + TELE + /// + LEFTDOWN_TELE, + + /// + /// Upper right + TELE + /// 右上 + TELE + /// + TIGHTUP_TELE, + + /// + /// Down right + TELE + /// 右下 + TELE + /// + RIGHTDOWN_TELE, + + /// + /// Up + WIDE param1=speed (1-8) + /// 上 + WIDE param1=速度(1-8),下同 + /// + UP_WIDE, + + /// + /// Down + WIDE + /// 下 + WIDE + /// + DOWN_WIDE, + + /// + /// Left + WIDE + /// 左 + WIDE + /// + LEFT_WIDE, + + /// + /// Right + WIDE + /// 右 + WIDE + /// + RIGHT_WIDE, + + /// + /// Upper left + WIDE + /// 左上 + WIDE + /// + LEFTUP_WIDE, + + /// + /// Down left+ WIDE + /// 左下 + WIDE + /// + LEFTDOWN_WIDE, + + /// + /// Upper right + WIDE + /// 右上 + WIDE + /// + TIGHTUP_WIDE, + + /// + /// Down right + WIDE + /// 右下 + WIDE + /// + RIGHTDOWN_WIDE, + + /// + /// Go to preset point and take a picture + /// 至预置点并抓图 + /// + GOTOPRESETSNAP = 0x80, + + /// + /// Calibrate the PTZ direction (two-way calibration) + /// 校准云台方向(双方向校准) + /// + DIRECTIONCALIBRATION = 0x82, + + /// + /// Calibrate the PTZ direction (one-way calibration) param4 -> NET_IN_CALIBRATE_SINGLEDIRECTION + /// 校准云台方向(单防线校准), param4 -> NET_IN_CALIBRATE_SINGLEDIRECTION + /// + SINGLEDIRECTIONCALIBRATION = 0x83, + + /// + /// Relative positioning of PTZ, param4 -> NET_IN_MOVERELATIVELY_INFO + /// 云台相对定位, param4 -> NET_IN_MOVERELATIVELY_INFO + /// + MOVE_RELATIVELY = 0x84, + + /// + /// Set direction for PTZ, param4 -> NET_IN_SET_DIRECTION_INFO + /// 设置云台方向, param4 -> NET_IN_SET_DIRECTION_INFO + /// + SET_DIRECTION = 0x85, + + /// + /// Precisely and absolutely movement control command, param4 -> NET_IN_PTZBASE_MOVEABSOLUTELY_INFO use CFG_CAP_CMD_PTZ command to get the capability of PTZ + /// if CFG_PTZ_PROTOCOL_CAPS_INFO -> bSupportReal equals TRUE means this device supports this feature + /// 精准绝对移动控制命令, param4 -> NET_IN_PTZBASE_MOVEABSOLUTELY_INFO(通过 CFG_CAP_CMD_PTZ 命令获取云台能力集( CFG_PTZ_PROTOCOL_CAPS_INFO ) + /// 若bSupportReal为TRUE则设备支持该操作) + /// + BASE_MOVE_ABSOLUTELY = 0x86, + + /// + /// Continuously movement control command, param4 -> NET_IN_PTZBASE_MOVECONTINUOUSLY_INFO. use CFG_CAP_CMD_PTZ command to get the capability of PTZ + /// if CFG_PTZ_PROTOCOL_CAPS_INFO -> stuMoveContinuously equals -> stuType.bSupportExtra equals TRUE means this device supports this feature + /// 云台连续移动控制命令, param4 -> NET_IN_PTZBASE_MOVECONTINUOUSLY_INFO. 通过 CFG_CAP_CMD_PTZ 命令获取云台能力集 + /// 若 CFG_PTZ_PROTOCOL_CAPS_INFO 中 stuMoveContinuously 字段的 为 TRUE, 表示设备支持该操作 + /// + BASE_MOVE_CONTINUOUSLY, + + /// + /// Maximum command value + /// 最大命令值 + /// + TOTAL, + } + + /// + /// 预置点状态枚举 + /// + public enum EM_DH_PTZ_PRESET_STATUS + { + UNKNOWN, // 未知 + REACH, // 预置点到达 + UNREACH, // 预置点未到达 + } + + /// + /// realplay type + /// 监视类型 + /// + public enum EM_RealPlayType + { + /// + /// Real-time preview + /// 实时预览 + /// + Realplay = 0, + + /// + /// Multiple-channel preview + /// 多画面预览 + /// + Multiplay, + + /// + /// Real-time monitor-main stream. It is the same as EM_RealPlayType.Realplay + /// 实时监视-主码流,等同于EM_RealPlayType.Realplay + /// + Realplay_0, + + /// + /// Real-time monitor -- extra stream 1 + /// 实时监视-从码流1 + /// + Realplay_1, + + /// + /// Real-time monitor -- extra stream 2 + /// 实时监视-从码流2 + /// + Realplay_2, + + /// + /// Real-time monitor -- extra stream 3 + /// 实时监视-从码流3 + /// + Realplay_3, + + /// + /// Multiple-channel preview--1-window + /// 多画面预览-1画面 + /// + Multiplay_1, + + /// + /// Multiple-channel preview--4-window + /// 多画面预览-4画面 + /// + Multiplay_4, + + /// + /// Multiple-channel preview--8-window + /// 多画面预览-8画面 + /// + Multiplay_8, + + /// + /// Multiple-channel preview--9-window + /// 多画面预览-9画面 + /// + Multiplay_9, + + /// + /// Multiple-channel preview--16-window + /// 多画面预览-16画面 + /// + Multiplay_16, + + /// + /// Multiple-channel preview--6-window + /// 多画面预览-6画面 + /// + Multiplay_6, + + /// + /// Multiple-channel preview--12-window + /// 多画面预览-12画面 + /// + Multiplay_12, + + /// + /// Multiple-channel preview--25-window + /// 多画面预览-25画面 + /// + Multiplay_25, + + /// + /// Multiple-channel preview--36-window + /// 多画面预览-36画面 + /// + Multiplay_36, + + /// + /// test stream + /// 带宽测试码流 + /// + Realplay_Test = 255, + } + + #endregion SDK Enum + + #region SDK Struct + + /// + /// CLIENT_LoginWithHighLevelSecurity 输入参数 + /// + public struct NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY + { + public uint dwSize;// 结构体大小 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szIP; // IP + + public int nPort; // 端口 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szUserName; // 用户名 + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szPassword; // 密码 + + public EM_LOGIN_SPAC_CAP_TYPE emSpecCap; // 登录模式 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] byReserved; // 字节对齐 + + public IntPtr pCapParam; // 见 CLIENT_LoginEx 接口 pCapParam 与 nSpecCap 关系 + } + + /// + /// device information structure + /// 设备信息结构体 + /// + public struct NET_DEVICEINFO_Ex + { + /// + /// serial number + /// 序列号 + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] + public string sSerialNumber; + + /// + /// count of alarm input + /// 报警输入个数 + /// + public int nAlarmInPortNum; + + /// + /// count of alarm output + /// 报警输出个数 + /// + public int nAlarmOutPortNum; + + /// + /// number of disk + /// 硬盘个数 + /// + public int nDiskNum; + + /// + /// device type, refer to EM_NET_DEVICE_TYPE + /// 设备类型,见枚举NET_DEVICE_TYPE + /// + public EM_NET_DEVICE_TYPE nDVRType; + + /// + /// number of channel + /// 通道个数 + /// + public int nChanNum; + + /// + /// Online Timeout, Not Limited Access to 0, not 0 Minutes Limit Said + /// 在线超时时间,为0表示不限制登陆,非0表示限制的分钟数 + /// + public byte byLimitLoginTime; + + /// + /// When login failed due to password error, notice user by this parameter.This parameter is invalid when remaining login times is zero + /// 当登陆失败原因为密码错误时,通过此参数通知用户,剩余登陆次数,为0时表示此参数无效 + /// + public byte byLeftLogTimes; + + /// + /// keep bytes for aligned + /// 保留字节,字节对齐 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] bReserved; + + /// + /// when log in failed,the left time for users to unlock (seconds), -1 indicate the device haven't set the parameter + /// 当登陆失败,用户解锁剩余时间(秒数), -1表示设备未设置该参数 + /// + public int nLockLeftTime; + + /// + /// reserved + /// 保留字节 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] + public byte[] Reserved; + } + + /// + /// CLIENT_LoginWithHighLevelSecurity 输出参数 + /// + public struct NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY + { + public uint dwSize;// 结构体大小 + public NET_DEVICEINFO_Ex stuDeviceInfo; // 设备信息 + public int nError; // 错误码,见 CLIENT_Login 接口错误码 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 132)] + public byte[] byReserved; // 保留字节 + } + + /// + /// 云台定位中非归一化坐标和变倍 + /// + public struct NET_PTZSPACE_UNNORMALIZED + { + public int nPosX; // x坐标 + public int nPosY; // y坐标 + public int nZoom; // 放大倍率 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 52)] + public byte[] byReserved; // 预留字节 + } + + /// + /// 云台定位信息 + /// + //云台定位信息 + public struct DH_PTZ_LOCATION_INFO + { + public int nChannelID; // 通道号 + public int nPTZPan; // 云台水平运动位置,有效范围:[0,3600] + public int nPTZTilt; // 云台垂直运动位置,有效范围:[-1800,1800] + public int nPTZZoom; // 云台光圈变动位置,有效范围:[0,128] + public byte bState; // 云台运动状态, 0-未知 1-运动 2-空闲 + public byte bAction; // 云台动作,255-未知,0-预置点,1-线扫,2-巡航,3-巡迹,4-水平旋转,5-普通移动,6-巡迹录制,7-全景云台扫描,8-热度图 + + // 9-精确定位,10-设备校正,11-智能配置,12-云台重启 + public byte bFocusState; // 云台聚焦状态, 0-未知, 1-运动状态, 2-空闲 + + public byte bEffectiveInTimeSection; // 在时间段内预置点状态是否有效 + + //如果当前上报的预置点是时间段内的预置点,则为1,其他情况为0 + public int nPtzActionID; // 巡航ID号 + + public uint dwPresetID; // 云台所在预置点编号 + public float fFocusPosition; // 聚焦位置 + public byte bZoomState; // 云台ZOOM状态,0-未知,1-ZOOM,2-空闲 + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bReserved; // 对齐 + + public uint dwSequence; // 包序号,用于校验是否丢包 + public uint dwUTC; // 对应的UTC(1970-1-1 00:00:00)秒数。 + public EM_DH_PTZ_PRESET_STATUS emPresetStatus; // 预置点位置 + + /// + /// 保留字段 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 248)] + public int[] reserved; + }; + + #endregion SDK Struct + + #region Common Method + + /// + /// network disconnection callback function original shape + /// 断线回调函数 + /// + /// user LoginID:Login's returns value 登陆ID + /// device IP 设备IP + /// device prot 设备端口 + /// user data from Init function 用户数据 + public delegate void fDisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser); + + /// + /// network re-connection callback function original shape + /// 重连回调函数 + /// + /// user LoginID:Login's returns value 登陆ID + /// device IP,string type 设备IP + /// device prot 设备端口 + /// user data from SetAutoReconnect function 用户数据 + public delegate void fHaveReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_InitEx(fDisConnectCallBack? cbDisConnect, IntPtr dwUser, IntPtr lpInitParam); + + [DllImport(LibDhNetSDK)] + public static extern void CLIENT_Cleanup(); + + [DllImport(LibDhNetSDK)] + public static extern int CLIENT_GetLastError(); + + [DllImport(LibDhNetSDK)] + public static extern IntPtr CLIENT_LoginWithHighLevelSecurity(ref NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam, ref NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_Logout(IntPtr lLoginID); + + [DllImport(LibDhNetSDK)] + public static extern void CLIENT_SetAutoReconnect(fHaveReConnectCallBack cbAutoConnect, IntPtr dwUser); + + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_QueryDevState(IntPtr lLoginID, int nType, IntPtr pBuf, int nBufLen, ref int pRetLen, int waittime); + + /// + /// PTZ control + /// PTZ控制接口 + /// + /// user LoginID:Login's returns value 登陆ID,Login返回值 + /// channel number 通道号 + /// PTZ control commands 控制命令 + /// Parameter1 details refer to EM_EXTPTZ_ControlType 控制命令的参数1 + /// Parameter2 details refer to EM_EXTPTZ_ControlType 控制命令的参数2 + /// Parameter3 details refer to EM_EXTPTZ_ControlType 控制命令的参数3 + /// stop or not, effective to PTZ eight-directions operation and lens operation. During other operation, this parameter should fill in false 是否停止 + /// support PTZ control extensive command,support these commands: 控制命令的参数4 + /// EM_EXTPTZ_ControlType.MOVE_ABSOLUTELY:Absolute motion control commands,param4 corresponding struct NET_PTZ_CONTROL_ABSOLUTELY + /// EM_EXTPTZ_ControlType.MOVE_CONTINUOUSLY:Continuous motion control commands,param4 corresponding struct NET_PTZ_CONTROL_CONTINUOUSLY + /// EM_EXTPTZ_ControlType.GOTOPRESET:PTZ control command, at a certain speed to preset locus,parm4 corresponding struct NET_PTZ_CONTROL_GOTOPRESET + /// EM_EXTPTZ_ControlType.SET_VIEW_RANGE:Set to horizon(param4 corresponding struct NET_PTZ_VIEW_RANGE_INFO + /// EM_EXTPTZ_ControlType.FOCUS_ABSOLUTELY:Absolute focus(param4 corresponding struct NET_PTZ_FOCUS_ABSOLUTELY + /// EM_EXTPTZ_ControlType.HORSECTORSCAN:Level fan sweep(param4 corresponding NET_PTZ_CONTROL_SECTORSCAN,param1、param2、param3 is invalid + /// EM_EXTPTZ_ControlType.VERSECTORSCAN:Vertical sweep fan(param4 corresponding NET_PTZ_CONTROL_SECTORSCAN,param1、param2、param3 is invalid + /// EM_EXTPTZ_ControlType.SET_FISHEYE_EPTZ:Control fish eye PTZ,param4corresponding to structure NET_PTZ_CONTROL_SET_FISHEYE_EPTZ + /// EM_EXTPTZ_ControlType.SET_TRACK_START/SET_TRACK_STOP:param4 corresponding to structure NET_PTZ_CONTROL_SET_TRACK_CONTROL,dwStop set as FALSE,param1、param2、param3 is invalid + /// failed return false, successful return true 失败返回false 成功返回true + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_DHPTZControlEx2(IntPtr lLoginID, int nChannelID, uint dwPTZCommand, int lParam1, int lParam2, int lParam3, bool dwStop, IntPtr param4); + + /// + /// start real-time monitor.support 32bit and 64bit + /// 开始实时监视.支持32位和64位 + /// + /// user LoginID:Login's returns value 登陆ID,Login返回值 + /// real time monitor channel NO.(from 0). 通道号 + /// display window handle. When value is 0(IntPtr.Zero), data are not decoded or displayed 显示窗口句柄 + /// realplay type 监视类型 + /// failed return 0, successful return the real time monitorID(real time monitor handle),as parameter of related function. 失败返回0,成功返回大于0的值 + [DllImport(LibDhNetSDK)] + public static extern IntPtr CLIENT_RealPlayEx(IntPtr lLoginID, int nChannelID, IntPtr hWnd, EM_RealPlayType rType); + + /// + /// stop real time monitoring + /// 关闭实时监视 + /// + /// monitor handle StartRealPlay returns value 监视ID StartRealPlay返回值 + /// failed return false, successful return true 失败返回false 成功返回true + [DllImport(LibDhNetSDK)] + public static extern bool CLIENT_StopRealPlayEx(IntPtr lRealHandle); + + #endregion Common Method +} \ No newline at end of file diff --git a/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs b/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs new file mode 100644 index 0000000..28610de --- /dev/null +++ b/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs @@ -0,0 +1,190 @@ +using System.Runtime.InteropServices; + +namespace EC.Util.CameraSDK; + +public class DaHuaSDK : ICameraSDK +{ + #region Attr + + private IntPtr LoginId { get; set; } = IntPtr.Zero; + + private IntPtr RealplayHandle { get; set; } = IntPtr.Zero; + + #endregion Attr + + public DaHuaSDK(CameraInfo cameraInfo) : base(cameraInfo) + { + } + + #region Base Method + + public override bool Init() + { + bool ret = ConnectSuccess(); + if (ret) return true; + + DaHuaOriSDK.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stuInParam = new(); + stuInParam.dwSize = (uint)Marshal.SizeOf(stuInParam); + stuInParam.szIP = CameraInfo.Ip; + stuInParam.nPort = CameraInfo.Port; + stuInParam.szUserName = CameraInfo.UserName; + stuInParam.szPassword = CameraInfo.Password; + stuInParam.emSpecCap = DaHuaOriSDK.EM_LOGIN_SPAC_CAP_TYPE.TCP; + stuInParam.pCapParam = IntPtr.Zero; + DaHuaOriSDK.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stuOutParam = new(); + stuOutParam.dwSize = (uint)Marshal.SizeOf(stuOutParam); + LoginId = DaHuaOriSDK.CLIENT_LoginWithHighLevelSecurity(ref stuInParam, ref stuOutParam); + ret = ConnectSuccess(); + if (ret) DaHuaOriSDK.CLIENT_SetAutoReconnect(delegate (IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser) + { + LoginId = lLoginID; + }, IntPtr.Zero); + + return ret; + } + + public override bool Destory() + { + bool ret = ConnectSuccess(); + if (!ret) return true; + + ret = DaHuaOriSDK.CLIENT_Logout(LoginId); + if (ret) LoginId = IntPtr.Zero; + + return ret; + } + + public override bool ConnectSuccess() + { + return LoginId != IntPtr.Zero; + } + + public override void BuildException() + { + uint errCode = (uint)DaHuaOriSDK.CLIENT_GetLastError(); + if (errCode == 0) return; + errCode -= 0x80000000; + throw CameraException.New(CameraInfo, (int)errCode); + } + + #endregion Base Method + + #region Ptz Method + + private static class GPIParams + { + public static int Size { get; private set; } + public static Type Type { get; private set; } + + static GPIParams() + { + DaHuaOriSDK.DH_PTZ_LOCATION_INFO info = new(); + Size = Marshal.SizeOf(info); + Type = info.GetType(); + } + } + + public override PtzInfo GetPtzInfo() + { + bool ret = ConnectSuccess(); + if (!ret) return PtzInfo.Default; + + DaHuaOriSDK.DH_PTZ_LOCATION_INFO entity = new(); + int nBufLen = GPIParams.Size; + int pRetLen = 0; + IntPtr ptrBuf = Marshal.AllocHGlobal(GPIParams.Size); + Marshal.StructureToPtr(entity, ptrBuf, true); + try + { + ret = DaHuaOriSDK.CLIENT_QueryDevState(LoginId, (int)DaHuaOriSDK.EM_DEVICE_STATE.PTZ_LOCATION, ptrBuf, nBufLen, ref pRetLen, 3000); + if (!ret) { BuildException(); return PtzInfo.Default; } + object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); + if (objBuf == null) return PtzInfo.Default; + entity = (DaHuaOriSDK.DH_PTZ_LOCATION_INFO)objBuf; + return PtzInfo.New(entity.nPTZPan, entity.nPTZTilt, entity.nPTZZoom); + } + finally + { + Marshal.FreeHGlobal(ptrBuf); + } + } + + public override bool TryGetPtzInfo(out PtzInfo ptzInfo) + { + bool ret = ConnectSuccess(); + if (!ret) { ptzInfo = PtzInfo.Default; return false; } + + DaHuaOriSDK.DH_PTZ_LOCATION_INFO entity = new(); + int nBufLen = GPIParams.Size; + int pRetLen = 0; + IntPtr ptrBuf = Marshal.AllocHGlobal(GPIParams.Size); + Marshal.StructureToPtr(entity, ptrBuf, true); + try + { + ret = DaHuaOriSDK.CLIENT_QueryDevState(LoginId, (int)DaHuaOriSDK.EM_DEVICE_STATE.PTZ_LOCATION, ptrBuf, nBufLen, ref pRetLen, 3000); + if (!ret) { BuildException(); ptzInfo = PtzInfo.Default; return false; } + object? objBuf = Marshal.PtrToStructure(ptrBuf, GPIParams.Type); + if (objBuf == null) { ptzInfo = PtzInfo.Default; return false; } + entity = (DaHuaOriSDK.DH_PTZ_LOCATION_INFO)objBuf; + ptzInfo = PtzInfo.New(entity.nPTZPan, entity.nPTZTilt, entity.nPTZZoom); + return true; + } + finally + { + Marshal.FreeHGlobal(ptrBuf); + } + } + + public override bool PtzMove(int cmd, int stop, int speed) + { + //if (!ConnectSuccess()) return false; + //if (stop == 1) cmd = YuShiOriSDK.ALLSTOP; + //int channel = 1; + //int flag = YuShiOriSDK.NETDEV_PTZControl_Other(LoginId, channel, cmd, speed); + //return flag == YuShiOriSDK.TRUE; + + if (!ConnectSuccess()) return false; + + //DaHuaOriSDK.CLIENT_DHPTZControlEx2(); + + + return true; + } + + public override bool PtzPreset(int cmd, int presetId) + { + //if (!ConnectSuccess()) return false; + //int channel = 1; + //int flag = YuShiOriSDK.NETDEV_PTZPreset_Other(LoginId, channel, cmd, Array.Empty(), presetId); + //return flag == YuShiOriSDK.TRUE; + if (!ConnectSuccess()) return false; + return true; + } + + #endregion Ptz Method + + #region Video Method + + public override void StartPlay(IntPtr hwnd) + { + if (!ConnectSuccess() || IsPlaying()) return; + int channel = 1; + RealplayHandle = DaHuaOriSDK.CLIENT_RealPlayEx(LoginId, channel, hwnd, DaHuaOriSDK.EM_RealPlayType.Realplay); + if (RealplayHandle == IntPtr.Zero) BuildException(); + } + + public override void StopPlay() + { + if (!IsPlaying()) return; + bool flag = DaHuaOriSDK.CLIENT_StopRealPlayEx(RealplayHandle); + RealplayHandle = IntPtr.Zero; + if (flag) BuildException(); + } + + public override bool IsPlaying() + { + return RealplayHandle != IntPtr.Zero; + } + + #endregion Video Method +} \ No newline at end of file diff --git a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs index 99a55f5..3076f50 100644 --- a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs @@ -6,7 +6,7 @@ public static class HiKOriSDK { #region Lib Attr - public const string LibHcNetSDK = @"./libs/hik-win64/HCNetSDK.dll"; + public const string LibHcNetSDK = @"./libs/hk-win64/HCNetSDK.dll"; #endregion Lib Attr @@ -42,6 +42,9 @@ public static class HiKOriSDK public const int SERIALNO_LEN = 48; //序列号长度 + public const int PtzSpeedMin = 1; + public const int PtzSpeedMax = 7; + #region 用于 NET_DVR_SetDVRConfig 和 NET_DVR_GetDVRConfig public const int NET_DVR_SET_PTZPOS = 292; //云台设置PTZ位置 @@ -70,10 +73,10 @@ public static class HiKOriSDK #region SDK Struct //NET_DVR_Login()参数结构 - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct NET_DVR_DEVICEINFO { - [MarshalAsAttribute( + [MarshalAs( UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1 @@ -89,10 +92,10 @@ public static class HiKOriSDK } //NET_DVR_Login_V30()参数结构 - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct NET_DVR_DEVICEINFO_V30 { - [MarshalAsAttribute( + [MarshalAs( UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1 @@ -158,7 +161,7 @@ public static class HiKOriSDK // byLanguageType 等于0 表示 老设备 // byLanguageType & 0x1表示支持中文 // byLanguageType & 0x2表示支持英文 - [MarshalAsAttribute( + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 9, ArraySubType = UnmanagedType.I1 @@ -167,7 +170,7 @@ public static class HiKOriSDK } //球机位置信息 - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct NET_DVR_PTZPOS { public ushort wAction; //获取时该字段无效 @@ -177,7 +180,7 @@ public static class HiKOriSDK } //球机范围信息 - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct NET_DVR_PTZSCOPE { public ushort wPanPosMin; //水平参数min @@ -196,7 +199,7 @@ public static class HiKOriSDK public const int PLAN_ID_LEN = 32; //预览V40接口 - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] public struct NET_DVR_PREVIEWINFO { public Int32 lChannel; //通道号 @@ -207,7 +210,7 @@ public static class HiKOriSDK public bool bPassbackRecord; //0-不启用录像回传,1启用录像回传 public byte byPreviewMode; //预览模式,0-正常预览,1-延迟预览 - [MarshalAsAttribute( + [MarshalAs( UnmanagedType.ByValArray, SizeConst = STREAM_ID_LEN, ArraySubType = UnmanagedType.I1 @@ -220,7 +223,7 @@ public static class HiKOriSDK public uint dwDisplayBufNum; //播放库播放缓冲区最大缓冲帧数,范围1-50,置0时默认为1 public byte byNPQMode; //NPQ是直连模式,还是过流媒体 0-直连 1-过流媒体 - [MarshalAsAttribute( + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 215, ArraySubType = UnmanagedType.I1 diff --git a/EC.Util/CameraSDK/HiK/HiKSDK.cs b/EC.Util/CameraSDK/HiK/HiKSDK.cs index 7489568..ad92565 100644 --- a/EC.Util/CameraSDK/HiK/HiKSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKSDK.cs @@ -8,7 +8,7 @@ public class HiKSDK : ICameraSDK private int LoginId { get; set; } = -1; - private int realplayHandle { get; set; } = -1; + private int RealplayHandle { get; set; } = -1; #endregion Attr @@ -50,12 +50,12 @@ public class HiKSDK : ICameraSDK { uint errCode = HiKOriSDK.NET_DVR_GetLastError(); if (errCode == 0) return; - throw CameraException.New(CameraManufactor.HiK, (int)errCode); + throw CameraException.New(CameraInfo, (int)errCode); } #endregion Base Method - #region Main Method + #region Ptz Method private static class GPIParams { @@ -121,34 +121,27 @@ public class HiKSDK : ICameraSDK } } - #endregion Main Method - - #region Ptz Method - - public void PtzMove(uint[] args) + public override bool PtzMove(int cmd, int stop, int speed) { - bool ret = ConnectSuccess(); - if (!ret || args == null || args.Length < 3) return; + if (!ConnectSuccess()) return false; int lChannel = 1; - HiKOriSDK.NET_DVR_PTZControlWithSpeed_Other(LoginId, lChannel, args[0], args[1], args[2]); + return HiKOriSDK.NET_DVR_PTZControlWithSpeed_Other(LoginId, lChannel, (uint)cmd, (uint)stop, (uint)speed); } - public void PtzPreset(uint[] args) + public override bool PtzPreset(int cmd, int presetId) { - bool ret = ConnectSuccess(); - if (!ret || args == null || args.Length < 2) return; + if (!ConnectSuccess()) return false; int lChannel = 1; - HiKOriSDK.NET_DVR_PTZPreset_Other(LoginId, lChannel, args[0], args[1]); + return HiKOriSDK.NET_DVR_PTZPreset_Other(LoginId, lChannel, (uint)cmd, (uint)presetId); } #endregion Ptz Method #region Video Method - public void StartPlay(IntPtr hwnd) + public override void StartPlay(IntPtr hwnd) { - bool ret = ConnectSuccess(); - if (!ret) return; + if (!ConnectSuccess() || IsPlaying()) return; HiKOriSDK.NET_DVR_PREVIEWINFO previewInfo = new() { hPlayWnd = hwnd, //预览窗口 @@ -161,17 +154,21 @@ public class HiKSDK : ICameraSDK byPreviewMode = 0 }; IntPtr pUser = new(); //用户数据 - realplayHandle = HiKOriSDK.NET_DVR_RealPlay_V40(LoginId, ref previewInfo, null, pUser); - if (realplayHandle < 0) BuildException(); + RealplayHandle = HiKOriSDK.NET_DVR_RealPlay_V40(LoginId, ref previewInfo, null, pUser); + if (RealplayHandle < 0) BuildException(); } - public void StopPlay() + public override void StopPlay() { - if (realplayHandle >= 0) - { - HiKOriSDK.NET_DVR_StopRealPlay(realplayHandle); - realplayHandle = -1; - } + if (!IsPlaying()) return; + bool flag = HiKOriSDK.NET_DVR_StopRealPlay(RealplayHandle); + RealplayHandle = -1; + if (!flag) BuildException(); + } + + public override bool IsPlaying() + { + return RealplayHandle >= 0; } #endregion Video Method diff --git a/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs b/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs new file mode 100644 index 0000000..0343a95 --- /dev/null +++ b/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs @@ -0,0 +1,221 @@ +using System.Runtime.InteropServices; + +namespace EC.Util.CameraSDK; + +public static class YuShiOriSDK +{ + #region Lib Attr + + public const string LibYsNetSDK = @"./libs/ys-win64/NetDEVSDK.dll"; + + #endregion Lib Attr + + static YuShiOriSDK() + { + GlobalInit(); + } + + #region Global + + public static bool InitSuccess { get; private set; } + + public static bool GlobalInit() + { + if (InitSuccess) return true; + bool ret = NETDEV_Init(); + InitSuccess = ret; + if (!ret) throw new Exception("YuShiOriSDK global init failure."); + return ret; + } + + public static bool GlobalDestory() + { + if (!InitSuccess) return true; + bool ret = NETDEV_Cleanup(); + if (ret) InitSuccess = false; + return ret; + } + + #endregion Global + + #region SDK Const + + public const int TRUE = 1; + public const int FALSE = 0; + + public const int PtzSpeedMin = 1; + public const int PtzSpeedMax = 9; + + /* Common length */ + public const int NETDEV_LEN_64 = 64; + public const int NETDEV_LEN_128 = 128; + public const int NETDEV_LEN_132 = 132; + public const int NETDEV_LEN_260 = 260; + + /* NETDEV_PTZ_E */ + public const int ZOOMTELE_STOP = 0x0301; /* Zoom in stop */ + public const int ZOOMTELE = 0x0302; /* Zoom in */ + public const int ZOOMWIDE_STOP = 0x0303; /* Zoom out stop */ + public const int ZOOMWIDE = 0x0304; /* Zoom out */ + public const int TILTUP = 0x0402; /* Tilt up */ + public const int TILTDOWN = 0x0404; /* Tilt down */ + public const int PANRIGHT = 0x0502; /* Pan right */ + public const int PANLEFT = 0x0504; /* Pan left */ + public const int LEFTUP = 0x0702; /* Move up left */ + public const int LEFTDOWN = 0x0704; /* Move down left */ + public const int RIGHTUP = 0x0802; /* Move up right */ + public const int RIGHTDOWN = 0x0804; /* Move down right */ + public const int ALLSTOP = 0x0901; /* All-stop command word */ + public const int FOCUS_AND_IRIS_STOP = 0x0907; /* Focus & Iris-stop command word */ + public const int MOVE_STOP = 0x0908; /* move stop command word */ + public const int ZOOM_STOP = 0x0909; /* zoom stop command word */ + /* NETDEV_PTZ_PRESETCMD_E */ + public const int PRESET_SET = 0; /* Set preset */ + public const int PRESET_CLE = 1; /* Clear preset */ + public const int PRESET_GOTO = 2; /* Go to preset */ + + public enum NETDEV_LIVE_STREAM_INDEX_E : int + { + NETDEV_LIVE_STREAM_INDEX_MAIN = 0, /* Main stream */ + NETDEV_LIVE_STREAM_INDEX_SUB = 1, /* Sub stream */ + NETDEV_LIVE_STREAM_INDEX_THIRD = 2, /* Third stream */ + + NETDEV_LIVE_STREAM_INDEX_INVALID + } + + public enum NETDEV_PROTOCAL_E : int + { + NETDEV_TRANSPROTOCAL_RTPUDP = 0, /* UDP */ + NETDEV_TRANSPROTOCAL_RTPTCP = 1 /* TCP */ + } + + public enum NETDEV_PICTURE_FLUENCY_E + { + NETDEV_PICTURE_REAL = 0, /* Real-time first */ + NETDEV_PICTURE_FLUENCY = 1, /* Fluency first */ + NETDEV_PICTURE_BALANCE_NEW = 3, /* Balance */ + NETDEV_PICTURE_RTMP_FLUENCY = 4, /* RTMP fluency first */ + + NETDEV_PICTURE_FLUENCY_INVALID = 0xff /* Invalid value */ + } + + #endregion SDK Const + + #region SDK Struct + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_DEVICE_LOGIN_INFO_S + { + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_260)] + public string szIPAddr; /* IP地址/域名 */ + + public int dwPort; /* 端口号 */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_132)] + public string szUserName; /* 用户名 */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_128)] + public string szPassword; /* 密码 */ + + public int dwLoginProto; /* 登录协议, 参见NETDEV_LOGIN_PROTO_E */ + public int dwDeviceType; /* 设备类型, 参见NETDEV_DEVICE_TYPE_E */ + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public byte[] byRes; /* Reserved */ + }; + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_SELOG_INFO_S + { + public int dwSELogCount; + public int dwSELogTime; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] byRes; + }; + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_VIDEO_CHL_DETAIL_INFO_S + { + public int dwChannelID; + public int bPtzSupported; /* Whether ptz is supported */ + public int enStatus; /* Channel status */ + public int dwStreamNum; /* Number of streams */ + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NETDEV_LEN_64)] + public string szChnName; /* Device serial number */ + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] szReserve; + } + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_PTZ_STATUS_S + { + public float fPanTiltX; /* 绝对水平坐标 Absolute horizontal coordinates*/ + public float fPanTiltY; /* 绝对竖直坐标 Absolute vertical coordinates*/ + public float fZoomX; /* 绝对聚焦倍数 Absolute multiples*/ + public int enPanTiltStatus;/* 云台状态 PTZ Status*/ + public int enZoomStatus; /* 聚焦状态 Focus Status*/ + }; + + [StructLayout(LayoutKind.Sequential)] + public struct NETDEV_PREVIEWINFO_S + { + public int dwChannelID; /* ID Channel ID */ + public int dwStreamType; /* #NETDEV_LIVE_STREAM_INDEX_E Stream type, see enumeration #NETDEV_LIVE_STREAM_INDEX_E */ + public int dwLinkMode; /* #NETDEV_PROTOCAL_E Transport protocol, see enumeration #NETDEV_PROTOCAL_E */ + public IntPtr hPlayWnd; /* Play window handle */ + public int dwFluency; /* #NETDEV_PICTURE_FLUENCY_E image play fluency*/ + public int dwStreamMode; /* #NETDEV_STREAM_MODE_E start stream mode see #NETDEV_STREAM_MODE_E*/ + public int dwLiveMode; /* #NETDEV_PULL_STREAM_MODE_E Rev. Flow pattern */ + public int dwDisTributeCloud; /* #NETDEV_DISTRIBUTE_CLOUD_SRV_E distribution */ + public int dwallowDistribution; /* allow or no distribution*/ + public int dwTransType; /* 传输类型,参见枚举# NETDEV_TRANS_TYPE_E */ + public int dwStreamProtocol; /* 起流协议,参见枚举# NETDEV_START_STREAM_PROT_E */ + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 236)] + public byte[] szReserve; /* Reserved */ + } + + #endregion SDK Struct + + #region Common Method + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Init(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Cleanup(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_GetLastError(); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr NETDEV_Login_V30(ref NETDEV_DEVICE_LOGIN_INFO_S pstDevLoginInfo, ref NETDEV_SELOG_INFO_S pstSELogInfo); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_Logout(IntPtr lpUserID); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_QueryVideoChlDetailList(IntPtr lpUserID, ref int pdwChlCount, IntPtr pstVideoChlList); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern bool NETDEV_PTZGetStatus(IntPtr lpUserID, int dwChannelID, ref NETDEV_PTZ_STATUS_S pstPTZStaus); + + //public boolean NETDEV_GetDevConfig(Pointer lpUserID, int dwChannelID, int dwCommand, Pointer lpOutBuffer, int dwOutBufferSize, IntByReference pdwBytesReturned); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_PTZControl_Other(IntPtr lpUserID, int dwChannelID, int dwPTZCommand, int dwSpeed); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_PTZPreset_Other(IntPtr lpUserID, int dwChannelID, int dwPTZPresetCmd, byte[] szPresetName, int dwPresetID); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr NETDEV_RealPlay(IntPtr lpUserID, ref NETDEV_PREVIEWINFO_S pstPreviewInfo, IntPtr cbPlayDataCallBack, IntPtr lpUserData); + + [DllImport(LibYsNetSDK, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] + public static extern int NETDEV_StopRealPlay(IntPtr lpRealHandle); + + #endregion Common Method +} \ No newline at end of file diff --git a/EC.Util/CameraSDK/YuShi/YuShiSDK.cs b/EC.Util/CameraSDK/YuShi/YuShiSDK.cs new file mode 100644 index 0000000..655bf8b --- /dev/null +++ b/EC.Util/CameraSDK/YuShi/YuShiSDK.cs @@ -0,0 +1,138 @@ +namespace EC.Util.CameraSDK; + +public class YuShiSDK : ICameraSDK +{ + #region Attr + + private IntPtr LoginId { get; set; } = IntPtr.Zero; + + private IntPtr RealplayHandle { get; set; } = IntPtr.Zero; + + #endregion Attr + + public YuShiSDK(CameraInfo cameraInfo) : base(cameraInfo) + { + } + + #region Base Method + + public override bool Init() + { + bool ret = ConnectSuccess(); + if (ret) return true; + + YuShiOriSDK.NETDEV_DEVICE_LOGIN_INFO_S loginInfo = new(); + loginInfo.szIPAddr = CameraInfo.Ip; + loginInfo.dwPort = CameraInfo.Port; + loginInfo.szUserName = CameraInfo.UserName; + loginInfo.szPassword = CameraInfo.Password; + YuShiOriSDK.NETDEV_SELOG_INFO_S logInfo = new(); + LoginId = YuShiOriSDK.NETDEV_Login_V30(ref loginInfo, ref logInfo); + ret = ConnectSuccess(); + + return ret; + } + + public override bool Destory() + { + bool ret = ConnectSuccess(); + if (!ret) return true; + + ret = YuShiOriSDK.NETDEV_Logout(LoginId); + if (ret) LoginId = IntPtr.Zero; + + return ret; + } + + public override bool ConnectSuccess() + { + return LoginId != IntPtr.Zero; + } + + public override void BuildException() + { + int errCode = YuShiOriSDK.NETDEV_GetLastError(); + if (errCode == 0) return; + throw CameraException.New(CameraInfo, errCode); + } + + #endregion Base Method + + #region Ptz Method + + public override PtzInfo GetPtzInfo() + { + bool ret = ConnectSuccess(); + if (!ret) return PtzInfo.Default; + + YuShiOriSDK.NETDEV_PTZ_STATUS_S entity = new(); + ret = YuShiOriSDK.NETDEV_PTZGetStatus(LoginId, 1, ref entity); + if (!ret) { BuildException(); return PtzInfo.Default; } + + return PtzInfo.New(entity.fPanTiltX, entity.fPanTiltY, entity.fZoomX); + } + + public override bool TryGetPtzInfo(out PtzInfo ptzInfo) + { + bool ret = ConnectSuccess(); + if (!ret) { ptzInfo = PtzInfo.Default; return false; } + + YuShiOriSDK.NETDEV_PTZ_STATUS_S entity = new(); + ret = YuShiOriSDK.NETDEV_PTZGetStatus(LoginId, 1, ref entity); + if (!ret) { BuildException(); ptzInfo = PtzInfo.Default; return false; } + + ptzInfo = PtzInfo.New(entity.fPanTiltX, entity.fPanTiltY, entity.fZoomX); + return true; + } + + public override bool PtzMove(int cmd, int stop, int speed) + { + if (!ConnectSuccess()) return false; + if (stop == 1) cmd = YuShiOriSDK.ALLSTOP; + int channel = 1; + int flag = YuShiOriSDK.NETDEV_PTZControl_Other(LoginId, channel, cmd, speed); + return flag == YuShiOriSDK.TRUE; + } + + public override bool PtzPreset(int cmd, int presetId) + { + if (!ConnectSuccess()) return false; + int channel = 1; + int flag = YuShiOriSDK.NETDEV_PTZPreset_Other(LoginId, channel, cmd, Array.Empty(), presetId); + return flag == YuShiOriSDK.TRUE; + } + + #endregion Ptz Method + + #region Video Method + + public override void StartPlay(IntPtr hwnd) + { + if (!ConnectSuccess() || IsPlaying()) return; + YuShiOriSDK.NETDEV_PREVIEWINFO_S stPreviewInfo = new() + { + hPlayWnd = hwnd, + dwChannelID = 1, + dwStreamType = 0, // YuShiOriSDK.NETDEV_LIVE_STREAM_INDEX_E + dwLinkMode = 1, // YuShiOriSDK.NETDEV_PROTOCAL_E + dwFluency = 0, // YuShiOriSDK.NETDEV_PICTURE_FLUENCY_E + }; + RealplayHandle = YuShiOriSDK.NETDEV_RealPlay(LoginId, ref stPreviewInfo, IntPtr.Zero, IntPtr.Zero); + if (RealplayHandle == IntPtr.Zero) BuildException(); + } + + public override void StopPlay() + { + if (!IsPlaying()) return; + int flag = YuShiOriSDK.NETDEV_StopRealPlay(RealplayHandle); + RealplayHandle = IntPtr.Zero; + if (flag == YuShiOriSDK.FALSE) BuildException(); + } + + public override bool IsPlaying() + { + return RealplayHandle != IntPtr.Zero; + } + + #endregion Video Method +} \ No newline at end of file diff --git a/EC.Util/EC.Util.csproj b/EC.Util/EC.Util.csproj index 3ac9eb4..b14e9c0 100644 --- a/EC.Util/EC.Util.csproj +++ b/EC.Util/EC.Util.csproj @@ -7,54 +7,62 @@ - - - - - - - - - - - + + + + + + + + + + + + + - + + PreserveNewest + + PreserveNewest - + + PreserveNewest + + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest diff --git a/EC.Util/Port/SerialPortParam.cs b/EC.Util/Port/SerialPortParam.cs index 0dd221b..d386c80 100644 --- a/EC.Util/Port/SerialPortParam.cs +++ b/EC.Util/Port/SerialPortParam.cs @@ -42,7 +42,7 @@ public class SerialPortParam /// public int ReceivedBytesThreshold { get; set; } - #endregion fields + #endregion Fields public SerialPortParam() { diff --git a/EC.Util/libs/dh-win64/dhnetsdk.dll b/EC.Util/libs/dh-win64/dhnetsdk.dll new file mode 100644 index 0000000..aa3a5e4 Binary files /dev/null and b/EC.Util/libs/dh-win64/dhnetsdk.dll differ diff --git a/EC.Util/libs/hik-win64/AudioRender.dll b/EC.Util/libs/hk-win64/AudioRender.dll similarity index 100% rename from EC.Util/libs/hik-win64/AudioRender.dll rename to EC.Util/libs/hk-win64/AudioRender.dll diff --git a/EC.Util/libs/hik-win64/HCCore.dll b/EC.Util/libs/hk-win64/HCCore.dll similarity index 100% rename from EC.Util/libs/hik-win64/HCCore.dll rename to EC.Util/libs/hk-win64/HCCore.dll diff --git a/EC.Util/libs/hik-win64/HCNetSDK.dll b/EC.Util/libs/hk-win64/HCNetSDK.dll similarity index 100% rename from EC.Util/libs/hik-win64/HCNetSDK.dll rename to EC.Util/libs/hk-win64/HCNetSDK.dll diff --git a/EC.Util/libs/hik-win64/HCNetSDKCom/HCCoreDevCfg.dll b/EC.Util/libs/hk-win64/HCNetSDKCom/HCCoreDevCfg.dll similarity index 100% rename from EC.Util/libs/hik-win64/HCNetSDKCom/HCCoreDevCfg.dll rename to EC.Util/libs/hk-win64/HCNetSDKCom/HCCoreDevCfg.dll diff --git a/EC.Util/libs/hik-win64/HCNetSDKCom/HCPreview.dll b/EC.Util/libs/hk-win64/HCNetSDKCom/HCPreview.dll similarity index 100% rename from EC.Util/libs/hik-win64/HCNetSDKCom/HCPreview.dll rename to EC.Util/libs/hk-win64/HCNetSDKCom/HCPreview.dll diff --git a/EC.Util/libs/hik-win64/HXVA.dll b/EC.Util/libs/hk-win64/HXVA.dll similarity index 100% rename from EC.Util/libs/hik-win64/HXVA.dll rename to EC.Util/libs/hk-win64/HXVA.dll diff --git a/EC.Util/libs/hik-win64/HmMerge.dll b/EC.Util/libs/hk-win64/HmMerge.dll similarity index 100% rename from EC.Util/libs/hik-win64/HmMerge.dll rename to EC.Util/libs/hk-win64/HmMerge.dll diff --git a/EC.Util/libs/hik-win64/PlayCtrl.dll b/EC.Util/libs/hk-win64/PlayCtrl.dll similarity index 100% rename from EC.Util/libs/hik-win64/PlayCtrl.dll rename to EC.Util/libs/hk-win64/PlayCtrl.dll diff --git a/EC.Util/libs/hik-win64/SuperRender.dll b/EC.Util/libs/hk-win64/SuperRender.dll similarity index 100% rename from EC.Util/libs/hik-win64/SuperRender.dll rename to EC.Util/libs/hk-win64/SuperRender.dll diff --git a/EC.Util/libs/hik-win64/libcrypto-1_1-x64.dll b/EC.Util/libs/hk-win64/libcrypto-1_1-x64.dll similarity index 100% rename from EC.Util/libs/hik-win64/libcrypto-1_1-x64.dll rename to EC.Util/libs/hk-win64/libcrypto-1_1-x64.dll diff --git a/EC.Util/libs/hik-win64/libssl-1_1-x64.dll b/EC.Util/libs/hk-win64/libssl-1_1-x64.dll similarity index 100% rename from EC.Util/libs/hik-win64/libssl-1_1-x64.dll rename to EC.Util/libs/hk-win64/libssl-1_1-x64.dll diff --git a/EC.Util/libs/ys-win64/NetDEVSDK.dll b/EC.Util/libs/ys-win64/NetDEVSDK.dll new file mode 100644 index 0000000..b705019 Binary files /dev/null and b/EC.Util/libs/ys-win64/NetDEVSDK.dll differ diff --git a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs index fa0eab5..9dfdbdb 100644 --- a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs +++ b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs @@ -10,6 +10,7 @@ public class AlarmMessage public int warnLevel; /** (必填)报警内容*/ public string warnContent; + public int ChannelNum; /** 处置方式*/ public int dealWay; /** (必填)处置状态(1-未处理,2-已处理)*/ diff --git a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs index e64829d..aed29c0 100644 --- a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs +++ b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs @@ -8,13 +8,14 @@ public static class AlarmMessageHelper { public static AlarmMessage ToAlarmMessage(this TcpAlarmHostMessage msg) { - AlarmCode code = AlarmCodeHelper.Get(msg.AlarmId); + AlarmCode code = AlarmCodeHelper.Get(msg.CID); AlarmMessage obj = new() { labelCode = Convert.ToString(msg.DeviceID), warnType = 3, warnLevel = code.Level, warnContent = code.Content, + ChannelNum = Convert.ToInt32(msg.ChannelNum), dealStatus = 1, createTime = Convert.ToDateTime(msg.AlarmTime), kind = 2, @@ -31,6 +32,7 @@ public static class AlarmMessageHelper warnType = 4, warnLevel = code.Level, warnContent = code.Content, + ChannelNum = msg.ChannelNum, dealStatus = 1, createTime = Convert.ToDateTime(msg.AlarmTime), kind = 2, diff --git a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs index 6a32df8..b18af28 100644 --- a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs +++ b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs @@ -48,7 +48,18 @@ public class AlarmMqttService : IAlarmService public void Start() { Server.StartAsync().Wait(); + ClientConnServer(); + } + + public void Close() + { + Client.DisconnectAsync().Wait(); + Server.StopAsync().Wait(); + } + private void ClientConnServer() + { + if (Client.IsConnected) return; MqttClientOptions mqttClientOptions = new MqttClientOptionsBuilder() .WithTcpServer("127.0.0.1", Config.Port) .WithClientId(Config.ClientId) @@ -57,19 +68,25 @@ public class AlarmMqttService : IAlarmService Client.ConnectAsync(mqttClientOptions, CancellationToken.None); } - public void Close() - { - Client.DisconnectAsync().Wait(); - Server.StopAsync().Wait(); - } - public void SendAlarmMessage(AlarmMessage msg) { MqttApplicationMessage mqttMsg = new MqttApplicationMessageBuilder() .WithTopic(Config.TransmitTopic) .WithPayload(JsonUtil.ToJson(msg)) .Build(); - Client.PublishAsync(mqttMsg, CancellationToken.None).Wait(); + MqttClientPublishResult? result = null; + while (result == null || !result.IsSuccess) + { + try + { + result = Client.PublishAsync(mqttMsg, CancellationToken.None).Result; + } + catch (Exception) + { + ClientConnServer(); + Thread.Sleep(100); + } + } } #endregion Base diff --git a/JiLinApp.Docking/Alarm/AlarmCodeHelper.cs b/JiLinApp.Docking/Alarm/AlarmCodeHelper.cs index 37086db..84d0a99 100644 --- a/JiLinApp.Docking/Alarm/AlarmCodeHelper.cs +++ b/JiLinApp.Docking/Alarm/AlarmCodeHelper.cs @@ -10,7 +10,7 @@ public class AlarmCodeHelper private static readonly List LevelList; private static readonly List TypeList; - #endregion fields + #endregion Fields static AlarmCodeHelper() { @@ -18,10 +18,8 @@ public class AlarmCodeHelper string jsonStr = r.ReadToEnd(); List list = JsonConvert.DeserializeObject>(jsonStr) ?? new(); AlarmCodeDict = list.ToDictionary(item => item.Id, item => item); - LevelList = list.GroupBy(item => item.Level) - .Select(it => it.First().Level).ToList(); - TypeList = list.GroupBy(item => item.Type) - .Select(it => it.First().Type).ToList(); + LevelList = list.GroupBy(item => item.Level).Select(it => it.First().Level).ToList(); + TypeList = list.GroupBy(item => item.Type).Select(it => it.First().Type).ToList(); } public static void Init() diff --git a/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs b/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs index de7d8e5..233a767 100644 --- a/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs +++ b/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs @@ -2,7 +2,9 @@ public class SectorState { - public int id { get; set; }//防区号 + #region Fields + + public int Id { get; set; }//防区号 /*0:防区未使用 1:防区撤防 2:防区布防 @@ -11,13 +13,13 @@ public class SectorState 5:无线防区欠压 6:防区掉线(与主线总线脱离) */ - public int state { get; set; }//防区状态 + public int State { get; set; }//防区状态 - public string stateStr + public string StateStr { get { - switch (state) + switch (State) { case 0: return "防区未使用"; case 1: return "防区撤防"; @@ -26,7 +28,7 @@ public class SectorState case 4: return "防区报警"; case 5: return "无线防区欠压"; case 6: return "防区掉线"; - default: return "未知状态:" + state; + default: return "未知状态:" + State; } } } @@ -39,13 +41,13 @@ public class SectorState 4:泄漏电缆 5:网络或总线多子防区模块 */ - public int type { get; set; }//防区类型,特殊参数需单独查询 + public int Type { get; set; }//防区类型,特殊参数需单独查询 - public string typeStr + public string TypeStr { get { - switch (type) + switch (Type) { case 0: return "普通防区"; case 1: return "张力防区"; @@ -53,15 +55,17 @@ public class SectorState case 3: return "振动光纤"; case 4: return "泄漏电缆"; case 5: return "网络或总线多子防区模块"; - default: return "未知类型:" + type; + default: return "未知类型:" + Type; } } } + #endregion Fields + public SectorState(int id, byte data) { - this.id = id; - state = data & 0x0F; - type = data >> 4; + Id = id; + State = data & 0x0F; + Type = data >> 4; } } \ No newline at end of file diff --git a/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs b/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs index fc2ec7f..5dc29df 100644 --- a/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs +++ b/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs @@ -4,11 +4,13 @@ public class UdpAlarmHostDevice { public int deviceID { get; set; }//设备唯一ID - public string IP { get; set; }//设备IP + public string Ip { get; set; }//设备Ip - public int groupID { get; set; }//分组号,报警主机可划入不同组 + public int Port { get; set; } //设备端口 - public int userID { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分 + public int GroupID { get; set; }//分组号,报警主机可划入不同组 + + public int UserID { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分 /*0x00: 撤防状态 0x04: 在家布防(留守布防有些防区可能是在旁路状态) 0x02:即时布防(所有防区没有延时) @@ -139,8 +141,8 @@ public class UdpAlarmHostDevice public UdpAlarmHostDevice() { deviceID = 0; - groupID = 0; - userID = 0; + GroupID = 0; + UserID = 0; deviceState = -1; deviceWorkState = 0; cellState = 0; diff --git a/JiLinApp.Docking/FenceAlarm/Entity/UdpDatagramReceivedEventArgs.cs b/JiLinApp.Docking/FenceAlarm/Entity/UdpDatagramReceivedEventArgs.cs new file mode 100644 index 0000000..13d433d --- /dev/null +++ b/JiLinApp.Docking/FenceAlarm/Entity/UdpDatagramReceivedEventArgs.cs @@ -0,0 +1,31 @@ +using System.Net; + +namespace JiLinApp.Docking.FenceAlarm; + +/// +/// 接收到数据报文事件参数 +/// +/// 报文类型 +public class UdpDatagramReceivedEventArgs : EventArgs +{ + /// + /// 客户端 + /// + public IPEndPoint Ipep { get; private set; } + + /// + /// 报文 + /// + public T Datagram { get; private set; } + + /// + /// 接收到数据报文事件参数 + /// + /// 客户端 + /// 报文 + public UdpDatagramReceivedEventArgs(IPEndPoint ipep, T datagram) + { + Ipep = ipep ?? throw new ArgumentNullException(nameof(ipep)); + Datagram = datagram; + } +} \ No newline at end of file diff --git a/JiLinApp.Docking/FenceAlarm/Entity/UdpManagerConfig.cs b/JiLinApp.Docking/FenceAlarm/Entity/UdpManagerConfig.cs index 0ab414c..77e74d9 100644 --- a/JiLinApp.Docking/FenceAlarm/Entity/UdpManagerConfig.cs +++ b/JiLinApp.Docking/FenceAlarm/Entity/UdpManagerConfig.cs @@ -6,7 +6,5 @@ public class UdpManagerConfig public int ServerPort { get; set; } - public int DevicePort { get; set; } - public int DeviceHeartKeep { get; set; } } \ No newline at end of file diff --git a/JiLinApp.Docking/FenceAlarm/Service/Udp.cs b/JiLinApp.Docking/FenceAlarm/Service/Udp.cs index d7a5f23..9916825 100644 --- a/JiLinApp.Docking/FenceAlarm/Service/Udp.cs +++ b/JiLinApp.Docking/FenceAlarm/Service/Udp.cs @@ -6,33 +6,38 @@ namespace JiLinApp.Docking.FenceAlarm; public class Udp { - private BackgroundWorker back = null; + #region Fields + + private BackgroundWorker BackWorker { get; } /// - /// 用于UDP发送的网络服务类 + /// 用于UDP接收的网络服务类 /// - private UdpClient udpcSend = null; + private UdpClient RecvUdp { get; } /// - /// 用于UDP接收的网络服务类 + /// 用于UDP发送的网络服务类 /// - private UdpClient udpcRecv; + private UdpClient SendUdp { get; } + + #endregion Fields - public delegate void UDPReceive(string IP, byte[] str);// + #region Ctors - public event UDPReceive myUDPReceive;// + public Udp(int port) : this("0.0.0.0", port) + { + } public Udp(string ip, int port) { - IPEndPoint localIpep = new IPEndPoint( - IPAddress.Parse(ip), port); // 本机IP和监听端口号 - - udpcRecv = new UdpClient(localIpep); - udpcSend = new UdpClient(); - back = new BackgroundWorker(); - back.WorkerSupportsCancellation = true; - back.DoWork += back_DoWork; - back.RunWorkerAsync(); + RecvUdp = new(new IPEndPoint(IPAddress.Parse(ip), port)); + SendUdp = new(new IPEndPoint(IPAddress.Any, 0)); + BackWorker = new BackgroundWorker + { + WorkerSupportsCancellation = true + }; + BackWorker.DoWork += Back_DoWork; + BackWorker.RunWorkerAsync(); } ~Udp() @@ -40,45 +45,64 @@ public class Udp Stop(); } + #endregion Ctors + + #region Server + public void Stop() { - if (back != null) - { - back.CancelAsync(); - back = null; - } - if (udpcRecv != null) - { - udpcRecv.Close(); - udpcRecv = null; - } - if (udpcSend != null) - { - udpcSend.Close(); - udpcSend = null; - } + BackWorker?.CancelAsync(); + RecvUdp?.Close(); + SendUdp?.Close(); } - public bool SendMessage(byte[] sendbytes, string IP, int port) + #endregion Server + + #region Receive + + public delegate void UDPReceive(IPEndPoint ipep, byte[] str); + + public event UDPReceive DatagramReceived; + + private void RaiseDatagramReceived(IPEndPoint ipep, byte[] datagram) { - IPEndPoint remoteIpep = new IPEndPoint( - IPAddress.Parse(IP), port); // 发送到的IP地址和端口号 - int result = udpcSend.Send(sendbytes, sendbytes.Length, remoteIpep); - return result >= sendbytes.Length; + DatagramReceived?.Invoke(ipep, datagram); } - private void back_DoWork(object sender, DoWorkEventArgs e) + #endregion Receive + + #region Send + + public bool SendMessage(string ip, int port, byte[] byteMsg) + { + IPEndPoint ipep = new(IPAddress.Parse(ip), port); // 发送到的IP地址和端口号 + int result = SendUdp.Send(byteMsg, byteMsg.Length, ipep); + bool flag = result >= byteMsg.Length; + Console.WriteLine("Send ok: {0}", flag); + return flag; + } + + public bool SendMessage(IPEndPoint ipep, byte[] byteMsg) + { + int result = SendUdp.Send(byteMsg, byteMsg.Length, ipep); + return result >= byteMsg.Length; + } + + #endregion Send + + private void Back_DoWork(object? sender, DoWorkEventArgs e) { - IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0); - while (!back.CancellationPending) + IPEndPoint remoteIpep = new(IPAddress.Any, 0); + while (BackWorker != null && !BackWorker.CancellationPending) { try { - byte[] bytRecv = udpcRecv.Receive(ref remoteIpep); - myUDPReceive(remoteIpep.Address.ToString(), bytRecv); + byte[] bytRecv = RecvUdp.Receive(ref remoteIpep); + DatagramReceived(remoteIpep, bytRecv); } catch { + throw; } } } diff --git a/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs b/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs index 5d6da5c..e5454f2 100644 --- a/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs +++ b/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs @@ -1,4 +1,5 @@ -using System.Timers; +using System.Net; +using System.Timers; using Timer = System.Timers.Timer; namespace JiLinApp.Docking.FenceAlarm; @@ -8,12 +9,10 @@ public class UdpManager #region Fields private Udp myUdp = null; - private int udp_sendPort = -1; - private int udp_ReceivePort = -1; - private int keep_alive = -1; + private int udp_ReceivePort { get; set; } = -1; + private int keep_alive { get; set; } = -1; private Timer PtzCheckTimer = new(); - - private List deviceList = new(); + private List deviceList { get; set; } = new(); #endregion Fields @@ -72,7 +71,7 @@ public class UdpManager if (state == null || state.sectorList == null) return null; foreach (SectorState p1 in state.sectorList) { - if (p1.id == channel) return p1; + if (p1.Id == channel) return p1; } return null; } @@ -83,10 +82,9 @@ public class UdpManager { string s_IP = config.ServerIp; int s_Port = config.ServerPort; - int d_Port = config.DevicePort; int d_Keep = config.DeviceHeartKeep; - return AlarmHostLogin(s_IP, s_Port, d_Port, d_Keep); + return AlarmHostLogin(s_IP, s_Port, d_Keep); } public bool StopServer() @@ -94,18 +92,17 @@ public class UdpManager return AlarmHostLoginOut(); } - private bool AlarmHostLogin(string IP, int Port, int device_port, int keep_alive) + private bool AlarmHostLogin(string ip, int port, int keep_alive) { if (myUdp != null) AlarmHostLoginOut(); - this.udp_ReceivePort = Port; - this.udp_sendPort = device_port; + this.udp_ReceivePort = port; this.keep_alive = keep_alive; try { //启动UDP协议 - myUdp = new Udp(IP, udp_ReceivePort); - myUdp.myUDPReceive += myUDPReceive; + myUdp = new Udp(udp_ReceivePort); + myUdp.DatagramReceived += myUDPReceive; } catch (Exception ex) { @@ -124,7 +121,7 @@ public class UdpManager PtzCheckTimer.Enabled = false; if (myUdp != null) { - myUdp.myUDPReceive -= myUDPReceive; + myUdp.DatagramReceived -= myUDPReceive; myUdp.Stop(); myUdp = null; } @@ -149,31 +146,33 @@ public class UdpManager public event UDPAlarmCancelEvent OnUdpAlarmCancel; - private void myUDPReceive(string Ip, byte[] str) + private void myUDPReceive(IPEndPoint ipep, byte[] str) { //解码 byte[] msg = AlarmEncode.decodeMessage(str); + string ip = ipep.Address.ToString(); + Console.WriteLine("Receive protocol:" + msg[4]); //解析 switch (msg[4]) { case 0x01: //心跳数据 - analysisHeartMessage(Ip, msg); + AnalysisHeartMessage(ipep, msg); break; case 0x02://报警信息 - AnalysisAlarmMessage(Ip, msg); + AnalysisAlarmMessage(ip, msg); break; case 0x03://防区信息 - analysisAllSectorMessage(Ip, msg); + AnalysisAllSectorMessage(ipep, msg); break; case 0x04://张力防区信息 - analysisSectorMessage(Ip, msg); + AnalysisSectorMessage(ipep, msg); break; case 0x05://报警主机最大防区信息 - analysisMaxSectorMessage(Ip, msg); + AnalysisMaxSectorMessage(ipep, msg); break; case 0x08://返回报警主机设置参数回服务器,无需解析 @@ -182,36 +181,37 @@ public class UdpManager default: break; } - Console.WriteLine("消息类型:" + msg[4]); - sendOK(Ip); + SendOK(ipep); } - private void sendOK(string IP) + private void SendOK(IPEndPoint ipep) { if (myUdp == null) return; - //byte[] bytes = new byte[] { 0x08, 0x12, 0xF0, 0xFA, 0x8F, 0x7F, 0x2E, 0x0D }; byte[] bytes = new byte[] { 0x08, 0x12, 0xF0, 0xFA, 0x8F, 0x06, 0x6B, 0x0D }; - myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), IP, udp_sendPort); + bool flag = myUdp.SendMessage(ipep.Address.ToString(), ipep.Port, AlarmEncode.encodeMessage(bytes)); + //bool flag = myUdp.SendMessage(ipep, AlarmEncode.encodeMessage(bytes)); } - private void analysisHeartMessage(string IP, byte[] msg) + private void AnalysisHeartMessage(IPEndPoint ipep, byte[] msg) { + string ip = ipep.Address.ToString(); int deviceID = ByteToInt(msg, 5); UdpAlarmHostDevice device = getDevice(deviceID); if (device == null) { - device = new UdpAlarmHostDevice(); - device.deviceID = deviceID; - device.userID = ByteToInt(msg, 13); - device.IP = IP; - device.deviceOnlineState = 1; - device.keep_live = keep_alive; + device = new() + { + deviceID = deviceID, + deviceOnlineState = 1, + keep_live = keep_alive + }; deviceList.Add(device); } - device.deviceID = deviceID; - device.IP = IP; - device.groupID = ByteToInt(msg, 9); - device.userID = ByteToInt(msg, 13); + device.Ip = ip; + device.Port = ipep.Port; + device.GroupID = ByteToInt(msg, 9); + device.UserID = ByteToInt(msg, 13); + if (device.deviceState != msg[17]) { if (OnUdpAlarmDeviceState != null) @@ -351,6 +351,7 @@ public class UdpManager 0x02,bytes2[0],bytes2[1],0x00, 0x00,0x04,0x03,0x01 }; + //byte[] encodeMsg = AlarmEncode.encodeMessage(msg); AnalysisAlarmMessage("127.0.0.1", msg); } @@ -519,22 +520,25 @@ public class UdpManager return (num1 * 10 + num2).ToString(); } - private void analysisAllSectorMessage(string IP, byte[] msg) + private void AnalysisAllSectorMessage(IPEndPoint ipep, byte[] msg) { + string ip = ipep.Address.ToString(); int deviceID = ByteToInt(msg, 5); UdpAlarmHostDevice device = getDevice(deviceID); if (device == null) { - device = new UdpAlarmHostDevice(); - device.deviceID = deviceID; - device.IP = IP; - device.deviceOnlineState = 1; - device.keep_live = keep_alive; + device = new() + { + deviceID = deviceID, + deviceOnlineState = 1, + keep_live = keep_alive + }; deviceList.Add(device); } - device.IP = IP; - device.groupID = ByteToInt(msg, 9); - device.userID = ByteToInt(msg, 13); + device.Ip = ip; + device.Port = ipep.Port; + device.GroupID = ByteToInt(msg, 9); + device.UserID = ByteToInt(msg, 13); if (device.sectorList == null) { @@ -554,19 +558,19 @@ public class UdpManager { for (int i = 0; i < list.Count; i++) { - if (list[i].id == state.id) + if (list[i].Id == state.Id) { //设备离线 - if (list[i].state != state.state) + if (list[i].State != state.State) { - reportSectorState(deviceId, state.id, state.state); + reportSectorState(deviceId, state.Id, state.State); } list[i] = state; //防区存在,更新 return; } } list.Add(state);//防区不存在,添加 - reportSectorState(deviceId, state.id, state.state); + reportSectorState(deviceId, state.Id, state.State); } private void reportSectorState(int deviceId, int channel, int state) @@ -610,27 +614,30 @@ public class UdpManager } } - private void analysisSectorMessage(string IP, byte[] msg) + private void AnalysisSectorMessage(IPEndPoint ipep, byte[] msg) { //东北没有张力防区,暂不解析 } - private void analysisMaxSectorMessage(string IP, byte[] msg) + private void AnalysisMaxSectorMessage(IPEndPoint ipep, byte[] msg) { + string ip = ipep.Address.ToString(); int deviceID = ByteToInt(msg, 5); UdpAlarmHostDevice device = getDevice(deviceID); if (device == null) { - device = new UdpAlarmHostDevice(); - device.deviceID = deviceID; - device.IP = IP; - device.deviceOnlineState = 1; - device.keep_live = keep_alive; + device = new() + { + deviceID = deviceID, + deviceOnlineState = 1, + keep_live = keep_alive + }; deviceList.Add(device); } - device.IP = IP; - device.groupID = ByteToInt(msg, 9); - device.userID = ByteToInt(msg, 13); + device.Ip = ip; + device.Port = ipep.Port; + device.GroupID = ByteToInt(msg, 9); + device.UserID = ByteToInt(msg, 13); device.maxSectorNum = msg[17] * 256 + msg[18]; } @@ -661,7 +668,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x60 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -676,7 +683,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x62 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -691,7 +698,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x63 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -706,7 +713,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x64 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -721,7 +728,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x61 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -736,7 +743,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x65 }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -752,7 +759,7 @@ public class UdpManager { byte[] content = getBCDTime(time); byte[] bytes = AlarmEncode.getSendMessage(0x8D, content); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -767,7 +774,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0xA0, null); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -782,7 +789,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0xC0, new byte[] { (byte)(channel / 256), (byte)(channel % 256) }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -797,7 +804,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0xC1, new byte[] { (byte)(channel / 256), (byte)(channel % 256) }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -812,7 +819,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0xC2, new byte[] { (byte)(channel / 256), (byte)(channel % 256) }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { @@ -827,7 +834,7 @@ public class UdpManager if (checkDevice(device, ref error)) { byte[] bytes = AlarmEncode.getSendMessage(0xC3, new byte[] { (byte)(channel / 256), (byte)(channel % 256) }); - return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort); + return myUdp.SendMessage(device.Ip, device.Port, AlarmEncode.encodeMessage(bytes)); } else { diff --git a/JiLinApp.Docking/JiLinApp.Docking.csproj b/JiLinApp.Docking/JiLinApp.Docking.csproj index 2b31c0d..5daedfc 100644 --- a/JiLinApp.Docking/JiLinApp.Docking.csproj +++ b/JiLinApp.Docking/JiLinApp.Docking.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/JiLinApp.Docking/Ptz/DCamera.cs b/JiLinApp.Docking/Ptz/DCamera.cs index 5a2f8e7..b69350b 100644 --- a/JiLinApp.Docking/Ptz/DCamera.cs +++ b/JiLinApp.Docking/Ptz/DCamera.cs @@ -1,6 +1,4 @@ -using System; - -namespace JiLinApp.Docking.Ptz; +namespace JiLinApp.Docking.Ptz; public class DCamera { @@ -13,7 +11,7 @@ public class DCamera #endregion Data3 - #endregion fields + #endregion Fields #region BaseMethod diff --git a/JiLinApp.Docking/Ptz/PelcoD.cs b/JiLinApp.Docking/Ptz/PelcoD.cs index 549358b..4665c16 100644 --- a/JiLinApp.Docking/Ptz/PelcoD.cs +++ b/JiLinApp.Docking/Ptz/PelcoD.cs @@ -1,6 +1,4 @@ -using System; - -namespace JiLinApp.Docking.Ptz; +namespace JiLinApp.Docking.Ptz; public class PelcoD { diff --git a/JiLinApp.Docking/Ptz/PelcoP.cs b/JiLinApp.Docking/Ptz/PelcoP.cs index df7e521..de28170 100644 --- a/JiLinApp.Docking/Ptz/PelcoP.cs +++ b/JiLinApp.Docking/Ptz/PelcoP.cs @@ -1,6 +1,4 @@ -using System; - -namespace JiLinApp.Docking.Ptz; +namespace JiLinApp.Docking.Ptz; /// /// dot.NET Implementation of Pelco P Protocol diff --git a/JiLinApp.Docking/Ptz/PtzCmd.cs b/JiLinApp.Docking/Ptz/PtzCmd.cs index 2e7789c..0c7e366 100644 --- a/JiLinApp.Docking/Ptz/PtzCmd.cs +++ b/JiLinApp.Docking/Ptz/PtzCmd.cs @@ -10,7 +10,8 @@ public class PtzCmd { "PelcoD" => PtzControlType.PelcoD, "PelcoP" => PtzControlType.PelcoP, - "HikSdk" => PtzControlType.HikSdk, + "DCamera" => PtzControlType.PelcoP, + "CameraSdk" => PtzControlType.CameraSdk, _ => PtzControlType.None }; } @@ -36,7 +37,10 @@ public class PtzCmd _ => PtzCmdType.None }; } +} +public class PtzComCmd +{ /// /// GetPelcoDCmd /// GetPelcoPCmd @@ -125,62 +129,174 @@ public class PtzCmd }; return cmd; } +} - public static void HikPtzMove(ref HiKSDK sdk, PtzCmdType cmdType, uint[] args) +public class PtzCameraCmd +{ + public static void PtzMove(ICameraSDK sdk, PtzCmdType cmdType, int[] args) { if (sdk == null || args == null) return; - uint[] arr = new uint[args.Length + 1]; - args.CopyTo(arr, 1); + switch (sdk.CameraInfo.GetManufactor) + { + case CameraManufactor.HiK: + HikPtzMove(sdk, cmdType, args); + break; + + case CameraManufactor.DaHua: + DaHuaPtzMove(sdk, cmdType, args); + break; + + case CameraManufactor.YuShi: + YuShiPtzMove(sdk, cmdType, args); + break; + + default: + break; + } + } + + public static void HikPtzMove(ICameraSDK sdk, PtzCmdType cmdType, int[] args) + { + int stop = args[0], presetId = args[0]; + int speed = (HiKOriSDK.PtzSpeedMin + HiKOriSDK.PtzSpeedMax) / 2; + switch (cmdType) + { + case PtzCmdType.Left: + sdk.PtzMove(HiKOriSDK.PAN_LEFT, stop, speed); + break; + + case PtzCmdType.Right: + sdk.PtzMove(HiKOriSDK.PAN_RIGHT, stop, speed); + break; + + case PtzCmdType.Top: + sdk.PtzMove(HiKOriSDK.TILT_UP, stop, speed); + break; + + case PtzCmdType.Down: + sdk.PtzMove(HiKOriSDK.TILT_DOWN, stop, speed); + break; + + case PtzCmdType.LeftTop: + sdk.PtzMove(HiKOriSDK.UP_LEFT, stop, speed); + break; + + case PtzCmdType.LeftDown: + sdk.PtzMove(HiKOriSDK.DOWN_LEFT, stop, speed); + break; + + case PtzCmdType.RightTop: + sdk.PtzMove(HiKOriSDK.UP_RIGHT, stop, speed); + break; + + case PtzCmdType.RightDown: + sdk.PtzMove(HiKOriSDK.DOWN_RIGHT, stop, speed); + break; + + case PtzCmdType.AutoStart: + sdk.PtzMove(HiKOriSDK.PAN_AUTO, stop, speed); + break; + + case PtzCmdType.PresetGoto: + sdk.PtzPreset(HiKOriSDK.GOTO_PRESET, presetId); + break; + + default: + break; + } + } + + private static void DaHuaPtzMove(ICameraSDK sdk, PtzCmdType cmdType, int[] args) + { + int stop = args[0], presetId = args[0]; + int speed = (DaHuaOriSDK.PtzSpeedMin + DaHuaOriSDK.PtzSpeedMax) / 2; switch (cmdType) { case PtzCmdType.Left: - arr[0] = HiKOriSDK.PAN_LEFT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.LEFT_CONTROL, stop, speed); break; case PtzCmdType.Right: - arr[0] = HiKOriSDK.PAN_RIGHT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHT_CONTROL, stop, speed); break; case PtzCmdType.Top: - arr[0] = HiKOriSDK.TILT_UP; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.UP_CONTROL, stop, speed); break; case PtzCmdType.Down: - arr[0] = HiKOriSDK.TILT_DOWN; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.DOWN_CONTROL, stop, speed); break; case PtzCmdType.LeftTop: - arr[0] = HiKOriSDK.UP_LEFT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.LEFTTOP, stop, speed); break; case PtzCmdType.LeftDown: - arr[0] = HiKOriSDK.DOWN_LEFT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.LEFTDOWN, stop, speed); break; case PtzCmdType.RightTop: - arr[0] = HiKOriSDK.UP_RIGHT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHTTOP, stop, speed); break; case PtzCmdType.RightDown: - arr[0] = HiKOriSDK.DOWN_RIGHT; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHTDOWN, stop, speed); break; case PtzCmdType.AutoStart: - arr[0] = HiKOriSDK.PAN_AUTO; - sdk.PtzMove(arr); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.HORSECTORSCAN, stop, speed); + break; + + case PtzCmdType.PresetGoto: + sdk.PtzPreset((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.GOTOPRESET, presetId); + break; + + default: + break; + } + } + + public static void YuShiPtzMove(ICameraSDK sdk, PtzCmdType cmdType, int[] args) + { + int stop = args[0], presetId = args[0]; + int speed = (YuShiOriSDK.PtzSpeedMax + YuShiOriSDK.PtzSpeedMin) / 2; + switch (cmdType) + { + case PtzCmdType.Left: + sdk.PtzMove(YuShiOriSDK.PANLEFT, stop, speed); + break; + + case PtzCmdType.Right: + sdk.PtzMove(YuShiOriSDK.PANRIGHT, stop, speed); + break; + + case PtzCmdType.Top: + sdk.PtzMove(YuShiOriSDK.TILTUP, stop, speed); + break; + + case PtzCmdType.Down: + sdk.PtzMove(YuShiOriSDK.TILTDOWN, stop, speed); + break; + + case PtzCmdType.LeftTop: + sdk.PtzMove(YuShiOriSDK.LEFTUP, stop, speed); + break; + + case PtzCmdType.LeftDown: + sdk.PtzMove(YuShiOriSDK.LEFTDOWN, stop, speed); + break; + + case PtzCmdType.RightTop: + sdk.PtzMove(YuShiOriSDK.RIGHTUP, stop, speed); + break; + + case PtzCmdType.RightDown: + sdk.PtzMove(YuShiOriSDK.RIGHTDOWN, stop, speed); break; case PtzCmdType.PresetGoto: - arr[0] = HiKOriSDK.GOTO_PRESET; - sdk.PtzPreset(arr); + sdk.PtzPreset(YuShiOriSDK.PRESET_GOTO, presetId); break; default: @@ -194,7 +310,7 @@ public enum PtzControlType PelcoD, PelcoP, DCamera, - HikSdk, + CameraSdk, None, } diff --git a/JiLinApp.Docking/Ptz/PtzConfig.cs b/JiLinApp.Docking/Ptz/PtzConfig.cs index 6bad4ae..3f8c53f 100644 --- a/JiLinApp.Docking/Ptz/PtzConfig.cs +++ b/JiLinApp.Docking/Ptz/PtzConfig.cs @@ -30,7 +30,8 @@ public class PtzControlTypeConfigHelper { "PelcoD" => PtzControlType.PelcoD, "PelcoP" => PtzControlType.PelcoP, - "HikSdk" => PtzControlType.HikSdk, + "DCamera" => PtzControlType.DCamera, + "CameraSdk" => PtzControlType.CameraSdk, _ => PtzControlType.None }; } diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs b/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs index 5b2ecec..ea9ba40 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs @@ -5,16 +5,34 @@ namespace JiLinApp.Docking.VibrateAlarm; public class ClientMessage { - public TcpClient client { get; set; } + #region Fields - public TcpAlarmHostTable host { get; set; } + public TcpClient Client { get; set; } - public string IP + public TcpAlarmHostTable Host { get; set; } + + public List DataList { get; } = new(); + + public Hashtable SectionTable { get; } = new(); + + public List SensorList { get; set; } + + public bool SensorListEmpty { get { - if (host != null) return host.ip; - if (client != null) return client.Client.RemoteEndPoint.ToString().Split(':')[0]; + return SensorList == null || SensorList.Count == 0; + } + } + + public ReaderWriterLockSlim SensorListLock { get; } = new(); + + public string Ip + { + get + { + if (Host != null) return Host.Ip; + if (Client != null) return Client.Client.RemoteEndPoint.ToString().Split(':')[0]; return ""; } } @@ -23,49 +41,43 @@ public class ClientMessage { get { - if (host != null) return host.port; - if (client != null) return client.Client.RemoteEndPoint.ToString().Split(':')[1]; + if (Host != null) return Host.Port; + if (Client != null) return Client.Client.RemoteEndPoint.ToString().Split(':')[1]; return "-1"; } } - public List list { get; set; } - - public Hashtable sectioTable { get; set; } + #endregion Fields public ClientMessage() { - list = new List(); - host = null; - sectioTable = new Hashtable(); } - public List getMessageList() + public void AddData(byte[] bytes) + { + DataList.AddRange(bytes); + } + + public List GetMessageList() { - List msglist = new List(); - while (list.Count >= 19) + List msglist = new(); + while (DataList.Count >= 19) { - if (list[0] == 0xAA && list[1] == 0xAA) + if (DataList[0] == 0xAA && DataList[1] == 0xAA) { - int num = list[17]; - if (list.Count < 19 + num) - { - break; - } - else + int num = DataList[17]; + if (DataList.Count < 19 + num) break; + byte[] bytes = new byte[num + 19]; + for (int i = 0; i < bytes.Length; i++) { - byte[] bytes = new byte[num + 19]; - for (int i = 0; i < bytes.Length; i++) - { - bytes[i] = list[i]; - } - msglist.Add(bytes); - list.RemoveRange(0, num + 19); + bytes[i] = DataList[i]; } + msglist.Add(bytes); + DataList.RemoveRange(0, num + 19); } else { - list.RemoveAt(0); + DataList.RemoveAt(0); } } return msglist; diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/DataMessage.cs b/JiLinApp.Docking/VibrateAlarm/Entity/DataMessage.cs index 7b6aa84..4b3bb87 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/DataMessage.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/DataMessage.cs @@ -4,86 +4,77 @@ namespace JiLinApp.Docking.VibrateAlarm; public class DataMessage { - private byte headA = 0xAA; - private byte headB = 0xAA; //(1)帧头 - public int deviceID { get; set; } //(2)设备ID - - public string sendIP { get; set; } //(3)原地址 - public int sendPort { get; set; }//(3)原地址 - public string receiveIP { get; set; }//(4)目标地址 - public int receivePort { get; set; }//(4)目标地址 - public byte frameNum { get; set; }//(5)帧编号 - public byte functionNum { get; set; }//(6)功能码 - public byte dataLen { get; set; }//(7)传输数据长度 - public byte[] data { get; set; }//(8)传输数据 + private byte HeadA = 0xAA; + private byte HeadB = 0xAA; //(1)帧头 + public int DeviceId { get; set; } //(2)设备ID + public string SendIp { get; set; } //(3)原地址 + public int SendPort { get; set; }//(3)原地址 + public string ReceiveIp { get; set; }//(4)目标地址 + public int ReceivePort { get; set; }//(4)目标地址 + public byte FrameNum { get; set; }//(5)帧编号 + public byte FunctionNum { get; set; }//(6)功能码 + public byte DataLen { get; set; }//(7)传输数据长度 + public byte[] Data { get; set; }//(8)传输数据 public byte CRC { get; set; }//(9)CRC8 - public void decode(byte[] bytes) + public void Decode(byte[] bytes) { - deviceID = bytes[2]; - sendIP = bytes[3].ToString() + "." + bytes[4].ToString() + "." + bytes[5].ToString() + "." + bytes[6].ToString(); - sendPort = bytes[8] * 256 + bytes[7]; - receiveIP = bytes[9].ToString() + "." + bytes[10].ToString() + "." + bytes[11].ToString() + "." + bytes[12].ToString(); - receivePort = bytes[13] * 256 + bytes[14]; - frameNum = bytes[15]; - functionNum = bytes[16]; - dataLen = bytes[17]; - data = new byte[dataLen]; - for (int i = 0; i < dataLen; i++) + DeviceId = bytes[2]; + SendIp = bytes[3].ToString() + "." + bytes[4].ToString() + "." + bytes[5].ToString() + "." + bytes[6].ToString(); + SendPort = bytes[8] * 256 + bytes[7]; + ReceiveIp = bytes[9].ToString() + "." + bytes[10].ToString() + "." + bytes[11].ToString() + "." + bytes[12].ToString(); + ReceivePort = bytes[14] * 256 + bytes[13]; + FrameNum = bytes[15]; + FunctionNum = bytes[16]; + DataLen = bytes[17]; + Data = new byte[DataLen]; + for (int i = 0; i < DataLen; i++) { - data[i] = bytes[18 + i]; + Data[i] = bytes[18 + i]; } - CRC = bytes[18 + dataLen]; + CRC = bytes[18 + DataLen]; } - public byte[] encode() + public byte[] Encode() { - byte[] bytes = new byte[19 + dataLen]; + byte[] bytes = new byte[19 + DataLen]; bytes[0] = bytes[1] = 0xAA; - bytes[2] = (byte)deviceID; + bytes[2] = (byte)DeviceId; - string[] strs = sendIP.Split('.'); + string[] strs = SendIp.Split('.'); bytes[3] = byte.Parse(strs[0]); bytes[4] = byte.Parse(strs[1]); bytes[5] = byte.Parse(strs[2]); bytes[6] = byte.Parse(strs[3]); - bytes[7] = (byte)(sendPort % 256); - bytes[8] = (byte)(sendPort / 256); + bytes[7] = (byte)(SendPort % 256); + bytes[8] = (byte)(SendPort / 256); - string[] strs2 = receiveIP.Split('.'); + string[] strs2 = ReceiveIp.Split('.'); bytes[9] = byte.Parse(strs2[0]); bytes[10] = byte.Parse(strs2[1]); bytes[11] = byte.Parse(strs2[2]); bytes[12] = byte.Parse(strs2[3]); - bytes[13] = (byte)(receivePort % 256); - bytes[14] = (byte)(receivePort / 256); - bytes[15] = frameNum; - bytes[16] = functionNum; - bytes[17] = dataLen; - for (int i = 0; i < dataLen; i++) + bytes[13] = (byte)(ReceivePort % 256); + bytes[14] = (byte)(ReceivePort / 256); + bytes[15] = FrameNum; + bytes[16] = FunctionNum; + bytes[17] = DataLen; + for (int i = 0; i < DataLen; i++) { - bytes[18 + i] = data[i]; + bytes[18 + i] = Data[i]; } bytes[bytes.Length - 1] = CRC8.CRC(bytes, 0, bytes.Length - 1); - Console.WriteLine("发送指令:" + ToHexString(bytes)); return bytes; } - private string ToHexString(byte[] bytes) + public static string ToHexString(byte[] bytes) { - string hexString = string.Empty; - - if (bytes != null) + if (bytes == null) return string.Empty; + StringBuilder builder = new(); + for (int i = 0; i < bytes.Length; i++) { - StringBuilder strB = new StringBuilder(); - - for (int i = 0; i < bytes.Length; i++) - { - strB.Append(bytes[i].ToString("X2") + " "); - } - - hexString = strB.ToString(); + builder.Append(bytes[i].ToString("X2") + " "); } - return hexString; + return builder.ToString(); } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/DataRequest.cs b/JiLinApp.Docking/VibrateAlarm/Entity/DataRequest.cs index d3e39e3..3853202 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/DataRequest.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/DataRequest.cs @@ -2,13 +2,11 @@ public class DataRequest { - public DataMessage request { get; set; } + public DataMessage Request { get; set; } - public DataMessage responce { get; set; } + public DataMessage Responce { get; set; } public DataRequest() { - responce = null; - request = null; } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/SectionState.cs b/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs similarity index 87% rename from JiLinApp.Docking/VibrateAlarm/Entity/SectionState.cs rename to JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs index 0b6339e..1057dcd 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/SectionState.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs @@ -1,6 +1,6 @@ namespace JiLinApp.Docking.VibrateAlarm; -public class SectionState +public class SensorState { public int deviceID { get; set; } @@ -39,7 +39,7 @@ public class SectionState } } - public SectionState(int id, int chan, int state) + public SensorState(int id, int chan, int state) { deviceID = id; channel = chan.ToString(); @@ -47,7 +47,7 @@ public class SectionState alarm = state / 2 % 2; } - public SectionState(int id, int chan, int on, int a) + public SensorState(int id, int chan, int on, int a) { deviceID = id; channel = chan.ToString(); diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs index 4a92739..aa180c3 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs @@ -5,8 +5,8 @@ namespace JiLinApp.Docking.VibrateAlarm; public class TcpAlarmHostMessage { public int Id { get; set; } - public string AlarmId { get; set; }//CID代码 public string AlarmTime { get; set; }//报警时间 + public string CID { get; set; }//CID代码 /*设备信息*/ public int DeviceID { get; set; }//设备唯一ID diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostTable.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostTable.cs index 2a40f91..6e5ba70 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostTable.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostTable.cs @@ -2,15 +2,15 @@ public class TcpAlarmHostTable { - public int id { get; set; } + public int Id { get; set; } - public string name { get; set; } + public string Name { get; set; } - public string lat { get; set; } + public string Ip { get; set; } - public string lng { get; set; } + public string Port { get; set; } - public string ip { get; set; } + public string Lat { get; set; } - public string port { get; set; } + public string Lng { get; set; } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpSectionTable.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpSectionTable.cs deleted file mode 100644 index 42b4ff2..0000000 --- a/JiLinApp.Docking/VibrateAlarm/Entity/TcpSectionTable.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace JiLinApp.Docking.VibrateAlarm; - -public class TcpSectionTable -{ - public int id { get; set; } - public int deviceID { get; set; } - - public string name { get; set; } - public string lat { get; set; } - - public string lng { get; set; } - - public string channel { get; set; } - - public string mode { get; set; } - public string sensitivity { get; set; } -} \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpSensorTable.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpSensorTable.cs new file mode 100644 index 0000000..29aa479 --- /dev/null +++ b/JiLinApp.Docking/VibrateAlarm/Entity/TcpSensorTable.cs @@ -0,0 +1,20 @@ +namespace JiLinApp.Docking.VibrateAlarm; + +public class TcpSensorTable +{ + public int Id { get; set; } + + public int DeviceId { get; set; } + + public string Name { get; set; } + + public string Lat { get; set; } + + public string Lng { get; set; } + + public string Channel { get; set; } + + public string Mode { get; set; } + + public string Sensitivity { get; set; } +} \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs b/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs index 7eb9fba..196bc5f 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs @@ -10,101 +10,89 @@ public class AsyncTcpServer : IDisposable { #region Fields - private TcpListener _listener; - private ConcurrentDictionary _clients; - private bool _disposed = false; + private TcpListener Listener { get; set; } + + private ConcurrentDictionary Clients { get; } + + #region Properties + + /// + /// 监听的IP地址 + /// + public IPAddress Address { get; private set; } + + /// + /// 监听的端口 + /// + public int Port { get; private set; } + + /// + /// 通信使用的编码 + /// + public Encoding Encoding { get; set; } + + public bool Disposed { get; private set; } + + #endregion Properties #endregion Fields #region Ctors - private byte[] inOptionValues; + private byte[] InOptionValues { get; set; } /// /// 异步TCP服务器 /// - /// 监听的端口 - public AsyncTcpServer(int listenPort) - : this(IPAddress.Any, listenPort) + /// 监听的端口 + public AsyncTcpServer(int port) : this(IPAddress.Any, port) { - uint dummy = 0; - inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; - BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); } /// /// 异步TCP服务器 /// - /// 监听的终结点 - public AsyncTcpServer(IPEndPoint localEP) - : this(localEP.Address, localEP.Port) + /// 监听的终结点 + public AsyncTcpServer(IPEndPoint ipep) : this(ipep.Address, ipep.Port) { - uint dummy = 0; - inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; - BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); } /// /// 异步TCP服务器 /// - /// 监听的IP地址 - /// 监听的端口 - public AsyncTcpServer(IPAddress localIPAddress, int listenPort) + /// 监听的IP地址 + /// 监听的端口 + public AsyncTcpServer(IPAddress address, int port) { uint dummy = 0; - inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; - BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); - BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); - Address = localIPAddress; - Port = listenPort; + InOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; + BitConverter.GetBytes((uint)1).CopyTo(InOptionValues, 0); + BitConverter.GetBytes((uint)1000).CopyTo(InOptionValues, Marshal.SizeOf(dummy)); + BitConverter.GetBytes((uint)1000).CopyTo(InOptionValues, Marshal.SizeOf(dummy) * 2); + Address = address; + Port = port; Encoding = Encoding.Default; + Listener = new(address, port); + Clients = new(); + Listener.AllowNatTraversal(true); + } - _clients = new ConcurrentDictionary(); - - _listener = new TcpListener(Address, Port); - _listener.AllowNatTraversal(true); + ~AsyncTcpServer() + { + Stop(); } #endregion Ctors - #region Properties - - /// - /// 服务器是否正在运行 - /// - public bool IsRunning { get; private set; } - - /// - /// 监听的IP地址 - /// - public IPAddress Address { get; private set; } - - /// - /// 监听的端口 - /// - public int Port { get; private set; } - - /// - /// 通信使用的编码 - /// - public Encoding Encoding { get; set; } - - #endregion Properties - #region Server /// /// 启动服务器 /// /// 异步TCP服务器 - public AsyncTcpServer Start() + public void Start() { - return Start(30); + Start(30); } /// @@ -112,216 +100,194 @@ public class AsyncTcpServer : IDisposable /// /// 服务器所允许的挂起连接序列的最大长度 /// 异步TCP服务器 - public AsyncTcpServer Start(int backlog) + public void Start(int backlog) { - if (IsRunning) return this; - - IsRunning = true; - _listener.Start(backlog); - ContinueAcceptTcpClient(_listener); - - return this; + if (IsRunning()) return; + try + { + Listener.Start(backlog); + AcceptTcpClient(Listener); + } + catch (Exception) + { + throw; + } } /// /// 停止服务器 /// /// 异步TCP服务器 - public AsyncTcpServer Stop() + public void Stop() { - if (!IsRunning) return this; - + if (!IsRunning()) return; try { - _listener.Stop(); - - foreach (var client in _clients.Values) - { - client.TcpClient.Client.Disconnect(false); - } - _clients.Clear(); + Listener.Stop(); } - catch (ObjectDisposedException ex) + catch (Exception) { - Console.WriteLine("对象注销错误:" + ex.Message); + throw; } - catch (SocketException ex) + finally { - Console.WriteLine("socket错误:" + ex.Message); + foreach (var client in Clients.Values) + { + client.TcpClient.Client.Disconnect(false); + } + Clients.Clear(); } - IsRunning = false; + } - return this; + public bool IsRunning() + { + return Listener != null && Listener.Server.IsBound; } - private void ContinueAcceptTcpClient(TcpListener tcpListener) + public ICollection GetAllClient() { - try - { - tcpListener.BeginAcceptTcpClient(new AsyncCallback(HandleTcpClientAccepted), tcpListener); - } - catch (ObjectDisposedException ex) - { - Console.WriteLine("对象注销错误:" + ex.Message); - } - catch (SocketException ex) - { - Console.WriteLine("socket错误:" + ex.Message); - } + return Clients.Values; } #endregion Server #region Receive - private void HandleTcpClientAccepted(IAsyncResult ar) + private void AcceptTcpClient(TcpListener listener) { - if (!IsRunning) return; + listener.BeginAcceptTcpClient(HandleTcpClientAccepted, listener); + } - TcpListener tcpListener; - TcpClient tcpClient; + private void ReadBuffer(TcpClientState internalClient, NetworkStream networkStream) + { + networkStream.BeginRead(internalClient.Buffer, 0, internalClient.Buffer.Length, HandleDatagramReceived, internalClient); + } + + private void HandleTcpClientAccepted(IAsyncResult ar) + { + if (!IsRunning()) return; + TcpListener? listener; + TcpClient? client; try { - tcpListener = (TcpListener)ar.AsyncState; - tcpClient = tcpListener.EndAcceptTcpClient(ar); - tcpClient.Client.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); + listener = ar.AsyncState as TcpListener; + client = listener?.EndAcceptTcpClient(ar); + client?.Client.IOControl(IOControlCode.KeepAliveValues, InOptionValues, null); } - catch (ObjectDisposedException ex) + catch (Exception) { - Console.WriteLine("对象注销错误:" + ex.Message); - return; + throw; } - if (!tcpClient.Connected) return; + if (listener == null || client == null || !client.Connected) return; - byte[] buffer = new byte[tcpClient.ReceiveBufferSize]; - TcpClientState internalClient = new TcpClientState(tcpClient, buffer); + byte[] buffer = new byte[client.ReceiveBufferSize]; + TcpClientState internalClient = new(client, buffer); // add client connection to cache - string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); - _clients.AddOrUpdate(tcpClientKey, internalClient, (n, o) => { return internalClient; }); - RaiseClientConnected(tcpClient); + string clientKey = client.Client.RemoteEndPoint?.ToString() ?? ""; + if (clientKey == "") return; + Clients.AddOrUpdate(clientKey, internalClient, (n, o) => { return internalClient; }); + RaiseClientConnected(client); // begin to read data - NetworkStream networkStream = internalClient.NetworkStream; - ContinueReadBuffer(internalClient, networkStream); - - // keep listening to accept next connection - ContinueAcceptTcpClient(tcpListener); - } - - private void HandleDatagramReceived(IAsyncResult ar) - { - if (!IsRunning) return; - try { - TcpClientState internalClient = (TcpClientState)ar.AsyncState; - if (!internalClient.TcpClient.Connected) return; - NetworkStream networkStream = internalClient.NetworkStream; - - int numberOfReadBytes = 0; - try - { - // if the remote host has shutdown its connection, - // read will immediately return with zero bytes. - numberOfReadBytes = networkStream.EndRead(ar); - } - catch (Exception ex) - { - Console.WriteLine("错误:" + ex.Message); - numberOfReadBytes = 0; - } - - if (numberOfReadBytes == 0) - { - // connection has been closed - TcpClientState internalClientToBeThrowAway; - string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString(); - _clients.TryRemove(tcpClientKey, out internalClientToBeThrowAway); - RaiseClientDisconnected(internalClient.TcpClient); - return; - } - - // received byte and trigger event notification - byte[] receivedBytes = new byte[numberOfReadBytes]; - Buffer.BlockCopy(internalClient.Buffer, 0, receivedBytes, 0, numberOfReadBytes); - RaiseDatagramReceived(internalClient, receivedBytes); - - // continue listening for tcp datagram packets - ContinueReadBuffer(internalClient, networkStream); + ReadBuffer(internalClient, networkStream); } - catch (InvalidOperationException ex) + catch (Exception) { - Console.WriteLine("错误:" + ex.Message); + Clients.TryRemove(clientKey, out _); + RaiseClientDisconnected(internalClient.TcpClient); + return; } + + // keep listening to accept next connection + AcceptTcpClient(listener); } - private void ContinueReadBuffer(TcpClientState internalClient, NetworkStream networkStream) + private void HandleDatagramReceived(IAsyncResult ar) { + if (!IsRunning()) return; + TcpClientState? internalClient = ar.AsyncState as TcpClientState; + if (internalClient == null) return; + string clientKey = internalClient.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; + if (clientKey == "") return; + if (!internalClient.TcpClient.Connected) + { + // connection has been closed + Clients.TryRemove(clientKey, out _); + RaiseClientDisconnected(internalClient.TcpClient); + } + + NetworkStream networkStream; + int readBytesNum; try { - networkStream.BeginRead(internalClient.Buffer, 0, internalClient.Buffer.Length, HandleDatagramReceived, internalClient); + networkStream = internalClient.NetworkStream; + // if the remote host has shutdown its connection, + // read will immediately return with zero bytes. + readBytesNum = networkStream.EndRead(ar); } - catch (ObjectDisposedException ex) + catch (Exception) { - Console.WriteLine("对象注销错误:" + ex.Message); + throw; } + if (readBytesNum == 0) + { + // connection has been closed + Clients.TryRemove(clientKey, out _); + RaiseClientDisconnected(internalClient.TcpClient); + return; + } + + // received byte and trigger event notification + byte[] receivedBytes = new byte[readBytesNum]; + Buffer.BlockCopy(internalClient.Buffer, 0, receivedBytes, 0, readBytesNum); + RaiseDatagramReceived(internalClient, receivedBytes); + + // continue listening for tcp datagram packets + ReadBuffer(internalClient, networkStream); } #endregion Receive - #region Events + #region Register Events /// - /// 接收到数据报文事件 + /// 与客户端的连接已建立事件 /// - public event EventHandler> DatagramReceived; - - private void RaiseDatagramReceived(TcpClientState sender, byte[] datagram) - { - if (DatagramReceived != null) - { - DatagramReceived(this, new TcpDatagramReceivedEventArgs(sender, datagram)); - } - } + public event EventHandler? ClientConnected; /// - /// 与客户端的连接已建立事件 + /// 与客户端的连接已断开事件 /// - public event EventHandler ClientConnected; + public event EventHandler? ClientDisconnected; /// - /// 与客户端的连接已断开事件 + /// 接收到数据报文事件 /// - public event EventHandler ClientDisconnected; + public event EventHandler>? DatagramReceived; - private void RaiseClientConnected(TcpClient tcpClient) + private void RaiseClientConnected(TcpClient client) { - if (ClientConnected != null) - { - ClientConnected(this, new TcpClientConnectedEventArgs(tcpClient)); - } + ClientConnected?.Invoke(this, new TcpClientConnectedEventArgs(client)); } - private void RaiseClientDisconnected(TcpClient tcpClient) + private void RaiseClientDisconnected(TcpClient client) { - if (ClientDisconnected != null) - { - ClientDisconnected(this, new TcpClientDisconnectedEventArgs(tcpClient)); - } + ClientDisconnected?.Invoke(this, new TcpClientDisconnectedEventArgs(client)); } - #endregion Events - - #region Send - - private void GuardRunning() + private void RaiseDatagramReceived(TcpClientState sender, byte[] datagram) { - if (!IsRunning) - throw new InvalidProgramException("This TCP server has not been started yet."); + DatagramReceived?.Invoke(this, new TcpDatagramReceivedEventArgs(sender, datagram)); } + #endregion Register Events + + #region Send + /// /// 发送报文至指定的客户端 /// @@ -329,25 +295,19 @@ public class AsyncTcpServer : IDisposable /// 报文 public void Send(TcpClient tcpClient, byte[] datagram) { - GuardRunning(); - - if (tcpClient == null) - throw new ArgumentNullException("tcpClient"); - - if (datagram == null) - throw new ArgumentNullException("datagram"); - + if (!IsRunning()) return; + if (tcpClient == null || !tcpClient.Connected || datagram == null) return; try { NetworkStream stream = tcpClient.GetStream(); if (stream.CanWrite) { - stream.BeginWrite(datagram, 0, datagram.Length, HandleDatagramWritten, tcpClient); + stream.Write(datagram, 0, datagram.Length); } } - catch (ObjectDisposedException ex) + catch (Exception) { - Console.WriteLine("对象注销错误:" + ex.Message); + throw; } } @@ -367,76 +327,43 @@ public class AsyncTcpServer : IDisposable /// 报文 public void SendToAll(byte[] datagram) { - GuardRunning(); - - foreach (var client in _clients.Values) + if (!IsRunning()) return; + foreach (var client in Clients.Values) { Send(client.TcpClient, datagram); } } - public ICollection GetAllClient() - { - return _clients.Values; - } - /// /// 发送报文至所有客户端 /// /// 报文 public void SendToAll(string datagram) { - GuardRunning(); - + if (!IsRunning()) return; SendToAll(Encoding.GetBytes(datagram)); } - private void HandleDatagramWritten(IAsyncResult ar) - { - try - { - ((TcpClient)ar.AsyncState).GetStream().EndWrite(ar); - } - catch (ObjectDisposedException ex) - { - Console.WriteLine("对象注销错误:" + ex.Message); - } - catch (InvalidOperationException ex) - { - Console.WriteLine("错误:" + ex.Message); - } - catch (IOException ex) - { - Console.WriteLine("错误:" + ex.Message); - } - } - /// /// 发送报文至指定的客户端 /// /// 客户端 /// 报文 - public void SyncSend(TcpClient tcpClient, byte[] datagram) + public void SendAsync(TcpClient tcpClient, byte[] datagram) { - GuardRunning(); - - if (tcpClient == null) - throw new ArgumentNullException("tcpClient"); - - if (datagram == null) - throw new ArgumentNullException("datagram"); - + if (!IsRunning()) return; + if (tcpClient == null || !tcpClient.Connected || datagram == null) return; try { NetworkStream stream = tcpClient.GetStream(); if (stream.CanWrite) { - stream.Write(datagram, 0, datagram.Length); + stream.BeginWrite(datagram, 0, datagram.Length, HandleDatagramWritten, tcpClient); } } - catch (ObjectDisposedException ex) + catch (Exception) { - Console.WriteLine("对象注销错误:" + ex.Message); + throw; } } @@ -445,22 +372,21 @@ public class AsyncTcpServer : IDisposable /// /// 客户端 /// 报文 - public void SyncSend(TcpClient tcpClient, string datagram) + public void SendAsync(TcpClient tcpClient, string datagram) { - SyncSend(tcpClient, Encoding.GetBytes(datagram)); + SendAsync(tcpClient, Encoding.GetBytes(datagram)); } /// /// 发送报文至所有客户端 /// /// 报文 - public void SyncSendToAll(byte[] datagram) + public void SendToAllAsync(byte[] datagram) { - GuardRunning(); - - foreach (var client in _clients.Values) + if (!IsRunning()) return; + foreach (var client in Clients.Values) { - SyncSend(client.TcpClient, datagram); + SendAsync(client.TcpClient, datagram); } } @@ -468,11 +394,15 @@ public class AsyncTcpServer : IDisposable /// 发送报文至所有客户端 /// /// 报文 - public void SyncSendToAll(string datagram) + public void SendToAllAsync(string datagram) { - GuardRunning(); + if (!IsRunning()) return; + SendToAllAsync(Encoding.GetBytes(datagram)); + } - SyncSendToAll(Encoding.GetBytes(datagram)); + private void HandleDatagramWritten(IAsyncResult ar) + { + (ar.AsyncState as TcpClient)?.GetStream().EndWrite(ar); } #endregion Send @@ -495,26 +425,10 @@ public class AsyncTcpServer : IDisposable /// false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { - if (!_disposed) + if (!Disposed) { - if (disposing) - { - try - { - Stop(); - - if (_listener != null) - { - _listener = null; - } - } - catch (SocketException ex) - { - Console.WriteLine("socket错误:" + ex.Message); - } - } - - _disposed = true; + if (disposing) Stop(); + Disposed = true; } } diff --git a/JiLinApp.Docking/VibrateAlarm/Service/TcpClientConnectedEventArgs.cs b/JiLinApp.Docking/VibrateAlarm/Service/TcpClientConnectedEventArgs.cs index 5445a6e..ead759a 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/TcpClientConnectedEventArgs.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/TcpClientConnectedEventArgs.cs @@ -7,20 +7,17 @@ namespace JiLinApp.Docking.VibrateAlarm; /// public class TcpClientConnectedEventArgs : EventArgs { + /// + /// 客户端 + /// + public TcpClient TcpClient { get; private set; } + /// /// 与客户端的连接已建立事件参数 /// /// 客户端 public TcpClientConnectedEventArgs(TcpClient tcpClient) { - if (tcpClient == null) - throw new ArgumentNullException("tcpClient"); - - TcpClient = tcpClient; + TcpClient = tcpClient ?? throw new ArgumentNullException(nameof(tcpClient)); } - - /// - /// 客户端 - /// - public TcpClient TcpClient { get; private set; } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Service/TcpClientDisconnectedEventArgs.cs b/JiLinApp.Docking/VibrateAlarm/Service/TcpClientDisconnectedEventArgs.cs index 25f96e4..3f93d4d 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/TcpClientDisconnectedEventArgs.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/TcpClientDisconnectedEventArgs.cs @@ -7,20 +7,17 @@ namespace JiLinApp.Docking.VibrateAlarm; /// public class TcpClientDisconnectedEventArgs : EventArgs { + /// + /// 客户端 + /// + public TcpClient TcpClient { get; private set; } + /// /// 与客户端的连接已断开事件参数 /// /// 客户端 public TcpClientDisconnectedEventArgs(TcpClient tcpClient) { - if (tcpClient == null) - throw new ArgumentNullException("tcpClient"); - - TcpClient = tcpClient; + TcpClient = tcpClient ?? throw new ArgumentNullException(nameof(tcpClient)); } - - /// - /// 客户端 - /// - public TcpClient TcpClient { get; private set; } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Service/TcpDatagramReceivedEventArgs.cs b/JiLinApp.Docking/VibrateAlarm/Service/TcpDatagramReceivedEventArgs.cs index c2ef7bd..ec1edf1 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/TcpDatagramReceivedEventArgs.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/TcpDatagramReceivedEventArgs.cs @@ -6,17 +6,6 @@ /// 报文类型 public class TcpDatagramReceivedEventArgs : EventArgs { - /// - /// 接收到数据报文事件参数 - /// - /// 客户端 - /// 报文 - public TcpDatagramReceivedEventArgs(TcpClientState tcpClient, T datagram) - { - TcpClient = tcpClient; - Datagram = datagram; - } - /// /// 客户端 /// @@ -26,4 +15,15 @@ public class TcpDatagramReceivedEventArgs : EventArgs /// 报文 /// public T Datagram { get; private set; } + + /// + /// 接收到数据报文事件参数 + /// + /// 客户端 + /// 报文 + public TcpDatagramReceivedEventArgs(TcpClientState tcpClient, T datagram) + { + TcpClient = tcpClient ?? throw new ArgumentNullException(nameof(tcpClient)); + Datagram = datagram; + } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs b/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs index ddd59ea..0fa1eeb 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs @@ -1,8 +1,7 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using EC.Util.Common; +using System.Collections.Concurrent; using System.Net; -using System.Net.Sockets; -using System.Text; +using System.Timers; using Timer = System.Timers.Timer; namespace JiLinApp.Docking.VibrateAlarm; @@ -11,675 +10,506 @@ public class TcpManager { #region Fields - private JsonSerializerSettings jSetting { get; } = new(); + private AsyncTcpServer Server { get; set; } - private AsyncTcpServer server { get; set; } = null; + private ConcurrentDictionary ClientMessageDict { get; } = new(); - private Timer stateSpanTimer { get; } = new(); + private Timer HeartTimer { get; } = new(); - private Timer heartTimer { get; } = new(); + private Timer StateSpanTimer { get; } = new(); - private List list { get; } = new(); + public delegate void TcpDeviceMessageEvent(TcpAlarmHostTable host, string msg); + + public delegate void TcpSensorMessageEvent(TcpAlarmHostTable host, TcpSensorTable section, string msg); + + public delegate void TcpSensorStateChangeEvent(SensorState state); + + public delegate void TcpSensorAlarmEvent(TcpAlarmHostMessage msg); + + public event TcpDeviceMessageEvent OnTcpDeviceMessage; + + public event TcpSensorMessageEvent OnTcpSensorMessage; + + public event TcpSensorStateChangeEvent OnTcpSensorStateChange; + + public event TcpSensorAlarmEvent OnTcpSensorAlarm; #endregion Fields public TcpManager() { - jSetting.NullValueHandling = NullValueHandling.Ignore; - jSetting.DefaultValueHandling = DefaultValueHandling.Ignore; } - #region BaseMethod + #region Server - public void StartServer(TcpManagerConfig config) + public void Start(TcpManagerConfig config) { if (IsRunning()) return; - IPAddress address = IPAddress.Any; - _ = IPAddress.TryParse(config.ServerIp, out address); + Server = new AsyncTcpServer(IPAddress.Any, config.ServerPort); + Server.ClientConnected += Server_ClientConnected; + Server.ClientDisconnected += Server_ClientDisconnected; + Server.DatagramReceived += Server_DatagramReceived; + Server.Start(); - server = new AsyncTcpServer(address, config.ServerPort); - server.ClientConnected += server_ClientConnected; - server.ClientDisconnected += server_ClientDisconnected; - server.DatagramReceived += server_DatagramReceived; - server.Start(); - - heartTimer.Close(); - heartTimer.Interval = 1000 * config.DeviceHeartKeep; - heartTimer.Elapsed += HeartTimer_Elapsed; - heartTimer.Enabled = true; - heartTimer.Start(); + HeartTimer.Close(); + HeartTimer.Interval = 1000 * config.DeviceHeartKeep; + HeartTimer.Elapsed += HeartTimer_Elapsed; + HeartTimer.Enabled = true; + HeartTimer.Start(); } - public void StopServer() + public void Stop() { - heartTimer.Enabled = false; - if (IsRunning()) - { - server.Stop(); - server = null; - } + HeartTimer.Enabled = false; + if (IsRunning()) Server.Stop(); } public bool IsRunning() { - return server != null && server.IsRunning; - } - - public bool StartScan(ref string error) - { - if (server == null) - { - error = "服务未创建"; - return false; - } - if (!server.IsRunning) - { - error = "服务未运行"; - return false; - } - stateSpanTimer.Enabled = true; - return true; + return Server != null && Server.IsRunning(); } - public void StopScan() - { - stateSpanTimer.Enabled = false; - } + #endregion Server - #endregion BaseMethod + #region Register Event - private void StateSpanTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + private void HeartTimer_Elapsed(object? sender, ElapsedEventArgs e) { - string error = ""; - for (int i = 0; i < list.Count; i++) + foreach (var clientMsg in ClientMessageDict.Values) { - sendState(list[i], ref error); + SendHostHeart_01(clientMsg); } } - private void HeartTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + private void StateSpanTimer_Elapsed(object? sender, ElapsedEventArgs e) { - string error = ""; - for (int i = 0; i < list.Count; i++) + foreach (var clientMsg in ClientMessageDict.Values) { - sendHeart(list[i], ref error); + RequestSensorState_04(clientMsg); } } - private ClientMessage GetClientMessage(TcpClient client) + private void Server_ClientConnected(object? sender, TcpClientConnectedEventArgs e) { - string clientIP = client.Client.RemoteEndPoint.ToString().Split(':')[0]; - for (int i = 0; i < list.Count; i++) + string clientKey = e.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; + if (clientKey == "") return; + string clientIp = clientKey.Split(':')[0]; + string clientPort = clientKey.Split(':')[1]; + Console.WriteLine("上线:{0}", clientIp); + if (!TryGetClientMessage(clientIp, out ClientMessage clientMsg)) { - if (list[i].IP == clientIP) + clientMsg = new() { - return list[i]; - } + Client = e.TcpClient, + Host = new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" } + }; + AddClientMessage(clientIp, clientMsg); + } + if (OnTcpDeviceMessage != null) + { + TcpAlarmHostTable host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; + OnTcpDeviceMessage(host, "报警主机上线"); } - return null; } - private ClientMessage GetClientMessageIP(string clientIP) + private void Server_ClientDisconnected(object? sender, TcpClientDisconnectedEventArgs e) { - for (int i = 0; i < list.Count; i++) + string clientKey = e.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; + if (clientKey == "") return; + string clientIp = clientKey.Split(':')[0]; + string clientPort = clientKey.Split(':')[1]; + Console.WriteLine("下线:{0}", clientIp); + if (TryGetClientMessage(clientIp, out ClientMessage clientMsg)) { - if (list[i].IP == clientIP) + RemoveClientMessage(clientIp); + if (OnTcpDeviceMessage != null) { - return list[i]; + TcpAlarmHostTable host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; + OnTcpDeviceMessage(host, "报警主机下线"); } } - return null; } - private ClientMessage GetClientMessageDeviceID(int deviceId) + private void Server_DatagramReceived(object? sender, TcpDatagramReceivedEventArgs e) { - for (int i = 0; i < list.Count; i++) + string clientKey = e.TcpClient.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; + if (clientKey == "") return; + string clientIp = clientKey.Split(':')[0]; + if (TryGetClientMessage(clientIp, out ClientMessage clientMsg)) { - if (list[i].host != null && list[i].host.id == deviceId) - { - return list[i]; - } + clientMsg.AddData(e.Datagram); + AnalysisClientMessage(clientMsg); } - return null; } - public delegate void TCPSectionAlarmOnEvent(TcpAlarmHostMessage msg); - - public event TCPSectionAlarmOnEvent OnTcpSectionAlarmOn; + #endregion Register Event - public delegate void TCPSectionStateChangeEvent(SectionState state); + #region ClientMessage - public event TCPSectionStateChangeEvent OnTcpSectionStateChange; - - public delegate void TCPDeviceMessageEvent(TcpAlarmHostTable host, string msg); - - public event TCPDeviceMessageEvent OnTcpDeviceMessage; + private bool ContainsClientMessage(string clientIp) + { + return ClientMessageDict.ContainsKey(clientIp); + } - public delegate void TCPSectionMessageEvent(TcpAlarmHostTable host, TcpSectionTable section, string msg); + private ClientMessage GetClientMessage(string clientIp) + { + return ClientMessageDict[clientIp]; + } - public event TCPSectionMessageEvent OnTcpSectionMessage; + private bool TryGetClientMessage(string clientIp, out ClientMessage clientMsg) + { + return ClientMessageDict.TryGetValue(clientIp, out clientMsg); + } - private void server_DatagramReceived(object sender, TcpDatagramReceivedEventArgs e) + private bool AddClientMessage(string clientIp, ClientMessage clientMsg) { - string clientIP = e.TcpClient.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0]; - ClientMessage client = GetClientMessage(e.TcpClient.TcpClient); - if (client != null) - { - AnalysisClientMessage(client, e.Datagram); - } + if (ContainsClientMessage(clientIp)) return false; + ClientMessageDict[clientIp] = clientMsg; + return true; } - public void TestAlarm(string devideId, string channel) + private void SetClientMessage(string clientIp, ClientMessage clientMsg) { - ClientMessage message = new ClientMessage(); - message.client = new TcpClient("127.0.0.1", 5080); + ClientMessageDict[clientIp] = clientMsg; + } - list.Add(message); - byte[] bytes1 = BitConverter.GetBytes(int.Parse(devideId)); - byte[] bytes2 = BitConverter.GetBytes(int.Parse(channel)); - byte[] bytes = new byte[24]{ - 0xAA,0xAA,bytes1[0],bytes1[1], - 127,0,0,1, - 0x00,0x00,127,0, - 0,1,0x00,0x00, - 1,0x14,0x04,bytes2[0], - bytes2[1],0x02,0x00,0x00 - }; - AnalysisClientMessage(message, bytes); + private bool RemoveClientMessage(string clientIp) + { + return ClientMessageDict.Remove(clientIp, out _); } - private string ToHexString(byte[] bytes) + private bool UpdateClientMessage(string clientIp, TcpAlarmHostTable host) { - string hexString = string.Empty; + if (!ClientMessageDict.ContainsKey(clientIp)) return false; + ClientMessageDict[clientIp].Host = host; + return true; + } - if (bytes != null) - { - StringBuilder strB = new StringBuilder(); + private bool UpdateClientMessage(string clientIp, List sensorList) + { + if (!ClientMessageDict.ContainsKey(clientIp)) return false; + ClientMessageDict[clientIp].SensorList = sensorList; + return true; + } - for (int i = 0; i < bytes.Length; i++) - { - strB.Append(bytes[i].ToString("X2") + " "); - } + #endregion ClientMessage - hexString = strB.ToString(); - } - return hexString; - } + #region Analysis - private void AnalysisClientMessage(ClientMessage client, byte[] bytes) + private void AnalysisClientMessage(ClientMessage clientMsg) { - client.list.AddRange(bytes); - - List msglist = client.getMessageList(); - if (msglist != null && msglist.Count > 0) + //AA AA 01 C0 A8 01 64 88 13 C0 A8 01 05 28 23 74 00 01 01 18 + //AA AA 01 C0 A8 01 05 28 23 C0 A8 01 64 88 13 7C 04 02 04 00 2B + //AA AA 01 C0 A8 01 64 88 13 C0 A8 01 05 28 23 24 14 04 0A 00 02 00 03 + List msglist = clientMsg.GetMessageList(); + if (msglist == null || msglist.Count == 0) return; + for (int i = 0; i < msglist.Count; i++) { - for (int i = 0; i < msglist.Count; i++) + DataMessage mm = new(); + mm.Decode(msglist[i]); + Console.WriteLine("Receive from {0}:{1} => {2}, {3}", clientMsg.Ip, clientMsg.Port, DataMessage.ToHexString(msglist[i]), JsonUtil.ToJson(mm)); + TcpAlarmHostTable host; + switch (mm.FunctionNum) { - Console.WriteLine(client.IP + " 收到数据:" + ToHexString(msglist[i])); - DataMessage mm = new DataMessage(); - mm.decode(msglist[i]); - switch (mm.functionNum) - { - case 0x00: - Console.WriteLine(client.IP + " 登录"); - if (client.host == null || client.host.id != mm.deviceID) + case 0x00: + Console.WriteLine("主机登录:{0}", clientMsg.Ip); + if (clientMsg.Host == null || clientMsg.Host.Id != mm.DeviceId) + { + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "未知设备" }; + UpdateClientMessage(clientMsg.Ip, clientMsg.Host); + } + ResponseHostLogin_10(clientMsg, mm); + if (clientMsg.SensorListEmpty && clientMsg.SensorListLock.TryEnterWriteLock(1000)) + { + Task.Run(() => { - //string error = ""; - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "id=" + mm.deviceID, ref error); - JArray arr = new(); - if (arr != null && arr.Count > 0) + while (clientMsg.SensorListEmpty) { - client.host = JsonConvert.DeserializeObject(arr[0].ToString(), jSetting); - client.host.ip = mm.sendIP; - client.host.port = mm.sendPort.ToString(); + RequestSensorList_07(clientMsg); + Thread.Sleep(1000); } - } - if (OnTcpDeviceMessage != null) + clientMsg.SensorListLock.ExitWriteLock(); + }); + } + if (OnTcpDeviceMessage != null) + { + host = clientMsg.Host ?? new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "未知设备" }; + OnTcpDeviceMessage(host, "报警主机登录"); + } + break; + + case 0x01: + Console.WriteLine("心跳:{0}", clientMsg.Ip); + break; + + case 0x12: + Console.WriteLine("传感器地址设置响应:{0}", clientMsg.Ip); + SetDataRequest(mm, 0x02); + break; + + case 0x13: + Console.WriteLine("传感器模式设置响应:{0}", clientMsg.Ip); + SetDataRequest(mm, 0x03); + break; + + case 0x14: + Console.WriteLine("传感器状态响应:{0}", clientMsg.Ip); + int channel = mm.Data[0] + mm.Data[1] * 256; + int state = mm.Data[2] + mm.Data[3] * 256; + int online = state % 2; + int alarm = state / 2 % 2; + if (clientMsg.Host == null || clientMsg.Host.Id != mm.DeviceId) + { + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "未知设备" }; + UpdateClientMessage(clientMsg.Ip, clientMsg.Host); + } + ProcessOnlineEvent(clientMsg, mm, channel, online); + ProcessAlarmEvent(clientMsg, mm, channel, alarm); + UpdateOnLineAlarm(clientMsg, channel, online, alarm); + SetDataRequest(mm, 0x04); + if (alarm == 1) + { + RequestSensorReset_05(clientMsg); + } + break; + + case 0x15: + Console.WriteLine("传感器复位响应:{0}", clientMsg.Ip); + SetDataRequest(mm, 0x05); + break; + + case 0x17: + Console.WriteLine("返回传感器列表:{0}", clientMsg.Ip); + if (clientMsg.Host == null || clientMsg.Host.Id != mm.DeviceId) + { + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "设备" }; + UpdateClientMessage(clientMsg.Ip, clientMsg.Host); + } + if (clientMsg.SensorListEmpty) + { + List sensorList = new(); + for (int j = 2; j < mm.Data.Length; j++) { - if (client.host != null) - { - OnTcpDeviceMessage(client.host, "报警主机登录"); - } - else - { - OnTcpDeviceMessage(new TcpAlarmHostTable() { id = mm.deviceID, ip = mm.sendIP, port = mm.sendPort.ToString(), name = "未知设备" }, "报警主机登录"); - } + sensorList.Add(Convert.ToByte((mm.Data[j] + mm.Data[++j] * 256))); } - break; - - case 0x01: - Console.WriteLine(client.IP + " 心跳"); - break; - - case 0x12: - Console.WriteLine(client.IP + "传感器地址设置响应"); - SetDataRequest(mm, 0x02); - break; - - case 0x13: - Console.WriteLine(client.IP + "传感器模式设置响应"); - SetDataRequest(mm, 0x03); - break; - - case 0x14: - Console.WriteLine(client.IP + "传感器状态响应"); - int channel = mm.data[0] + mm.data[1] * 256; - int state = mm.data[2] + mm.data[3] * 256; - int online = state % 2; - int alarm = state / 2 % 2; - TcpAlarmHostTable host = new() { id = mm.deviceID, ip = mm.sendIP, port = mm.sendPort.ToString(), name = "未知设备" }; - ProcessOnlineEvent(client, host, mm, channel, online); - ProcessAlarmEvent(client, host, mm, channel, alarm); - UpdateOnLineAlarm(client, host, channel, online, alarm); - SetDataRequest(mm, 0x04); - break; - - case 0x15: - Console.WriteLine(client.IP + "传感器复位响应"); - SetDataRequest(mm, 0x05); - break; - } + clientMsg.SensorList = sensorList; + UpdateClientMessage(clientMsg.Ip, sensorList); + RequestSensorState_04(clientMsg); + } + SetDataRequest(mm, 0x07); + break; } } } - private void ProcessOnlineEvent(ClientMessage client, TcpAlarmHostTable host, DataMessage mm, int channel, int online) + private void ProcessOnlineEvent(ClientMessage client, DataMessage mm, int channel, int online) { - if (client.sectioTable.ContainsKey(channel)) + if (client.SectionTable.ContainsKey(channel)) { - SectionState oldState = client.sectioTable[channel] as SectionState; + SensorState oldState = client.SectionTable[channel] as SensorState; if (oldState.online == online) return; } - TcpAlarmHostTable host1 = client.host == null ? host : client.host; - string error = ""; - TcpSectionTable section = new TcpSectionTable() { deviceID = host.id, name = "未知传感器", channel = channel.ToString() }; - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + mm.deviceID + "/channel='" + channel + "'", ref error); - JArray arr = new(); - if (arr != null && arr.Count > 0) section = JsonConvert.DeserializeObject(arr[0].ToString(), jSetting); - if (OnTcpSectionMessage != null) - { - OnTcpSectionMessage(host1, section, online == 0 ? "传感器上线" : "传感器离线"); - } + TcpAlarmHostTable host = client.Host; + TcpSensorTable section = new() { DeviceId = host.Id, Name = "未知传感器", Channel = channel.ToString() }; + OnTcpSensorMessage?.Invoke(host, section, online == 0 ? "传感器上线" : "传感器离线"); } - private void ProcessAlarmEvent(ClientMessage client, TcpAlarmHostTable host, DataMessage mm, int channel, int alarm) + private void ProcessAlarmEvent(ClientMessage client, DataMessage mm, int channel, int alarm) { - if (client.sectioTable.ContainsKey(channel)) + if (client.SectionTable.ContainsKey(channel)) { - SectionState oldState = client.sectioTable[channel] as SectionState; + SensorState oldState = client.SectionTable[channel] as SensorState; if (oldState.alarm == alarm) return; } - TcpAlarmHostTable host1 = client.host == null ? host : client.host; + TcpAlarmHostTable host = client.Host; if (alarm == 1) { - ProcessAlarm(host1.id, channel, alarm); + ProcessAlarm(host.Id, channel); } } - private void UpdateOnLineAlarm(ClientMessage client, TcpAlarmHostTable host, int channel, int online, int alarm) + private void UpdateOnLineAlarm(ClientMessage client, int channel, int online, int alarm) { - if (client.sectioTable.ContainsKey(channel)) + if (client.SectionTable.ContainsKey(channel)) { - SectionState oldState = client.sectioTable[channel] as SectionState; + SensorState oldState = client.SectionTable[channel] as SensorState; oldState.online = online; oldState.alarm = alarm; - if (OnTcpSectionStateChange != null) - { - OnTcpSectionStateChange(oldState); - } + OnTcpSensorStateChange?.Invoke(oldState); } else { - TcpAlarmHostTable host1 = client.host == null ? host : client.host; - SectionState state = new SectionState(host1.id, channel, online, alarm); - client.sectioTable[channel] = state; - if (OnTcpSectionStateChange != null) - { - OnTcpSectionStateChange(state); - } + TcpAlarmHostTable host = client.Host; + SensorState state = new(host.Id, channel, online, alarm); + client.SectionTable[channel] = state; + OnTcpSensorStateChange?.Invoke(state); } } - private void ProcessAlarm(int deviceId, int channel, int alarmId) + private void ProcessAlarm(int deviceId, int channel) { - TcpAlarmHostMessage alarm = new() + TcpAlarmHostMessage alarmMsg = new() { - AlarmId = Convert.ToString(alarmId), AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), + CID = "1151", DeviceID = deviceId, ChannelNum = channel.ToString() }; - ProcessAlarmDB(alarm); + OnTcpSensorAlarm?.Invoke(alarmMsg); } - //处理报警事件 - private void ProcessAlarmDB(TcpAlarmHostMessage msg) - { - if (OnTcpSectionAlarmOn != null) OnTcpSectionAlarmOn(msg); - } + #endregion Analysis - public void SetDataRequest(DataMessage msg, byte functionNum) - { - lock (this) - { - for (int i = 0; i < reqlist.Count; i++) - { - if (reqlist[i].request.functionNum == functionNum && reqlist[i].request.frameNum == msg.frameNum) - { - reqlist[i].responce = msg; - } - } - } - } + #region Send - public bool SendMessage(string IP, byte[] bytes, ref string error) + public bool SendMessage(string ip, byte[] bytes) { - if (server == null) - { - error = "服务未创建"; - return false; - } - if (!server.IsRunning) - { - error = "服务未运行"; - return false; - } - ClientMessage client = GetClientMessageIP(IP); - if (client != null) - { - server.Send(client.client, bytes); - return true; - } - else - { - error = "主机未连接"; - return false; - } + if (Server == null || !Server.IsRunning()) return false; + if (!TryGetClientMessage(ip, out ClientMessage clientMsg)) return false; + string cmd = DataMessage.ToHexString(bytes); + DataMessage mm = new(); + mm.Decode(bytes); + Console.WriteLine("Send to {0}:{1} => {2}, {3}", ip, clientMsg.Port, cmd, JsonUtil.ToJson(mm)); + Server.SendAsync(clientMsg.Client, bytes); + return true; } - private List reqlist = new List(); - private byte frameNumber = 0; - - public bool sendRequest(ref DataRequest request, ref string error) + public bool SendRequest(ref DataRequest request) { - if (request.request == null) - { - error = "请求信息未填写"; - return false; - } - //int waitTime = int.Parse(DBCenter.center.GetConfig("WW_TCP_DeviceTimeOut")) * 10; - int waitTime = 100; - request.request.frameNum = frameNumber; - frameNumber++; - bool send = SendMessage(request.request.receiveIP, request.request.encode(), ref error); - if (!send) return false; - reqlist.Add(request); - for (int i = 0; i < waitTime; i++) - { - if (request.responce != null) - { - reqlist.Remove(request); - return true; - } - System.Threading.Thread.Sleep(100); - } - return false; + if (request.Request == null) return false; + request.Request.FrameNum = FrameNumber; + FrameNumber++; + bool send = SendMessage(request.Request.ReceiveIp, request.Request.Encode()); + return send; } - public bool sendNoRequest(DataMessage msg, ref string error) + public bool SendNoRequest(DataMessage msg) { - msg.frameNum = frameNumber; - frameNumber++; - return SendMessage(msg.receiveIP, msg.encode(), ref error); + msg.FrameNum = FrameNumber; + FrameNumber++; + bool send = SendMessage(msg.ReceiveIp, msg.Encode()); + return send; } - public bool sendHeart(ClientMessage client, ref string error) + public bool SendResponse(DataMessage msg) { - if (client.host == null) - { - error = "报警主机信息缺失"; - return false; - } - DataMessage msg = getSendMessageHead(client.host.id, client, 0x01, 1); - msg.data = new byte[] { 0xFF }; - - return sendNoRequest(msg, ref error); + bool send = SendMessage(msg.ReceiveIp, msg.Encode()); + return send; } - public bool SetSectionAddress(int deviceId, string channel_str, int address, ref string error) + public bool SendHostHeart_01(ClientMessage client) { - ClientMessage client = GetClientMessageDeviceID(deviceId); - if (client == null) - { - error = "此主机号不在线"; - return false; - } - DataMessage msg = getSendMessageHead(deviceId, client, 0x02, 4); - int channel = int.Parse(channel_str); - msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256), (byte)(address % 256), (byte)(address / 256) }; - DataRequest request = new DataRequest(); - request.request = msg; - bool result = sendRequest(ref request, ref error); - if (result) - { - JObject conlist = new JObject(); - conlist.Add("deviceID", deviceId); - conlist.Add("channel", channel_str); - JObject valuelist = new JObject(); - valuelist.Add("channel", address.ToString()); - //DBCenter.center.UpdateResult("table_TCPSection", valuelist, conlist, ref error); - } - return result; + if (client.Host == null) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x01, 1); + msg.Data = new byte[] { 0xFF }; + return SendNoRequest(msg); } - public bool SetSectionMode(int deviceId, string channel_str, byte mode, byte sensitivity, ref string error) + public bool RequestSensorChange_02(ClientMessage client) { - ClientMessage client = GetClientMessageDeviceID(deviceId); - if (client == null) - { - error = "此主机号不在线"; - return false; - } - DataMessage msg = getSendMessageHead(deviceId, client, 0x03, 3); - int channel = int.Parse(channel_str); - msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256), (byte)(mode + sensitivity * 8) }; - DataRequest request = new DataRequest(); - request.request = msg; - bool result = sendRequest(ref request, ref error); - if (result) + if (client.Host == null || client.Host.Id < 0) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x02, 4); + int channel = 10; + msg.Data = new byte[] { (byte)(channel % 256), (byte)(channel / 256), (100 % 256), (100 / 256) }; + DataRequest request = new() { - JObject conlist = new JObject(); - conlist.Add("deviceID", deviceId); - conlist.Add("channel", channel_str); - JObject valuelist = new JObject(); - valuelist.Add("mode", mode.ToString()); - valuelist.Add("sensitivity", sensitivity.ToString()); - //DBCenter.center.UpdateResult("table_TCPSection", valuelist, conlist, ref error); - } - return result; + Request = msg + }; + SendRequest(ref request); + return true; } - public bool SetSectionReset(int deviceId, string channel_str, ref string error) + public bool RequestSensorState_04(ClientMessage client) { - ClientMessage client = GetClientMessageDeviceID(deviceId); - if (client == null) + if (client.Host == null || client.Host.Id < 0) return false; + if (client.SensorListEmpty) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x04, 2); + foreach (var item in client.SensorList) { - error = "此主机号不在线"; - return false; + int channel = item; + msg.Data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; + DataRequest request = new() + { + Request = msg + }; + SendRequest(ref request); } - DataMessage msg = getSendMessageHead(deviceId, client, 0x05, 2); - int channel = int.Parse(channel_str); - msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; - DataRequest request = new DataRequest(); - request.request = msg; - return sendRequest(ref request, ref error); + return true; } - public SectionState SetSectionCheck(int deviceId, string channel_str, ref string error) + public bool RequestSensorReset_05(ClientMessage client) { - ClientMessage client = GetClientMessageDeviceID(deviceId); - if (client == null) - { - error = "此主机号不在线"; - return null; - } - DataMessage msg = getSendMessageHead(deviceId, client, 0x04, 2); - int channel = int.Parse(channel_str); - msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; - DataRequest request = new DataRequest(); - request.request = msg; - bool result = sendRequest(ref request, ref error); - if (result) - { - int channel2 = request.responce.data[0] + request.responce.data[1] * 256; - int state2 = request.responce.data[2] + request.responce.data[3] * 256; - return new SectionState(deviceId, channel2, state2); - } - else + if (client.Host == null || client.Host.Id < 0) return false; + if (client.SensorListEmpty) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x05, 2); + foreach (var item in client.SensorList) { - return null; + int channel = item; + msg.Data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; + DataRequest request = new() + { + Request = msg + }; + SendRequest(ref request); } + return true; } - public List SetDeviceCheck(int deviceId, ref string error) + public bool RequestSensorList_07(ClientMessage client) { - List list = new List(); - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + deviceId, ref error); - JArray arr = new(); - if (arr != null && arr.Count > 0) + if (client.Host == null || client.Host.Id < 0) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x07, 0); + DataRequest request = new() { - for (int i = 0; i < arr.Count; i++) - { - string channel = arr[i]["channel"].ToString(); - SectionState state = SetSectionCheck(deviceId, channel, ref error); - if (state == null) - { - state = new SectionState(deviceId, int.Parse(channel), -1, -1); - } - list.Add(state); - } - } - else - { - error = "数据库中没有防区信息"; - } - return list; + Request = msg + }; + return SendRequest(ref request); } - public List SetAllCheck(ref string error) + public bool ResponseHostLogin_10(ClientMessage client, DataMessage mm) { - List list = new List(); - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "", ref error); - JArray arr = new(); - if (arr != null && arr.Count > 0) - { - for (int i = 0; i < arr.Count; i++) - { - int deviceId = int.Parse(arr[i]["id"].ToString()); - list.AddRange(SetDeviceCheck(deviceId, ref error)); - } - } - return list; - } - - private DataMessage getSendMessageHead(int deviceId, ClientMessage client, byte fun_num, byte datalen) - { - //DataMessage msg = new DataMessage(); - //msg.deviceID = deviceId; - //msg.sendIP = DBCenter.center.GetConfig("WW_TCP_ServeIP"); - //msg.sendPort = int.Parse(DBCenter.center.GetConfig("WW_TCP_ServePort")); - //msg.receiveIP = client.IP; - //msg.receivePort = int.Parse(client.Port); - //msg.functionNum = fun_num; - //msg.dataLen = datalen; - //return msg; - return null; - } - - public void sendState(ClientMessage client, ref string error) - { - //if (client.host == null) - //{ - // error = "报警主机信息缺失"; - // return; - //} - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID='" + client.host.id + "'", ref error); - //if (arr != null && arr.Count > 0) - //{ - // for (int i = 0; i < arr.Count; i++) - // { - // DataMessage msg = getSendMessageHead(client.host.id, client, 0x04, 2); - // int channel = int.Parse(arr[i]["channel"].ToString()); - // msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; - // sendNoRequest(msg, ref error); - // } - //} - } - - private void server_ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e) - { - string clientIP = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0]; - Console.WriteLine(clientIP + "下线"); - ClientMessage client = GetClientMessage(e.TcpClient); - if (client != null) - { - list.Remove(client); - if (OnTcpDeviceMessage != null) - { - if (client.host != null) - { - OnTcpDeviceMessage(client.host, "报警主机掉线"); - } - else - { - OnTcpDeviceMessage(new TcpAlarmHostTable() { id = -1, ip = clientIP, port = client.Port, name = "未知设备" }, "报警主机掉线"); - } - } - } + if (client.Host == null) return false; + DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x10, 0); + msg.FrameNum = mm.FrameNum; + return SendResponse(msg); } - private void server_ClientConnected(object sender, TcpClientConnectedEventArgs e) + #endregion Send + + #region Set + + private List Reqlist { get; } = new(); + + private byte FrameNumber { get; set; } = 0; + + private DataMessage GetSendMessageHead(int deviceId, ClientMessage client, byte fun_num, byte datalen) { - string error = ""; - string clientIP = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0]; - string port = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[1]; - Console.WriteLine(clientIP + "上线"); - ClientMessage client = GetClientMessage(e.TcpClient); - if (client == null) + DataMessage msg = new() { - ClientMessage msg = new ClientMessage(); - msg.client = e.TcpClient; - //JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "IP='" + clientIP + "'", ref error); - JArray arr = new(); - if (arr != null && arr.Count > 0) - { - msg.host = JsonConvert.DeserializeObject(arr[0].ToString(), jSetting); - } - list.Add(msg); - if (OnTcpDeviceMessage != null) - { - if (msg.host != null) - { - OnTcpDeviceMessage(msg.host, "报警主机上线"); - } - else - { - OnTcpDeviceMessage(new TcpAlarmHostTable() { id = -1, ip = clientIP, port = client.Port, name = "未知设备" }, "报警主机上线"); - } - } - } + DeviceId = deviceId, + SendIp = client.Client.Client.LocalEndPoint.ToString().Split(':')[0], + SendPort = Server.Port, + ReceiveIp = client.Ip, + ReceivePort = int.Parse(client.Port), + FunctionNum = fun_num, + DataLen = datalen + }; + return msg; } - public List getOnlineState(int deviceId) + public void SetDataRequest(DataMessage msg, byte functionNum) { - ClientMessage msg = GetClientMessageDeviceID(deviceId); - if (msg != null) - { - return msg.sectioTable.Values as List; - } - else + lock (this) { - return new List(); + //for (int i = 0; i < Reqlist.Count; i++) + //{ + // if (Reqlist[i].Request.FunctionNum == functionNum && Reqlist[i].Request.FrameNum == msg.FrameNum) + // { + // Reqlist[i].Responce = msg; + // } + //} } } + + #endregion Set } \ No newline at end of file diff --git a/JiLinApp.Docking/config/alarmcode.json b/JiLinApp.Docking/config/alarmcode.json index 9e6b6a2..7b30c3c 100644 --- a/JiLinApp.Docking/config/alarmcode.json +++ b/JiLinApp.Docking/config/alarmcode.json @@ -1,2198 +1,2216 @@ [ - { - "Id": "1000", - "Level": "0", - "Type": "错误", - "Content": "接收到未定义的代码" - }, - { - "Id": "1100", - "Level": "1", - "Type": "紧急", - "Content": "个人救护报警" - }, - { - "Id": "1101", - "Level": "1", - "Type": "紧急", - "Content": "个人救护报警,紧急按钮" - }, - { - "Id": "1102", - "Level": "1", - "Type": "紧急", - "Content": "报到失败" - }, - { - "Id": "1103", - "Level": "1", - "Type": "紧急", - "Content": "紧急报警" - }, - { - "Id": "1104", - "Level": "1", - "Type": "紧急", - "Content": "紧急报警" - }, - { - "Id": "1110", - "Level": "1", - "Type": "火警", - "Content": "火警报警" - }, - { - "Id": "1111", - "Level": "1", - "Type": "火警", - "Content": "烟感探头" - }, - { - "Id": "1112", - "Level": "1", - "Type": "火警", - "Content": "燃烧" - }, - { - "Id": "1113", - "Level": "1", - "Type": "火警", - "Content": "消防水流" - }, - { - "Id": "1114", - "Level": "1", - "Type": "火警", - "Content": "热感探头" - }, - { - "Id": "1115", - "Level": "1", - "Type": "火警", - "Content": "火警手动报警" - }, - { - "Id": "1117", - "Level": "1", - "Type": "火警", - "Content": "火焰探头" - }, - { - "Id": "1118", - "Level": "1", - "Type": "火警", - "Content": "接近警报" - }, - { - "Id": "1119", - "Level": "1", - "Type": "火警", - "Content": "煤气泄漏" - }, - { - "Id": "1120", - "Level": "1", - "Type": "劫盗", - "Content": "劫盗" - }, - { - "Id": "1121", - "Level": "1", - "Type": "劫盗", - "Content": "挟持" - }, - { - "Id": "1122", - "Level": "1", - "Type": "劫盗", - "Content": "无声劫盗" - }, - { - "Id": "1123", - "Level": "1", - "Type": "劫盗", - "Content": "有声劫盗" - }, - { - "Id": "1124", - "Level": "1", - "Type": "窃盗", - "Content": "异地劫持" - }, - { - "Id": "1130", - "Level": "1", - "Type": "窃盗", - "Content": "窃盗" - }, - { - "Id": "1131", - "Level": "1", - "Type": "窃盗", - "Content": "周界窃盗" - }, - { - "Id": "1132", - "Level": "1", - "Type": "窃盗", - "Content": "内部窃盗" - }, - { - "Id": "1133", - "Level": "1", - "Type": "窃盗", - "Content": "24小时窃盗" - }, - { - "Id": "1134", - "Level": "1", - "Type": "窃盗", - "Content": "出/入窃盗" - }, - { - "Id": "1135", - "Level": "1", - "Type": "窃盗", - "Content": "日/夜防区" - }, - { - "Id": "1136", - "Level": "1", - "Type": "窃盗", - "Content": "室外窃盗" - }, - { - "Id": "1137", - "Level": "1", - "Type": "窃盗", - "Content": "拆动报警" - }, - { - "Id": "1138", - "Level": "1", - "Type": "窃盗", - "Content": "接近报警" - }, - { - "Id": "1140", - "Level": "1", - "Type": "警报", - "Content": "一般报警" - }, - { - "Id": "1141", - "Level": "1", - "Type": "警报", - "Content": "总线开路" - }, - { - "Id": "1142", - "Level": "1", - "Type": "警报", - "Content": "总线短路" - }, - { - "Id": "1143", - "Level": "1", - "Type": "警报", - "Content": "扩充器故障" - }, - { - "Id": "1144", - "Level": "1", - "Type": "警报", - "Content": "探头被拆动" - }, - { - "Id": "1145", - "Level": "1", - "Type": "警报", - "Content": "扩充器被拆" - }, - { - "Id": "1150", - "Level": "1", - "Type": "警报", - "Content": "24小时非盗窃报警" - }, - { - "Id": "1156", - "Level": "1", - "Type": "警报", - "Content": "日间防区" - }, - { - "Id": "1158", - "Level": "1", - "Type": "警报", - "Content": "温度过高" - }, - { - "Id": "1159", - "Level": "1", - "Type": "警报", - "Content": "温度过低" - }, - { - "Id": "1161", - "Level": "1", - "Type": "周界窃盗", - "Content": "攀爬报警" - }, - { - "Id": "1170", - "Level": "1", - "Type": "故障", - "Content": "用户离线" - }, - { - "Id": "1180", - "Level": "1", - "Type": "故障", - "Content": "GPRS设备断线" - }, - { - "Id": "1181", - "Level": "1", - "Type": "周界窃盗", - "Content": "张力围栏报警" - }, - { - "Id": "1190", - "Level": "1", - "Type": "周界窃盗", - "Content": "脉冲围栏断路报警" - }, - { - "Id": "1191", - "Level": "1", - "Type": "周界窃盗", - "Content": "脉冲围栏短路报警" - }, - { - "Id": "1192", - "Level": "1", - "Type": "周界窃盗", - "Content": "振动光纤断光" - }, - { - "Id": "1193", - "Level": "1", - "Type": "周界窃盗", - "Content": "振动光纤触网" - }, - { - "Id": "1200", - "Level": "2", - "Type": "监控", - "Content": "火警监视" - }, - { - "Id": "1201", - "Level": "2", - "Type": "监控", - "Content": "水压过低" - }, - { - "Id": "1202", - "Level": "2", - "Type": "监控", - "Content": "二氧化碳过低" - }, - { - "Id": "1203", - "Level": "2", - "Type": "监控", - "Content": "阀门感应" - }, - { - "Id": "1300", - "Level": "3", - "Type": "故障", - "Content": "系统故障" - }, - { - "Id": "1301", - "Level": "3", - "Type": "故障", - "Content": "无交流" - }, - { - "Id": "1302", - "Level": "3", - "Type": "故障", - "Content": "电池低压" - }, - { - "Id": "1303", - "Level": "3", - "Type": "故障", - "Content": "RAM校验和故障" - }, - { - "Id": "1304", - "Level": "3", - "Type": "故障", - "Content": "ROM校验和故障" - }, - { - "Id": "1305", - "Level": "3", - "Type": "故障", - "Content": "系统重新设定" - }, - { - "Id": "1306", - "Level": "3", - "Type": "故障", - "Content": "编程改动" - }, - { - "Id": "1307", - "Level": "3", - "Type": "故障", - "Content": "自检故障" - }, - { - "Id": "1308", - "Level": "3", - "Type": "故障", - "Content": "主机停机使用" - }, - { - "Id": "1309", - "Level": "3", - "Type": "故障", - "Content": "电池测试故障" - }, - { - "Id": "130A", - "Level": "3", - "Type": "故障", - "Content": "系统复位" - }, - { - "Id": "1310", - "Level": "3", - "Type": "故障", - "Content": "接地故障" - }, - { - "Id": "1320", - "Level": "3", - "Type": "故障", - "Content": "警号/继电器" - }, - { - "Id": "1321", - "Level": "3", - "Type": "故障", - "Content": "警铃#1" - }, - { - "Id": "1322", - "Level": "3", - "Type": "故障", - "Content": "警铃#2" - }, - { - "Id": "1323", - "Level": "3", - "Type": "故障", - "Content": "警报继电器" - }, - { - "Id": "1324", - "Level": "3", - "Type": "故障", - "Content": "故障继电器" - }, - { - "Id": "1325", - "Level": "3", - "Type": "故障", - "Content": "逆转继电器" - }, - { - "Id": "132A", - "Level": "3", - "Type": "故障", - "Content": "警铃保险管烧坏" - }, - { - "Id": "1330", - "Level": "3", - "Type": "故障", - "Content": "系统周边" - }, - { - "Id": "1331", - "Level": "3", - "Type": "故障", - "Content": "总线开路" - }, - { - "Id": "1332", - "Level": "3", - "Type": "故障", - "Content": "总线短路" - }, - { - "Id": "1333", - "Level": "3", - "Type": "故障", - "Content": "防区掉线" - }, - { - "Id": "1334", - "Level": "3", - "Type": "故障", - "Content": "单元控制器掉线楼道机" - }, - { - "Id": "1335", - "Level": "3", - "Type": "故障", - "Content": "打印机无纸" - }, - { - "Id": "1339", - "Level": "3", - "Type": "故障", - "Content": "振动光纤断光" - }, - { - "Id": "1340", - "Level": "3", - "Type": "故障", - "Content": "网络设备离线" - }, - { - "Id": "1336", - "Level": "3", - "Type": "故障", - "Content": "打印机故障" - }, - { - "Id": "1350", - "Level": "3", - "Type": "故障", - "Content": "通讯故障" - }, - { - "Id": "1351", - "Level": "3", - "Type": "故障", - "Content": "电话线1故障" - }, - { - "Id": "1352", - "Level": "3", - "Type": "故障", - "Content": "电话线2故障" - }, - { - "Id": "1353", - "Level": "3", - "Type": "故障", - "Content": "长距离无线发射器故障" - }, - { - "Id": "1354", - "Level": "3", - "Type": "故障", - "Content": "通讯失败" - }, - { - "Id": "1355", - "Level": "3", - "Type": "故障", - "Content": "失去长距无线监控" - }, - { - "Id": "1356", - "Level": "3", - "Type": "故障", - "Content": "失去长距无线中央监控" - }, - { - "Id": "1357", - "Level": "3", - "Type": "故障", - "Content": "无线干扰" - }, - { - "Id": "1360", - "Level": "3", - "Type": "故障", - "Content": "防区故障" - }, - { - "Id": "1361", - "Level": "3", - "Type": "故障", - "Content": "防拆故障" - }, - { - "Id": "1362", - "Level": "3", - "Type": "故障", - "Content": "充电故障" - }, - { - "Id": "1363", - "Level": "3", - "Type": "故障", - "Content": "模块未准备就绪" - }, - { - "Id": "1370", - "Level": "3", - "Type": "故障", - "Content": "保护回路" - }, - { - "Id": "1371", - "Level": "3", - "Type": "故障", - "Content": "保护回路开路" - }, - { - "Id": "1372", - "Level": "3", - "Type": "故障", - "Content": "保护回路短路" - }, - { - "Id": "1373", - "Level": "3", - "Type": "故障", - "Content": "火警回路故障" - }, - { - "Id": "137A", - "Level": "3", - "Type": "故障", - "Content": "回路故障" - }, - { - "Id": "1380", - "Level": "3", - "Type": "故障", - "Content": "感应器故障" - }, - { - "Id": "1381", - "Level": "3", - "Type": "故障", - "Content": "无线监控故障" - }, - { - "Id": "1382", - "Level": "3", - "Type": "故障", - "Content": "总线监控故障" - }, - { - "Id": "1383", - "Level": "3", - "Type": "故障", - "Content": "感应器被拆" - }, - { - "Id": "1384", - "Level": "3", - "Type": "故障", - "Content": "无线感应器电池过低" - }, - { - "Id": "1393", - "Level": "3", - "Type": "故障", - "Content": "电话故障" - }, - { - "Id": "1394", - "Level": "3", - "Type": "故障", - "Content": "卡故障" - }, - { - "Id": "13A0", - "Level": "3", - "Type": "故障", - "Content": "请求服务" - }, - { - "Id": "13A1", - "Level": "3", - "Type": "故障", - "Content": "时间重设" - }, - { - "Id": "13A2", - "Level": "3", - "Type": "故障", - "Content": "5(12)伏电源故障" - }, - { - "Id": "13A3", - "Level": "3", - "Type": "故障", - "Content": "电话线故障" - }, - { - "Id": "13A4", - "Level": "3", - "Type": "故障", - "Content": "卡故障" - }, - { - "Id": "13A5", - "Level": "3", - "Type": "故障", - "Content": "失去电池" - }, - { - "Id": "13A6", - "Level": "3", - "Type": "故障", - "Content": "进入编程模式" - }, - { - "Id": "13A7", - "Level": "3", - "Type": "故障", - "Content": "未知故障" - }, - { - "Id": "13A8", - "Level": "3", - "Type": "故障", - "Content": "无效报告" - }, - { - "Id": "13B0", - "Level": "3", - "Type": "故障", - "Content": "用户密码更改" - }, - { - "Id": "13B1", - "Level": "3", - "Type": "故障", - "Content": "错误信息" - }, - { - "Id": "1400", - "Level": "4", - "Type": "撤防", - "Content": "撤防" - }, - { - "Id": "1401", - "Level": "4", - "Type": "撤防", - "Content": "用户撤防" - }, - { - "Id": "1402", - "Level": "4", - "Type": "撤防", - "Content": "集体撤防" - }, - { - "Id": "1403", - "Level": "4", - "Type": "撤防", - "Content": "自动撤防" - }, - { - "Id": "1404", - "Level": "4", - "Type": "撤防", - "Content": "过迟撤防" - }, - { - "Id": "1405", - "Level": "4", - "Type": "撤防", - "Content": "不适用" - }, - { - "Id": "1406", - "Level": "4", - "Type": "撤防", - "Content": "取消" - }, - { - "Id": "1407", - "Level": "4", - "Type": "撤防", - "Content": "遥控撤防" - }, - { - "Id": "1408", - "Level": "4", - "Type": "撤防", - "Content": "快速撤防" - }, - { - "Id": "1409", - "Level": "4", - "Type": "撤防", - "Content": "开关撤防" - }, - { - "Id": "140A", - "Level": "4", - "Type": "撤防", - "Content": "部分撤防" - }, - { - "Id": "140B", - "Level": "4", - "Type": "撤防", - "Content": "周边撤防" - }, - { - "Id": "1411", - "Level": "4", - "Type": "遥控", - "Content": "要求回电" - }, - { - "Id": "1412", - "Level": "4", - "Type": "遥控", - "Content": "遥控编程成功" - }, - { - "Id": "1413", - "Level": "4", - "Type": "遥控", - "Content": "遥控不成功" - }, - { - "Id": "1414", - "Level": "4", - "Type": "遥控", - "Content": "关闭系统" - }, - { - "Id": "1415", - "Level": "4", - "Type": "遥控", - "Content": "关闭通讯" - }, - { - "Id": "1416", - "Level": "4", - "Type": "撤防", - "Content": "撤防操作" - }, - { - "Id": "1417", - "Level": "4", - "Type": "撤防", - "Content": "防区撤防" - }, - { - "Id": "1421", - "Level": "4", - "Type": "出入", - "Content": "拒绝出入-用户" - }, - { - "Id": "1422", - "Level": "4", - "Type": "出入", - "Content": "成功出入-用户" - }, - { - "Id": "1441", - "Level": "4", - "Type": "出入", - "Content": "在家布防" - }, - { - "Id": "1450", - "Level": "4", - "Type": "出入", - "Content": "非正常时段撤防" - }, - { - "Id": "1451", - "Level": "4", - "Type": "出入", - "Content": "过早撤防" - }, - { - "Id": "1452", - "Level": "4", - "Type": "出入", - "Content": "过迟撤防" - }, - { - "Id": "1453", - "Level": "4", - "Type": "出入", - "Content": "撤防失败" - }, - { - "Id": "1454", - "Level": "4", - "Type": "出入", - "Content": "布防失败" - }, - { - "Id": "1455", - "Level": "4", - "Type": "出入", - "Content": "自动布防失败" - }, - { - "Id": "1456", - "Level": "4", - "Type": "出入", - "Content": "部分布防" - }, - { - "Id": "1457", - "Level": "4", - "Type": "出入", - "Content": "外出错误" - }, - { - "Id": "1458", - "Level": "4", - "Type": "出入", - "Content": "操作员在现场" - }, - { - "Id": "1459", - "Level": "4", - "Type": "出入", - "Content": "最近布防" - }, - { - "Id": "1480", - "Level": "4", - "Type": "出入", - "Content": "关警号" - }, - { - "Id": "1520", - "Level": "5", - "Type": "停用", - "Content": "停用警号/继电器" - }, - { - "Id": "1521", - "Level": "5", - "Type": "停用", - "Content": "警铃1停用" - }, - { - "Id": "1522", - "Level": "5", - "Type": "停用", - "Content": "警铃2停用" - }, - { - "Id": "1523", - "Level": "5", - "Type": "停用", - "Content": "停用警报继电器" - }, - { - "Id": "1524", - "Level": "5", - "Type": "停用", - "Content": "停用故障继电器" - }, - { - "Id": "1525", - "Level": "5", - "Type": "停用", - "Content": "逆反继电器" - }, - { - "Id": "1530", - "Level": "5", - "Type": "停用", - "Content": "停用系统周边" - }, - { - "Id": "1540", - "Level": "5", - "Type": "停用", - "Content": "停用系统周边" - }, - { - "Id": "1551", - "Level": "5", - "Type": "停用", - "Content": "通讯器停用" - }, - { - "Id": "1552", - "Level": "5", - "Type": "停用", - "Content": "无线发射器停用" - }, - { - "Id": "1570", - "Level": "5", - "Type": "旁路", - "Content": "防区旁路" - }, - { - "Id": "1571", - "Level": "5", - "Type": "旁路", - "Content": "火警旁路" - }, - { - "Id": "1572", - "Level": "5", - "Type": "旁路", - "Content": "24小时防区旁路" - }, - { - "Id": "1573", - "Level": "5", - "Type": "旁路", - "Content": "窃盗旁路" - }, - { - "Id": "1574", - "Level": "5", - "Type": "旁路", - "Content": "集体旁路" - }, - { - "Id": "1580", - "Level": "5", - "Type": "旁路", - "Content": "旁路操作" - }, - { - "Id": "1601", - "Level": "6", - "Type": "测试", - "Content": "手动测试" - }, - { - "Id": "1602", - "Level": "6", - "Type": "测试", - "Content": "定期测试" - }, - { - "Id": "1603", - "Level": "6", - "Type": "测试", - "Content": "定期无线发射器测试" - }, - { - "Id": "1604", - "Level": "6", - "Type": "测试", - "Content": "火警测试" - }, - { - "Id": "1605", - "Level": "6", - "Type": "测试", - "Content": "状态报告" - }, - { - "Id": "1606", - "Level": "6", - "Type": "测试", - "Content": "监听" - }, - { - "Id": "1607", - "Level": "6", - "Type": "测试", - "Content": "不行测试模式" - }, - { - "Id": "1609", - "Level": "6", - "Type": "测试", - "Content": "图像传输" - }, - { - "Id": "1630", - "Level": "6", - "Type": "测试", - "Content": "改动时间表" - }, - { - "Id": "1631", - "Level": "6", - "Type": "测试", - "Content": "改动例外时间表" - }, - { - "Id": "1632", - "Level": "6", - "Type": "测试", - "Content": "改动出入时间表" - }, - { - "Id": "1695", - "Level": "6", - "Type": "用户", - "Content": "提早布防" - }, - { - "Id": "1696", - "Level": "6", - "Type": "用户", - "Content": "未及时布防" - }, - { - "Id": "1697", - "Level": "6", - "Type": "用户", - "Content": "提早撤防" - }, - { - "Id": "1698", - "Level": "6", - "Type": "用户", - "Content": "未及时撤防" - }, - { - "Id": "1699", - "Level": "6", - "Type": "用户", - "Content": "超时测试间隔信号" - }, - { - "Id": "16A0", - "Level": "6", - "Type": "用户", - "Content": "用户缴费时间到" - }, - { - "Id": "16B0", - "Level": "6", - "Type": "测试", - "Content": "手动测试操作" - }, - { - "Id": "16CC", - "Level": "6", - "Type": "错误", - "Content": "测试" - }, - { - "Id": "3100", - "Level": "1", - "Type": "紧急恢复", - "Content": "个人救护报警恢复" - }, - { - "Id": "3101", - "Level": "1", - "Type": "紧急恢复", - "Content": "个人救护报警,紧急按钮恢复" - }, - { - "Id": "3102", - "Level": "1", - "Type": "紧急恢复", - "Content": "报到失败恢复" - }, - { - "Id": "3103", - "Level": "1", - "Type": "紧急恢复", - "Content": "紧急报警恢复" - }, - { - "Id": "3104", - "Level": "1", - "Type": "紧急恢复", - "Content": "紧急报警恢复" - }, - { - "Id": "3110", - "Level": "1", - "Type": "火警恢复", - "Content": "火警报警恢复" - }, - { - "Id": "3111", - "Level": "1", - "Type": "火警恢复", - "Content": "烟感探头恢复" - }, - { - "Id": "3112", - "Level": "1", - "Type": "火警恢复", - "Content": "燃烧熄灭" - }, - { - "Id": "3113", - "Level": "1", - "Type": "火警恢复", - "Content": "消防水流恢复" - }, - { - "Id": "3114", - "Level": "1", - "Type": "火警恢复", - "Content": "热感探头恢复" - }, - { - "Id": "3115", - "Level": "1", - "Type": "火警恢复", - "Content": "火警手动报警恢复" - }, - { - "Id": "3116", - "Level": "1", - "Type": "火警恢复", - "Content": "空调槽烟感恢复" - }, - { - "Id": "3117", - "Level": "1", - "Type": "火警恢复", - "Content": "火焰探头恢复" - }, - { - "Id": "3118", - "Level": "1", - "Type": "火警恢复", - "Content": "接近警报恢复" - }, - { - "Id": "3119", - "Level": "1", - "Type": "火警恢复", - "Content": "煤气泄漏恢复" - }, - { - "Id": "3120", - "Level": "1", - "Type": "劫盗恢复", - "Content": "劫盗恢复" - }, - { - "Id": "3121", - "Level": "1", - "Type": "劫盗恢复", - "Content": "挟持恢复" - }, - { - "Id": "3122", - "Level": "1", - "Type": "劫盗恢复", - "Content": "无声劫盗恢复" - }, - { - "Id": "3123", - "Level": "1", - "Type": "劫盗恢复", - "Content": "有声劫盗恢复" - }, - { - "Id": "3124", - "Level": "1", - "Type": "劫盗恢复", - "Content": "异地劫持恢复" - }, - { - "Id": "3130", - "Level": "1", - "Type": "窃盗恢复", - "Content": "窃盗恢复" - }, - { - "Id": "3131", - "Level": "1", - "Type": "窃盗恢复", - "Content": "周界窃盗恢复" - }, - { - "Id": "3132", - "Level": "1", - "Type": "窃盗恢复", - "Content": "内部窃盗恢复" - }, - { - "Id": "3133", - "Level": "1", - "Type": "窃盗恢复", - "Content": "24小时窃盗恢复" - }, - { - "Id": "3134", - "Level": "1", - "Type": "窃盗恢复", - "Content": "出/入窃盗恢复" - }, - { - "Id": "3135", - "Level": "1", - "Type": "窃盗恢复", - "Content": "日/夜防区恢复" - }, - { - "Id": "3136", - "Level": "1", - "Type": "窃盗恢复", - "Content": "室外窃盗恢复" - }, - { - "Id": "3137", - "Level": "1", - "Type": "窃盗恢复", - "Content": "拆动报警恢复" - }, - { - "Id": "3138", - "Level": "1", - "Type": "窃盗恢复", - "Content": "接近报警恢复" - }, - { - "Id": "3140", - "Level": "1", - "Type": "警报恢复", - "Content": "一般报警恢复" - }, - { - "Id": "3141", - "Level": "1", - "Type": "警报恢复", - "Content": "总线开路恢复" - }, - { - "Id": "3142", - "Level": "1", - "Type": "警报恢复", - "Content": "总线短路恢复" - }, - { - "Id": "3143", - "Level": "1", - "Type": "警报恢复", - "Content": "扩充器恢复" - }, - { - "Id": "3144", - "Level": "1", - "Type": "警报恢复", - "Content": "探头被拆动恢复" - }, - { - "Id": "3145", - "Level": "1", - "Type": "警报恢复", - "Content": "扩充器被拆恢复" - }, - { - "Id": "3150", - "Level": "1", - "Type": "警报恢复", - "Content": "24小时非窃盗报警恢复" - }, - { - "Id": "3151", - "Level": "1", - "Type": "警报恢复", - "Content": "气体恢复" - }, - { - "Id": "3152", - "Level": "1", - "Type": "警报恢复", - "Content": "冷藏器恢复" - }, - { - "Id": "3153", - "Level": "1", - "Type": "警报恢复", - "Content": "加热系统恢复" - }, - { - "Id": "3154", - "Level": "1", - "Type": "警报恢复", - "Content": "漏水恢复" - }, - { - "Id": "3155", - "Level": "1", - "Type": "警报恢复", - "Content": "箔片破损恢复" - }, - { - "Id": "3156", - "Level": "1", - "Type": "警报恢复", - "Content": "日间防区恢复" - }, - { - "Id": "3157", - "Level": "1", - "Type": "警报恢复", - "Content": "气体水平过低恢复" - }, - { - "Id": "3158", - "Level": "1", - "Type": "警报恢复", - "Content": "温度过高恢复" - }, - { - "Id": "3159", - "Level": "1", - "Type": "警报恢复", - "Content": "温度过低恢复" - }, - { - "Id": "3161", - "Level": "1", - "Type": "警报恢复", - "Content": "空气流动恢复" - }, - { - "Id": "3170", - "Level": "1", - "Type": "故障恢复", - "Content": "用户离线恢复" - }, - { - "Id": "3180", - "Level": "1", - "Type": "故障", - "Content": "GPRS设备恢复连接" - }, - { - "Id": "3200", - "Level": "2", - "Type": "监控恢复", - "Content": "火警监控恢复" - }, - { - "Id": "3201", - "Level": "2", - "Type": "监控恢复", - "Content": "水压过低恢复" - }, - { - "Id": "3202", - "Level": "2", - "Type": "监控恢复", - "Content": "二氧化碳过低恢复" - }, - { - "Id": "3203", - "Level": "2", - "Type": "监控恢复", - "Content": "阀门感应恢复" - }, - { - "Id": "3204", - "Level": "2", - "Type": "监控恢复", - "Content": "水压过低恢复" - }, - { - "Id": "3205", - "Level": "2", - "Type": "监控恢复", - "Content": "水泵关闭" - }, - { - "Id": "3206", - "Level": "2", - "Type": "监控恢复", - "Content": "水泵故障恢复" - }, - { - "Id": "3300", - "Level": "3", - "Type": "故障恢复", - "Content": "系统故障恢复" - }, - { - "Id": "3301", - "Level": "3", - "Type": "故障恢复", - "Content": "交流恢复" - }, - { - "Id": "3302", - "Level": "3", - "Type": "故障恢复", - "Content": "电池低压恢复" - }, - { - "Id": "3303", - "Level": "3", - "Type": "故障恢复", - "Content": "RAM校验和故障恢复" - }, - { - "Id": "3304", - "Level": "3", - "Type": "故障恢复", - "Content": "ROM检验和故障恢复" - }, - { - "Id": "3305", - "Level": "3", - "Type": "故障恢复", - "Content": "系统重新设定恢复" - }, - { - "Id": "3306", - "Level": "3", - "Type": "故障恢复", - "Content": "编程改动恢复" - }, - { - "Id": "3307", - "Level": "3", - "Type": "故障恢复", - "Content": "自检故障恢复" - }, - { - "Id": "3308", - "Level": "3", - "Type": "故障恢复", - "Content": "主机停机使用恢复" - }, - { - "Id": "3309", - "Level": "3", - "Type": "故障恢复", - "Content": "电池测试故障恢复" - }, - { - "Id": "330A", - "Level": "3", - "Type": "故障恢复", - "Content": "系统复位恢复" - }, - { - "Id": "3310", - "Level": "3", - "Type": "故障恢复", - "Content": "接地故障恢复" - }, - { - "Id": "3320", - "Level": "3", - "Type": "故障恢复", - "Content": "警号/继电器恢复" - }, - { - "Id": "3321", - "Level": "3", - "Type": "故障恢复", - "Content": "警铃#1恢复" - }, - { - "Id": "3322", - "Level": "3", - "Type": "故障恢复", - "Content": "警铃#2恢复" - }, - { - "Id": "3323", - "Level": "3", - "Type": "故障恢复", - "Content": "警报继电器恢复" - }, - { - "Id": "3324", - "Level": "3", - "Type": "故障恢复", - "Content": "故障继电器恢复" - }, - { - "Id": "3325", - "Level": "3", - "Type": "故障恢复", - "Content": "逆转继电器恢复" - }, - { - "Id": "332A", - "Level": "3", - "Type": "故障恢复", - "Content": "警铃保险管烧坏恢复" - }, - { - "Id": "3330", - "Level": "3", - "Type": "故障恢复", - "Content": "系统周边恢复" - }, - { - "Id": "3331", - "Level": "3", - "Type": "故障恢复", - "Content": "总线开路恢复" - }, - { - "Id": "3332", - "Level": "3", - "Type": "故障恢复", - "Content": "总线短路恢复" - }, - { - "Id": "3333", - "Level": "3", - "Type": "故障恢复", - "Content": "扩充器故障" - }, - { - "Id": "3334", - "Level": "3", - "Type": "故障恢复", - "Content": "重复器故障恢复" - }, - { - "Id": "3335", - "Level": "3", - "Type": "故障恢复", - "Content": "打印机无纸恢复" - }, - { - "Id": "3336", - "Level": "3", - "Type": "故障恢复", - "Content": "打印机故障恢复" - }, - { - "Id": "3339", - "Level": "3", - "Type": "故障恢复", - "Content": "振动光纤断光恢复" - }, - { - "Id": "3340", - "Level": "3", - "Type": "故障恢复", - "Content": "网络设备在线" - }, - { - "Id": "3350", - "Level": "3", - "Type": "故障恢复", - "Content": "通讯故障恢复" - }, - { - "Id": "3351", - "Level": "3", - "Type": "故障恢复", - "Content": "电话线1故障恢复" - }, - { - "Id": "3352", - "Level": "3", - "Type": "故障恢复", - "Content": "电话线2故障恢复" - }, - { - "Id": "3353", - "Level": "3", - "Type": "故障恢复", - "Content": "长距离无线发射器故障恢复" - }, - { - "Id": "3354", - "Level": "3", - "Type": "故障恢复", - "Content": "通讯失败恢复" - }, - { - "Id": "3355", - "Level": "3", - "Type": "故障恢复", - "Content": "失去长距无线监控恢复" - }, - { - "Id": "3356", - "Level": "3", - "Type": "故障恢复", - "Content": "失去长距无线中央监控恢复" - }, - { - "Id": "3357", - "Level": "3", - "Type": "故障恢复", - "Content": "无线感干扰恢复" - }, - { - "Id": "3360", - "Level": "3", - "Type": "故障恢复", - "Content": "防区故障恢复" - }, - { - "Id": "3361", - "Level": "3", - "Type": "故障恢复", - "Content": "防拆故障恢复" - }, - { - "Id": "3362", - "Level": "3", - "Type": "故障恢复", - "Content": "充电故障恢复" - }, - { - "Id": "3363", - "Level": "3", - "Type": "故障恢复", - "Content": "模块已准备就绪" - }, - { - "Id": "3370", - "Level": "3", - "Type": "故障恢复", - "Content": "保护回路恢复" - }, - { - "Id": "3371", - "Level": "3", - "Type": "故障恢复", - "Content": "保护回路开路恢复" - }, - { - "Id": "3372", - "Level": "3", - "Type": "故障恢复", - "Content": "保护回路短路恢复" - }, - { - "Id": "3373", - "Level": "3", - "Type": "故障恢复", - "Content": "火警回路故障恢复" - }, - { - "Id": "337A", - "Level": "3", - "Type": "故障恢复", - "Content": "回路故障恢复" - }, - { - "Id": "3380", - "Level": "3", - "Type": "故障恢复", - "Content": "感应器故障恢复" - }, - { - "Id": "3381", - "Level": "3", - "Type": "故障恢复", - "Content": "无线监控故障恢复" - }, - { - "Id": "3382", - "Level": "3", - "Type": "故障恢复", - "Content": "总线监控故障恢复" - }, - { - "Id": "3383", - "Level": "3", - "Type": "故障恢复", - "Content": "感应器被拆恢复" - }, - { - "Id": "3384", - "Level": "3", - "Type": "故障恢复", - "Content": "无线感应器电池过低恢复" - }, - { - "Id": "3393", - "Level": "3", - "Type": "故障恢复", - "Content": "电话故障恢复" - }, - { - "Id": "3394", - "Level": "3", - "Type": "故障恢复", - "Content": "卡故障恢复" - }, - { - "Id": "33A0", - "Level": "3", - "Type": "故障恢复", - "Content": "请求服务恢复" - }, - { - "Id": "33A1", - "Level": "3", - "Type": "故障恢复", - "Content": "设置时间恢复" - }, - { - "Id": "33A2", - "Level": "3", - "Type": "故障恢复", - "Content": "5(12)伏电源故障恢复" - }, - { - "Id": "33A3", - "Level": "3", - "Type": "故障恢复", - "Content": "电话线故障恢复" - }, - { - "Id": "33A4", - "Level": "3", - "Type": "故障恢复", - "Content": "卡故障恢复" - }, - { - "Id": "33A5", - "Level": "3", - "Type": "故障恢复", - "Content": "失去电池恢复" - }, - { - "Id": "33A6", - "Level": "3", - "Type": "故障恢复", - "Content": "进入编程模式恢复" - }, - { - "Id": "33A7", - "Level": "3", - "Type": "故障恢复", - "Content": "未知故障恢复" - }, - { - "Id": "33A8", - "Level": "3", - "Type": "故障恢复", - "Content": "无效报告恢复" - }, - { - "Id": "33B0", - "Level": "3", - "Type": "密码恢复", - "Content": "用户密码更改恢复" - }, - { - "Id": "33B1", - "Level": "3", - "Type": "故障恢复", - "Content": "错误恢复" - }, - { - "Id": "3400", - "Level": "4", - "Type": "布防", - "Content": "布防" - }, - { - "Id": "3401", - "Level": "4", - "Type": "布防", - "Content": "用户布防" - }, - { - "Id": "3402", - "Level": "4", - "Type": "布防", - "Content": "集体布防" - }, - { - "Id": "3403", - "Level": "4", - "Type": "布防", - "Content": "自动布防" - }, - { - "Id": "3404", - "Level": "4", - "Type": "布防", - "Content": "过迟布防" - }, - { - "Id": "3405", - "Level": "4", - "Type": "布防", - "Content": "不适用恢复" - }, - { - "Id": "3406", - "Level": "4", - "Type": "布防", - "Content": "取消恢复" - }, - { - "Id": "3407", - "Level": "4", - "Type": "布防", - "Content": "遥控布防" - }, - { - "Id": "3408", - "Level": "4", - "Type": "布防", - "Content": "快速布防" - }, - { - "Id": "3409", - "Level": "4", - "Type": "布防", - "Content": "开关布防" - }, - { - "Id": "340A", - "Level": "4", - "Type": "布防", - "Content": "部分布防" - }, - { - "Id": "340B", - "Level": "4", - "Type": "布防", - "Content": "周边布防" - }, - { - "Id": "3411", - "Level": "4", - "Type": "遥控恢复", - "Content": "要求回电恢复" - }, - { - "Id": "3412", - "Level": "4", - "Type": "遥控恢复", - "Content": "遥控编程成功恢复" - }, - { - "Id": "3413", - "Level": "4", - "Type": "遥控恢复", - "Content": "遥控不成功恢复" - }, - { - "Id": "3414", - "Level": "4", - "Type": "遥控恢复", - "Content": "关闭系统恢复" - }, - { - "Id": "3415", - "Level": "4", - "Type": "遥控恢复", - "Content": "关闭通讯恢复" - }, - { - "Id": "3416", - "Level": "4", - "Type": "布防", - "Content": "布防操作" - }, - { - "Id": "3417", - "Level": "4", - "Type": "布防", - "Content": "防区布防" - }, - { - "Id": "3421", - "Level": "4", - "Type": "出入恢复", - "Content": "拒绝出入-用户恢复" - }, - { - "Id": "3422", - "Level": "4", - "Type": "出入恢复", - "Content": "成功出入-用户恢复" - }, - { - "Id": "3441", - "Level": "4", - "Type": "布防", - "Content": "留守布防" - }, - { - "Id": "3450", - "Level": "4", - "Type": "出入恢复", - "Content": "非正常时段布防" - }, - { - "Id": "3451", - "Level": "4", - "Type": "出入恢复", - "Content": "过早布防" - }, - { - "Id": "3452", - "Level": "4", - "Type": "出入恢复", - "Content": "过迟布防" - }, - { - "Id": "3453", - "Level": "4", - "Type": "出入恢复", - "Content": "撤防失败恢复" - }, - { - "Id": "3454", - "Level": "4", - "Type": "出入恢复", - "Content": "布防失败恢复" - }, - { - "Id": "3455", - "Level": "4", - "Type": "出入恢复", - "Content": "自动布防失败恢复" - }, - { - "Id": "3456", - "Level": "4", - "Type": "出入恢复", - "Content": "部分布防恢复" - }, - { - "Id": "3457", - "Level": "4", - "Type": "出入恢复", - "Content": "外出错误恢复" - }, - { - "Id": "3458", - "Level": "4", - "Type": "出入恢复", - "Content": "操作员在现场恢复" - }, - { - "Id": "3459", - "Level": "4", - "Type": "出入恢复", - "Content": "最近布防恢复" - }, - { - "Id": "3480", - "Level": "4", - "Type": "用户恢复", - "Content": "开警号" - }, - { - "Id": "3520", - "Level": "5", - "Type": "停用恢复", - "Content": "停用警号/继电器恢复" - }, - { - "Id": "3521", - "Level": "5", - "Type": "停用恢复", - "Content": "警铃1停用恢复" - }, - { - "Id": "3522", - "Level": "5", - "Type": "停用恢复", - "Content": "警铃2停用恢复" - }, - { - "Id": "3523", - "Level": "5", - "Type": "停用恢复", - "Content": "停用警报继电器恢复" - }, - { - "Id": "3524", - "Level": "5", - "Type": "停用恢复", - "Content": "停用故障继电器恢复" - }, - { - "Id": "3525", - "Level": "5", - "Type": "停用恢复", - "Content": "逆反继电器恢复" - }, - { - "Id": "3530", - "Level": "5", - "Type": "停用恢复", - "Content": "停用系统周边恢复" - }, - { - "Id": "3540", - "Level": "5", - "Type": "停用恢复", - "Content": "停用系统周边恢复" - }, - { - "Id": "3551", - "Level": "5", - "Type": "停用恢复", - "Content": "通讯器停用恢复" - }, - { - "Id": "3552", - "Level": "5", - "Type": "停用恢复", - "Content": "无线发射器停用恢复" - }, - { - "Id": "3570", - "Level": "5", - "Type": "旁路恢复", - "Content": "防区旁路恢复" - }, - { - "Id": "3571", - "Level": "5", - "Type": "旁路恢复", - "Content": "火警旁路恢复" - }, - { - "Id": "3572", - "Level": "5", - "Type": "旁路恢复", - "Content": "24小时防区旁路恢复" - }, - { - "Id": "3573", - "Level": "5", - "Type": "旁路恢复", - "Content": "窃盗旁路恢复" - }, - { - "Id": "3574", - "Level": "5", - "Type": "旁路恢复", - "Content": "集体旁路恢复" - }, - { - "Id": "3580", - "Level": "5", - "Type": "旁路恢复", - "Content": "旁路操作恢复" - }, - { - "Id": "3601", - "Level": "6", - "Type": "测试恢复", - "Content": "手动测试恢复" - }, - { - "Id": "3602", - "Level": "6", - "Type": "测试恢复", - "Content": "定期测试恢复" - }, - { - "Id": "3603", - "Level": "6", - "Type": "测试恢复", - "Content": "定期无线发射器测试恢复" - }, - { - "Id": "3604", - "Level": "6", - "Type": "测试恢复", - "Content": "火警测试恢复" - }, - { - "Id": "3605", - "Level": "6", - "Type": "测试恢复", - "Content": "状态报告恢复" - }, - { - "Id": "3606", - "Level": "6", - "Type": "测试恢复", - "Content": "监听恢复" - }, - { - "Id": "3607", - "Level": "6", - "Type": "测试恢复", - "Content": "步行测试模式恢复" - }, - { - "Id": "3609", - "Level": "6", - "Type": "测试恢复", - "Content": "图像传输恢复" - }, - { - "Id": "3630", - "Level": "6", - "Type": "测试恢复", - "Content": "改动时间表恢复" - }, - { - "Id": "3631", - "Level": "6", - "Type": "测试恢复", - "Content": "改动例外时间表恢复" - }, - { - "Id": "3632", - "Level": "6", - "Type": "测试恢复", - "Content": "改动出入时间表恢复" - }, - { - "Id": "3695", - "Level": "6", - "Type": "用户恢复", - "Content": "提早布防恢复" - }, - { - "Id": "3696", - "Level": "6", - "Type": "用户恢复", - "Content": "未及时布防恢复" - }, - { - "Id": "3697", - "Level": "6", - "Type": "用户恢复", - "Content": "提早撤防恢复" - }, - { - "Id": "3698", - "Level": "6", - "Type": "用户恢复", - "Content": "未及时撤防恢复" - }, - { - "Id": "3699", - "Level": "6", - "Type": "用户恢复", - "Content": "超过测试间隔信号恢复" - }, - { - "Id": "36B0", - "Level": "6", - "Type": "测试恢复", - "Content": "手动测试操作恢复" - } + { + "Id": "1000", + "Level": "0", + "Type": "错误", + "Content": "接收到未定义的代码" + }, + { + "Id": "1100", + "Level": "1", + "Type": "紧急", + "Content": "个人救护报警" + }, + { + "Id": "1101", + "Level": "1", + "Type": "紧急", + "Content": "个人救护报警,紧急按钮" + }, + { + "Id": "1102", + "Level": "1", + "Type": "紧急", + "Content": "报到失败" + }, + { + "Id": "1103", + "Level": "1", + "Type": "紧急", + "Content": "紧急报警" + }, + { + "Id": "1104", + "Level": "1", + "Type": "紧急", + "Content": "紧急报警" + }, + { + "Id": "1110", + "Level": "1", + "Type": "火警", + "Content": "火警报警" + }, + { + "Id": "1111", + "Level": "1", + "Type": "火警", + "Content": "烟感探头" + }, + { + "Id": "1112", + "Level": "1", + "Type": "火警", + "Content": "燃烧" + }, + { + "Id": "1113", + "Level": "1", + "Type": "火警", + "Content": "消防水流" + }, + { + "Id": "1114", + "Level": "1", + "Type": "火警", + "Content": "热感探头" + }, + { + "Id": "1115", + "Level": "1", + "Type": "火警", + "Content": "火警手动报警" + }, + { + "Id": "1117", + "Level": "1", + "Type": "火警", + "Content": "火焰探头" + }, + { + "Id": "1118", + "Level": "1", + "Type": "火警", + "Content": "接近警报" + }, + { + "Id": "1119", + "Level": "1", + "Type": "火警", + "Content": "煤气泄漏" + }, + { + "Id": "1120", + "Level": "1", + "Type": "劫盗", + "Content": "劫盗" + }, + { + "Id": "1121", + "Level": "1", + "Type": "劫盗", + "Content": "挟持" + }, + { + "Id": "1122", + "Level": "1", + "Type": "劫盗", + "Content": "无声劫盗" + }, + { + "Id": "1123", + "Level": "1", + "Type": "劫盗", + "Content": "有声劫盗" + }, + { + "Id": "1124", + "Level": "1", + "Type": "窃盗", + "Content": "异地劫持" + }, + { + "Id": "1130", + "Level": "1", + "Type": "窃盗", + "Content": "窃盗" + }, + { + "Id": "1131", + "Level": "1", + "Type": "窃盗", + "Content": "周界窃盗" + }, + { + "Id": "1132", + "Level": "1", + "Type": "窃盗", + "Content": "内部窃盗" + }, + { + "Id": "1133", + "Level": "1", + "Type": "窃盗", + "Content": "24小时窃盗" + }, + { + "Id": "1134", + "Level": "1", + "Type": "窃盗", + "Content": "出/入窃盗" + }, + { + "Id": "1135", + "Level": "1", + "Type": "窃盗", + "Content": "日/夜防区" + }, + { + "Id": "1136", + "Level": "1", + "Type": "窃盗", + "Content": "室外窃盗" + }, + { + "Id": "1137", + "Level": "1", + "Type": "窃盗", + "Content": "拆动报警" + }, + { + "Id": "1138", + "Level": "1", + "Type": "窃盗", + "Content": "接近报警" + }, + { + "Id": "1140", + "Level": "1", + "Type": "警报", + "Content": "一般报警" + }, + { + "Id": "1141", + "Level": "1", + "Type": "警报", + "Content": "总线开路" + }, + { + "Id": "1142", + "Level": "1", + "Type": "警报", + "Content": "总线短路" + }, + { + "Id": "1143", + "Level": "1", + "Type": "警报", + "Content": "扩充器故障" + }, + { + "Id": "1144", + "Level": "1", + "Type": "警报", + "Content": "探头被拆动" + }, + { + "Id": "1145", + "Level": "1", + "Type": "警报", + "Content": "扩充器被拆" + }, + { + "Id": "1150", + "Level": "1", + "Type": "警报", + "Content": "24小时非盗窃报警" + }, + { + "Id": "1151", + "Level": "1", + "Type": "警报", + "Content": "挖掘报警" + }, + { + "Id": "1152", + "Level": "1", + "Type": "警报", + "Content": "步行报警" + }, + { + "Id": "1153", + "Level": "1", + "Type": "警报", + "Content": "行车报警" + }, + { + "Id": "1156", + "Level": "1", + "Type": "警报", + "Content": "日间防区" + }, + { + "Id": "1158", + "Level": "1", + "Type": "警报", + "Content": "温度过高" + }, + { + "Id": "1159", + "Level": "1", + "Type": "警报", + "Content": "温度过低" + }, + { + "Id": "1161", + "Level": "1", + "Type": "周界窃盗", + "Content": "攀爬报警" + }, + { + "Id": "1170", + "Level": "1", + "Type": "故障", + "Content": "用户离线" + }, + { + "Id": "1180", + "Level": "1", + "Type": "故障", + "Content": "GPRS设备断线" + }, + { + "Id": "1181", + "Level": "1", + "Type": "周界窃盗", + "Content": "张力围栏报警" + }, + { + "Id": "1190", + "Level": "1", + "Type": "周界窃盗", + "Content": "脉冲围栏断路报警" + }, + { + "Id": "1191", + "Level": "1", + "Type": "周界窃盗", + "Content": "脉冲围栏短路报警" + }, + { + "Id": "1192", + "Level": "1", + "Type": "周界窃盗", + "Content": "振动光纤断光" + }, + { + "Id": "1193", + "Level": "1", + "Type": "周界窃盗", + "Content": "振动光纤触网" + }, + { + "Id": "1200", + "Level": "2", + "Type": "监控", + "Content": "火警监视" + }, + { + "Id": "1201", + "Level": "2", + "Type": "监控", + "Content": "水压过低" + }, + { + "Id": "1202", + "Level": "2", + "Type": "监控", + "Content": "二氧化碳过低" + }, + { + "Id": "1203", + "Level": "2", + "Type": "监控", + "Content": "阀门感应" + }, + { + "Id": "1300", + "Level": "3", + "Type": "故障", + "Content": "系统故障" + }, + { + "Id": "1301", + "Level": "3", + "Type": "故障", + "Content": "无交流" + }, + { + "Id": "1302", + "Level": "3", + "Type": "故障", + "Content": "电池低压" + }, + { + "Id": "1303", + "Level": "3", + "Type": "故障", + "Content": "RAM校验和故障" + }, + { + "Id": "1304", + "Level": "3", + "Type": "故障", + "Content": "ROM校验和故障" + }, + { + "Id": "1305", + "Level": "3", + "Type": "故障", + "Content": "系统重新设定" + }, + { + "Id": "1306", + "Level": "3", + "Type": "故障", + "Content": "编程改动" + }, + { + "Id": "1307", + "Level": "3", + "Type": "故障", + "Content": "自检故障" + }, + { + "Id": "1308", + "Level": "3", + "Type": "故障", + "Content": "主机停机使用" + }, + { + "Id": "1309", + "Level": "3", + "Type": "故障", + "Content": "电池测试故障" + }, + { + "Id": "130A", + "Level": "3", + "Type": "故障", + "Content": "系统复位" + }, + { + "Id": "1310", + "Level": "3", + "Type": "故障", + "Content": "接地故障" + }, + { + "Id": "1320", + "Level": "3", + "Type": "故障", + "Content": "警号/继电器" + }, + { + "Id": "1321", + "Level": "3", + "Type": "故障", + "Content": "警铃#1" + }, + { + "Id": "1322", + "Level": "3", + "Type": "故障", + "Content": "警铃#2" + }, + { + "Id": "1323", + "Level": "3", + "Type": "故障", + "Content": "警报继电器" + }, + { + "Id": "1324", + "Level": "3", + "Type": "故障", + "Content": "故障继电器" + }, + { + "Id": "1325", + "Level": "3", + "Type": "故障", + "Content": "逆转继电器" + }, + { + "Id": "132A", + "Level": "3", + "Type": "故障", + "Content": "警铃保险管烧坏" + }, + { + "Id": "1330", + "Level": "3", + "Type": "故障", + "Content": "系统周边" + }, + { + "Id": "1331", + "Level": "3", + "Type": "故障", + "Content": "总线开路" + }, + { + "Id": "1332", + "Level": "3", + "Type": "故障", + "Content": "总线短路" + }, + { + "Id": "1333", + "Level": "3", + "Type": "故障", + "Content": "防区掉线" + }, + { + "Id": "1334", + "Level": "3", + "Type": "故障", + "Content": "单元控制器掉线楼道机" + }, + { + "Id": "1335", + "Level": "3", + "Type": "故障", + "Content": "打印机无纸" + }, + { + "Id": "1339", + "Level": "3", + "Type": "故障", + "Content": "振动光纤断光" + }, + { + "Id": "1340", + "Level": "3", + "Type": "故障", + "Content": "网络设备离线" + }, + { + "Id": "1336", + "Level": "3", + "Type": "故障", + "Content": "打印机故障" + }, + { + "Id": "1350", + "Level": "3", + "Type": "故障", + "Content": "通讯故障" + }, + { + "Id": "1351", + "Level": "3", + "Type": "故障", + "Content": "电话线1故障" + }, + { + "Id": "1352", + "Level": "3", + "Type": "故障", + "Content": "电话线2故障" + }, + { + "Id": "1353", + "Level": "3", + "Type": "故障", + "Content": "长距离无线发射器故障" + }, + { + "Id": "1354", + "Level": "3", + "Type": "故障", + "Content": "通讯失败" + }, + { + "Id": "1355", + "Level": "3", + "Type": "故障", + "Content": "失去长距无线监控" + }, + { + "Id": "1356", + "Level": "3", + "Type": "故障", + "Content": "失去长距无线中央监控" + }, + { + "Id": "1357", + "Level": "3", + "Type": "故障", + "Content": "无线干扰" + }, + { + "Id": "1360", + "Level": "3", + "Type": "故障", + "Content": "防区故障" + }, + { + "Id": "1361", + "Level": "3", + "Type": "故障", + "Content": "防拆故障" + }, + { + "Id": "1362", + "Level": "3", + "Type": "故障", + "Content": "充电故障" + }, + { + "Id": "1363", + "Level": "3", + "Type": "故障", + "Content": "模块未准备就绪" + }, + { + "Id": "1370", + "Level": "3", + "Type": "故障", + "Content": "保护回路" + }, + { + "Id": "1371", + "Level": "3", + "Type": "故障", + "Content": "保护回路开路" + }, + { + "Id": "1372", + "Level": "3", + "Type": "故障", + "Content": "保护回路短路" + }, + { + "Id": "1373", + "Level": "3", + "Type": "故障", + "Content": "火警回路故障" + }, + { + "Id": "137A", + "Level": "3", + "Type": "故障", + "Content": "回路故障" + }, + { + "Id": "1380", + "Level": "3", + "Type": "故障", + "Content": "感应器故障" + }, + { + "Id": "1381", + "Level": "3", + "Type": "故障", + "Content": "无线监控故障" + }, + { + "Id": "1382", + "Level": "3", + "Type": "故障", + "Content": "总线监控故障" + }, + { + "Id": "1383", + "Level": "3", + "Type": "故障", + "Content": "感应器被拆" + }, + { + "Id": "1384", + "Level": "3", + "Type": "故障", + "Content": "无线感应器电池过低" + }, + { + "Id": "1393", + "Level": "3", + "Type": "故障", + "Content": "电话故障" + }, + { + "Id": "1394", + "Level": "3", + "Type": "故障", + "Content": "卡故障" + }, + { + "Id": "13A0", + "Level": "3", + "Type": "故障", + "Content": "请求服务" + }, + { + "Id": "13A1", + "Level": "3", + "Type": "故障", + "Content": "时间重设" + }, + { + "Id": "13A2", + "Level": "3", + "Type": "故障", + "Content": "5(12)伏电源故障" + }, + { + "Id": "13A3", + "Level": "3", + "Type": "故障", + "Content": "电话线故障" + }, + { + "Id": "13A4", + "Level": "3", + "Type": "故障", + "Content": "卡故障" + }, + { + "Id": "13A5", + "Level": "3", + "Type": "故障", + "Content": "失去电池" + }, + { + "Id": "13A6", + "Level": "3", + "Type": "故障", + "Content": "进入编程模式" + }, + { + "Id": "13A7", + "Level": "3", + "Type": "故障", + "Content": "未知故障" + }, + { + "Id": "13A8", + "Level": "3", + "Type": "故障", + "Content": "无效报告" + }, + { + "Id": "13B0", + "Level": "3", + "Type": "故障", + "Content": "用户密码更改" + }, + { + "Id": "13B1", + "Level": "3", + "Type": "故障", + "Content": "错误信息" + }, + { + "Id": "1400", + "Level": "4", + "Type": "撤防", + "Content": "撤防" + }, + { + "Id": "1401", + "Level": "4", + "Type": "撤防", + "Content": "用户撤防" + }, + { + "Id": "1402", + "Level": "4", + "Type": "撤防", + "Content": "集体撤防" + }, + { + "Id": "1403", + "Level": "4", + "Type": "撤防", + "Content": "自动撤防" + }, + { + "Id": "1404", + "Level": "4", + "Type": "撤防", + "Content": "过迟撤防" + }, + { + "Id": "1405", + "Level": "4", + "Type": "撤防", + "Content": "不适用" + }, + { + "Id": "1406", + "Level": "4", + "Type": "撤防", + "Content": "取消" + }, + { + "Id": "1407", + "Level": "4", + "Type": "撤防", + "Content": "遥控撤防" + }, + { + "Id": "1408", + "Level": "4", + "Type": "撤防", + "Content": "快速撤防" + }, + { + "Id": "1409", + "Level": "4", + "Type": "撤防", + "Content": "开关撤防" + }, + { + "Id": "140A", + "Level": "4", + "Type": "撤防", + "Content": "部分撤防" + }, + { + "Id": "140B", + "Level": "4", + "Type": "撤防", + "Content": "周边撤防" + }, + { + "Id": "1411", + "Level": "4", + "Type": "遥控", + "Content": "要求回电" + }, + { + "Id": "1412", + "Level": "4", + "Type": "遥控", + "Content": "遥控编程成功" + }, + { + "Id": "1413", + "Level": "4", + "Type": "遥控", + "Content": "遥控不成功" + }, + { + "Id": "1414", + "Level": "4", + "Type": "遥控", + "Content": "关闭系统" + }, + { + "Id": "1415", + "Level": "4", + "Type": "遥控", + "Content": "关闭通讯" + }, + { + "Id": "1416", + "Level": "4", + "Type": "撤防", + "Content": "撤防操作" + }, + { + "Id": "1417", + "Level": "4", + "Type": "撤防", + "Content": "防区撤防" + }, + { + "Id": "1421", + "Level": "4", + "Type": "出入", + "Content": "拒绝出入-用户" + }, + { + "Id": "1422", + "Level": "4", + "Type": "出入", + "Content": "成功出入-用户" + }, + { + "Id": "1441", + "Level": "4", + "Type": "出入", + "Content": "在家布防" + }, + { + "Id": "1450", + "Level": "4", + "Type": "出入", + "Content": "非正常时段撤防" + }, + { + "Id": "1451", + "Level": "4", + "Type": "出入", + "Content": "过早撤防" + }, + { + "Id": "1452", + "Level": "4", + "Type": "出入", + "Content": "过迟撤防" + }, + { + "Id": "1453", + "Level": "4", + "Type": "出入", + "Content": "撤防失败" + }, + { + "Id": "1454", + "Level": "4", + "Type": "出入", + "Content": "布防失败" + }, + { + "Id": "1455", + "Level": "4", + "Type": "出入", + "Content": "自动布防失败" + }, + { + "Id": "1456", + "Level": "4", + "Type": "出入", + "Content": "部分布防" + }, + { + "Id": "1457", + "Level": "4", + "Type": "出入", + "Content": "外出错误" + }, + { + "Id": "1458", + "Level": "4", + "Type": "出入", + "Content": "操作员在现场" + }, + { + "Id": "1459", + "Level": "4", + "Type": "出入", + "Content": "最近布防" + }, + { + "Id": "1480", + "Level": "4", + "Type": "出入", + "Content": "关警号" + }, + { + "Id": "1520", + "Level": "5", + "Type": "停用", + "Content": "停用警号/继电器" + }, + { + "Id": "1521", + "Level": "5", + "Type": "停用", + "Content": "警铃1停用" + }, + { + "Id": "1522", + "Level": "5", + "Type": "停用", + "Content": "警铃2停用" + }, + { + "Id": "1523", + "Level": "5", + "Type": "停用", + "Content": "停用警报继电器" + }, + { + "Id": "1524", + "Level": "5", + "Type": "停用", + "Content": "停用故障继电器" + }, + { + "Id": "1525", + "Level": "5", + "Type": "停用", + "Content": "逆反继电器" + }, + { + "Id": "1530", + "Level": "5", + "Type": "停用", + "Content": "停用系统周边" + }, + { + "Id": "1540", + "Level": "5", + "Type": "停用", + "Content": "停用系统周边" + }, + { + "Id": "1551", + "Level": "5", + "Type": "停用", + "Content": "通讯器停用" + }, + { + "Id": "1552", + "Level": "5", + "Type": "停用", + "Content": "无线发射器停用" + }, + { + "Id": "1570", + "Level": "5", + "Type": "旁路", + "Content": "防区旁路" + }, + { + "Id": "1571", + "Level": "5", + "Type": "旁路", + "Content": "火警旁路" + }, + { + "Id": "1572", + "Level": "5", + "Type": "旁路", + "Content": "24小时防区旁路" + }, + { + "Id": "1573", + "Level": "5", + "Type": "旁路", + "Content": "窃盗旁路" + }, + { + "Id": "1574", + "Level": "5", + "Type": "旁路", + "Content": "集体旁路" + }, + { + "Id": "1580", + "Level": "5", + "Type": "旁路", + "Content": "旁路操作" + }, + { + "Id": "1601", + "Level": "6", + "Type": "测试", + "Content": "手动测试" + }, + { + "Id": "1602", + "Level": "6", + "Type": "测试", + "Content": "定期测试" + }, + { + "Id": "1603", + "Level": "6", + "Type": "测试", + "Content": "定期无线发射器测试" + }, + { + "Id": "1604", + "Level": "6", + "Type": "测试", + "Content": "火警测试" + }, + { + "Id": "1605", + "Level": "6", + "Type": "测试", + "Content": "状态报告" + }, + { + "Id": "1606", + "Level": "6", + "Type": "测试", + "Content": "监听" + }, + { + "Id": "1607", + "Level": "6", + "Type": "测试", + "Content": "不行测试模式" + }, + { + "Id": "1609", + "Level": "6", + "Type": "测试", + "Content": "图像传输" + }, + { + "Id": "1630", + "Level": "6", + "Type": "测试", + "Content": "改动时间表" + }, + { + "Id": "1631", + "Level": "6", + "Type": "测试", + "Content": "改动例外时间表" + }, + { + "Id": "1632", + "Level": "6", + "Type": "测试", + "Content": "改动出入时间表" + }, + { + "Id": "1695", + "Level": "6", + "Type": "用户", + "Content": "提早布防" + }, + { + "Id": "1696", + "Level": "6", + "Type": "用户", + "Content": "未及时布防" + }, + { + "Id": "1697", + "Level": "6", + "Type": "用户", + "Content": "提早撤防" + }, + { + "Id": "1698", + "Level": "6", + "Type": "用户", + "Content": "未及时撤防" + }, + { + "Id": "1699", + "Level": "6", + "Type": "用户", + "Content": "超时测试间隔信号" + }, + { + "Id": "16A0", + "Level": "6", + "Type": "用户", + "Content": "用户缴费时间到" + }, + { + "Id": "16B0", + "Level": "6", + "Type": "测试", + "Content": "手动测试操作" + }, + { + "Id": "16CC", + "Level": "6", + "Type": "错误", + "Content": "测试" + }, + { + "Id": "3100", + "Level": "1", + "Type": "紧急恢复", + "Content": "个人救护报警恢复" + }, + { + "Id": "3101", + "Level": "1", + "Type": "紧急恢复", + "Content": "个人救护报警,紧急按钮恢复" + }, + { + "Id": "3102", + "Level": "1", + "Type": "紧急恢复", + "Content": "报到失败恢复" + }, + { + "Id": "3103", + "Level": "1", + "Type": "紧急恢复", + "Content": "紧急报警恢复" + }, + { + "Id": "3104", + "Level": "1", + "Type": "紧急恢复", + "Content": "紧急报警恢复" + }, + { + "Id": "3110", + "Level": "1", + "Type": "火警恢复", + "Content": "火警报警恢复" + }, + { + "Id": "3111", + "Level": "1", + "Type": "火警恢复", + "Content": "烟感探头恢复" + }, + { + "Id": "3112", + "Level": "1", + "Type": "火警恢复", + "Content": "燃烧熄灭" + }, + { + "Id": "3113", + "Level": "1", + "Type": "火警恢复", + "Content": "消防水流恢复" + }, + { + "Id": "3114", + "Level": "1", + "Type": "火警恢复", + "Content": "热感探头恢复" + }, + { + "Id": "3115", + "Level": "1", + "Type": "火警恢复", + "Content": "火警手动报警恢复" + }, + { + "Id": "3116", + "Level": "1", + "Type": "火警恢复", + "Content": "空调槽烟感恢复" + }, + { + "Id": "3117", + "Level": "1", + "Type": "火警恢复", + "Content": "火焰探头恢复" + }, + { + "Id": "3118", + "Level": "1", + "Type": "火警恢复", + "Content": "接近警报恢复" + }, + { + "Id": "3119", + "Level": "1", + "Type": "火警恢复", + "Content": "煤气泄漏恢复" + }, + { + "Id": "3120", + "Level": "1", + "Type": "劫盗恢复", + "Content": "劫盗恢复" + }, + { + "Id": "3121", + "Level": "1", + "Type": "劫盗恢复", + "Content": "挟持恢复" + }, + { + "Id": "3122", + "Level": "1", + "Type": "劫盗恢复", + "Content": "无声劫盗恢复" + }, + { + "Id": "3123", + "Level": "1", + "Type": "劫盗恢复", + "Content": "有声劫盗恢复" + }, + { + "Id": "3124", + "Level": "1", + "Type": "劫盗恢复", + "Content": "异地劫持恢复" + }, + { + "Id": "3130", + "Level": "1", + "Type": "窃盗恢复", + "Content": "窃盗恢复" + }, + { + "Id": "3131", + "Level": "1", + "Type": "窃盗恢复", + "Content": "周界窃盗恢复" + }, + { + "Id": "3132", + "Level": "1", + "Type": "窃盗恢复", + "Content": "内部窃盗恢复" + }, + { + "Id": "3133", + "Level": "1", + "Type": "窃盗恢复", + "Content": "24小时窃盗恢复" + }, + { + "Id": "3134", + "Level": "1", + "Type": "窃盗恢复", + "Content": "出/入窃盗恢复" + }, + { + "Id": "3135", + "Level": "1", + "Type": "窃盗恢复", + "Content": "日/夜防区恢复" + }, + { + "Id": "3136", + "Level": "1", + "Type": "窃盗恢复", + "Content": "室外窃盗恢复" + }, + { + "Id": "3137", + "Level": "1", + "Type": "窃盗恢复", + "Content": "拆动报警恢复" + }, + { + "Id": "3138", + "Level": "1", + "Type": "窃盗恢复", + "Content": "接近报警恢复" + }, + { + "Id": "3140", + "Level": "1", + "Type": "警报恢复", + "Content": "一般报警恢复" + }, + { + "Id": "3141", + "Level": "1", + "Type": "警报恢复", + "Content": "总线开路恢复" + }, + { + "Id": "3142", + "Level": "1", + "Type": "警报恢复", + "Content": "总线短路恢复" + }, + { + "Id": "3143", + "Level": "1", + "Type": "警报恢复", + "Content": "扩充器恢复" + }, + { + "Id": "3144", + "Level": "1", + "Type": "警报恢复", + "Content": "探头被拆动恢复" + }, + { + "Id": "3145", + "Level": "1", + "Type": "警报恢复", + "Content": "扩充器被拆恢复" + }, + { + "Id": "3150", + "Level": "1", + "Type": "警报恢复", + "Content": "24小时非窃盗报警恢复" + }, + { + "Id": "3151", + "Level": "1", + "Type": "警报恢复", + "Content": "气体恢复" + }, + { + "Id": "3152", + "Level": "1", + "Type": "警报恢复", + "Content": "冷藏器恢复" + }, + { + "Id": "3153", + "Level": "1", + "Type": "警报恢复", + "Content": "加热系统恢复" + }, + { + "Id": "3154", + "Level": "1", + "Type": "警报恢复", + "Content": "漏水恢复" + }, + { + "Id": "3155", + "Level": "1", + "Type": "警报恢复", + "Content": "箔片破损恢复" + }, + { + "Id": "3156", + "Level": "1", + "Type": "警报恢复", + "Content": "日间防区恢复" + }, + { + "Id": "3157", + "Level": "1", + "Type": "警报恢复", + "Content": "气体水平过低恢复" + }, + { + "Id": "3158", + "Level": "1", + "Type": "警报恢复", + "Content": "温度过高恢复" + }, + { + "Id": "3159", + "Level": "1", + "Type": "警报恢复", + "Content": "温度过低恢复" + }, + { + "Id": "3161", + "Level": "1", + "Type": "警报恢复", + "Content": "空气流动恢复" + }, + { + "Id": "3170", + "Level": "1", + "Type": "故障恢复", + "Content": "用户离线恢复" + }, + { + "Id": "3180", + "Level": "1", + "Type": "故障", + "Content": "GPRS设备恢复连接" + }, + { + "Id": "3200", + "Level": "2", + "Type": "监控恢复", + "Content": "火警监控恢复" + }, + { + "Id": "3201", + "Level": "2", + "Type": "监控恢复", + "Content": "水压过低恢复" + }, + { + "Id": "3202", + "Level": "2", + "Type": "监控恢复", + "Content": "二氧化碳过低恢复" + }, + { + "Id": "3203", + "Level": "2", + "Type": "监控恢复", + "Content": "阀门感应恢复" + }, + { + "Id": "3204", + "Level": "2", + "Type": "监控恢复", + "Content": "水压过低恢复" + }, + { + "Id": "3205", + "Level": "2", + "Type": "监控恢复", + "Content": "水泵关闭" + }, + { + "Id": "3206", + "Level": "2", + "Type": "监控恢复", + "Content": "水泵故障恢复" + }, + { + "Id": "3300", + "Level": "3", + "Type": "故障恢复", + "Content": "系统故障恢复" + }, + { + "Id": "3301", + "Level": "3", + "Type": "故障恢复", + "Content": "交流恢复" + }, + { + "Id": "3302", + "Level": "3", + "Type": "故障恢复", + "Content": "电池低压恢复" + }, + { + "Id": "3303", + "Level": "3", + "Type": "故障恢复", + "Content": "RAM校验和故障恢复" + }, + { + "Id": "3304", + "Level": "3", + "Type": "故障恢复", + "Content": "ROM检验和故障恢复" + }, + { + "Id": "3305", + "Level": "3", + "Type": "故障恢复", + "Content": "系统重新设定恢复" + }, + { + "Id": "3306", + "Level": "3", + "Type": "故障恢复", + "Content": "编程改动恢复" + }, + { + "Id": "3307", + "Level": "3", + "Type": "故障恢复", + "Content": "自检故障恢复" + }, + { + "Id": "3308", + "Level": "3", + "Type": "故障恢复", + "Content": "主机停机使用恢复" + }, + { + "Id": "3309", + "Level": "3", + "Type": "故障恢复", + "Content": "电池测试故障恢复" + }, + { + "Id": "330A", + "Level": "3", + "Type": "故障恢复", + "Content": "系统复位恢复" + }, + { + "Id": "3310", + "Level": "3", + "Type": "故障恢复", + "Content": "接地故障恢复" + }, + { + "Id": "3320", + "Level": "3", + "Type": "故障恢复", + "Content": "警号/继电器恢复" + }, + { + "Id": "3321", + "Level": "3", + "Type": "故障恢复", + "Content": "警铃#1恢复" + }, + { + "Id": "3322", + "Level": "3", + "Type": "故障恢复", + "Content": "警铃#2恢复" + }, + { + "Id": "3323", + "Level": "3", + "Type": "故障恢复", + "Content": "警报继电器恢复" + }, + { + "Id": "3324", + "Level": "3", + "Type": "故障恢复", + "Content": "故障继电器恢复" + }, + { + "Id": "3325", + "Level": "3", + "Type": "故障恢复", + "Content": "逆转继电器恢复" + }, + { + "Id": "332A", + "Level": "3", + "Type": "故障恢复", + "Content": "警铃保险管烧坏恢复" + }, + { + "Id": "3330", + "Level": "3", + "Type": "故障恢复", + "Content": "系统周边恢复" + }, + { + "Id": "3331", + "Level": "3", + "Type": "故障恢复", + "Content": "总线开路恢复" + }, + { + "Id": "3332", + "Level": "3", + "Type": "故障恢复", + "Content": "总线短路恢复" + }, + { + "Id": "3333", + "Level": "3", + "Type": "故障恢复", + "Content": "扩充器故障" + }, + { + "Id": "3334", + "Level": "3", + "Type": "故障恢复", + "Content": "重复器故障恢复" + }, + { + "Id": "3335", + "Level": "3", + "Type": "故障恢复", + "Content": "打印机无纸恢复" + }, + { + "Id": "3336", + "Level": "3", + "Type": "故障恢复", + "Content": "打印机故障恢复" + }, + { + "Id": "3339", + "Level": "3", + "Type": "故障恢复", + "Content": "振动光纤断光恢复" + }, + { + "Id": "3340", + "Level": "3", + "Type": "故障恢复", + "Content": "网络设备在线" + }, + { + "Id": "3350", + "Level": "3", + "Type": "故障恢复", + "Content": "通讯故障恢复" + }, + { + "Id": "3351", + "Level": "3", + "Type": "故障恢复", + "Content": "电话线1故障恢复" + }, + { + "Id": "3352", + "Level": "3", + "Type": "故障恢复", + "Content": "电话线2故障恢复" + }, + { + "Id": "3353", + "Level": "3", + "Type": "故障恢复", + "Content": "长距离无线发射器故障恢复" + }, + { + "Id": "3354", + "Level": "3", + "Type": "故障恢复", + "Content": "通讯失败恢复" + }, + { + "Id": "3355", + "Level": "3", + "Type": "故障恢复", + "Content": "失去长距无线监控恢复" + }, + { + "Id": "3356", + "Level": "3", + "Type": "故障恢复", + "Content": "失去长距无线中央监控恢复" + }, + { + "Id": "3357", + "Level": "3", + "Type": "故障恢复", + "Content": "无线感干扰恢复" + }, + { + "Id": "3360", + "Level": "3", + "Type": "故障恢复", + "Content": "防区故障恢复" + }, + { + "Id": "3361", + "Level": "3", + "Type": "故障恢复", + "Content": "防拆故障恢复" + }, + { + "Id": "3362", + "Level": "3", + "Type": "故障恢复", + "Content": "充电故障恢复" + }, + { + "Id": "3363", + "Level": "3", + "Type": "故障恢复", + "Content": "模块已准备就绪" + }, + { + "Id": "3370", + "Level": "3", + "Type": "故障恢复", + "Content": "保护回路恢复" + }, + { + "Id": "3371", + "Level": "3", + "Type": "故障恢复", + "Content": "保护回路开路恢复" + }, + { + "Id": "3372", + "Level": "3", + "Type": "故障恢复", + "Content": "保护回路短路恢复" + }, + { + "Id": "3373", + "Level": "3", + "Type": "故障恢复", + "Content": "火警回路故障恢复" + }, + { + "Id": "337A", + "Level": "3", + "Type": "故障恢复", + "Content": "回路故障恢复" + }, + { + "Id": "3380", + "Level": "3", + "Type": "故障恢复", + "Content": "感应器故障恢复" + }, + { + "Id": "3381", + "Level": "3", + "Type": "故障恢复", + "Content": "无线监控故障恢复" + }, + { + "Id": "3382", + "Level": "3", + "Type": "故障恢复", + "Content": "总线监控故障恢复" + }, + { + "Id": "3383", + "Level": "3", + "Type": "故障恢复", + "Content": "感应器被拆恢复" + }, + { + "Id": "3384", + "Level": "3", + "Type": "故障恢复", + "Content": "无线感应器电池过低恢复" + }, + { + "Id": "3393", + "Level": "3", + "Type": "故障恢复", + "Content": "电话故障恢复" + }, + { + "Id": "3394", + "Level": "3", + "Type": "故障恢复", + "Content": "卡故障恢复" + }, + { + "Id": "33A0", + "Level": "3", + "Type": "故障恢复", + "Content": "请求服务恢复" + }, + { + "Id": "33A1", + "Level": "3", + "Type": "故障恢复", + "Content": "设置时间恢复" + }, + { + "Id": "33A2", + "Level": "3", + "Type": "故障恢复", + "Content": "5(12)伏电源故障恢复" + }, + { + "Id": "33A3", + "Level": "3", + "Type": "故障恢复", + "Content": "电话线故障恢复" + }, + { + "Id": "33A4", + "Level": "3", + "Type": "故障恢复", + "Content": "卡故障恢复" + }, + { + "Id": "33A5", + "Level": "3", + "Type": "故障恢复", + "Content": "失去电池恢复" + }, + { + "Id": "33A6", + "Level": "3", + "Type": "故障恢复", + "Content": "进入编程模式恢复" + }, + { + "Id": "33A7", + "Level": "3", + "Type": "故障恢复", + "Content": "未知故障恢复" + }, + { + "Id": "33A8", + "Level": "3", + "Type": "故障恢复", + "Content": "无效报告恢复" + }, + { + "Id": "33B0", + "Level": "3", + "Type": "密码恢复", + "Content": "用户密码更改恢复" + }, + { + "Id": "33B1", + "Level": "3", + "Type": "故障恢复", + "Content": "错误恢复" + }, + { + "Id": "3400", + "Level": "4", + "Type": "布防", + "Content": "布防" + }, + { + "Id": "3401", + "Level": "4", + "Type": "布防", + "Content": "用户布防" + }, + { + "Id": "3402", + "Level": "4", + "Type": "布防", + "Content": "集体布防" + }, + { + "Id": "3403", + "Level": "4", + "Type": "布防", + "Content": "自动布防" + }, + { + "Id": "3404", + "Level": "4", + "Type": "布防", + "Content": "过迟布防" + }, + { + "Id": "3405", + "Level": "4", + "Type": "布防", + "Content": "不适用恢复" + }, + { + "Id": "3406", + "Level": "4", + "Type": "布防", + "Content": "取消恢复" + }, + { + "Id": "3407", + "Level": "4", + "Type": "布防", + "Content": "遥控布防" + }, + { + "Id": "3408", + "Level": "4", + "Type": "布防", + "Content": "快速布防" + }, + { + "Id": "3409", + "Level": "4", + "Type": "布防", + "Content": "开关布防" + }, + { + "Id": "340A", + "Level": "4", + "Type": "布防", + "Content": "部分布防" + }, + { + "Id": "340B", + "Level": "4", + "Type": "布防", + "Content": "周边布防" + }, + { + "Id": "3411", + "Level": "4", + "Type": "遥控恢复", + "Content": "要求回电恢复" + }, + { + "Id": "3412", + "Level": "4", + "Type": "遥控恢复", + "Content": "遥控编程成功恢复" + }, + { + "Id": "3413", + "Level": "4", + "Type": "遥控恢复", + "Content": "遥控不成功恢复" + }, + { + "Id": "3414", + "Level": "4", + "Type": "遥控恢复", + "Content": "关闭系统恢复" + }, + { + "Id": "3415", + "Level": "4", + "Type": "遥控恢复", + "Content": "关闭通讯恢复" + }, + { + "Id": "3416", + "Level": "4", + "Type": "布防", + "Content": "布防操作" + }, + { + "Id": "3417", + "Level": "4", + "Type": "布防", + "Content": "防区布防" + }, + { + "Id": "3421", + "Level": "4", + "Type": "出入恢复", + "Content": "拒绝出入-用户恢复" + }, + { + "Id": "3422", + "Level": "4", + "Type": "出入恢复", + "Content": "成功出入-用户恢复" + }, + { + "Id": "3441", + "Level": "4", + "Type": "布防", + "Content": "留守布防" + }, + { + "Id": "3450", + "Level": "4", + "Type": "出入恢复", + "Content": "非正常时段布防" + }, + { + "Id": "3451", + "Level": "4", + "Type": "出入恢复", + "Content": "过早布防" + }, + { + "Id": "3452", + "Level": "4", + "Type": "出入恢复", + "Content": "过迟布防" + }, + { + "Id": "3453", + "Level": "4", + "Type": "出入恢复", + "Content": "撤防失败恢复" + }, + { + "Id": "3454", + "Level": "4", + "Type": "出入恢复", + "Content": "布防失败恢复" + }, + { + "Id": "3455", + "Level": "4", + "Type": "出入恢复", + "Content": "自动布防失败恢复" + }, + { + "Id": "3456", + "Level": "4", + "Type": "出入恢复", + "Content": "部分布防恢复" + }, + { + "Id": "3457", + "Level": "4", + "Type": "出入恢复", + "Content": "外出错误恢复" + }, + { + "Id": "3458", + "Level": "4", + "Type": "出入恢复", + "Content": "操作员在现场恢复" + }, + { + "Id": "3459", + "Level": "4", + "Type": "出入恢复", + "Content": "最近布防恢复" + }, + { + "Id": "3480", + "Level": "4", + "Type": "用户恢复", + "Content": "开警号" + }, + { + "Id": "3520", + "Level": "5", + "Type": "停用恢复", + "Content": "停用警号/继电器恢复" + }, + { + "Id": "3521", + "Level": "5", + "Type": "停用恢复", + "Content": "警铃1停用恢复" + }, + { + "Id": "3522", + "Level": "5", + "Type": "停用恢复", + "Content": "警铃2停用恢复" + }, + { + "Id": "3523", + "Level": "5", + "Type": "停用恢复", + "Content": "停用警报继电器恢复" + }, + { + "Id": "3524", + "Level": "5", + "Type": "停用恢复", + "Content": "停用故障继电器恢复" + }, + { + "Id": "3525", + "Level": "5", + "Type": "停用恢复", + "Content": "逆反继电器恢复" + }, + { + "Id": "3530", + "Level": "5", + "Type": "停用恢复", + "Content": "停用系统周边恢复" + }, + { + "Id": "3540", + "Level": "5", + "Type": "停用恢复", + "Content": "停用系统周边恢复" + }, + { + "Id": "3551", + "Level": "5", + "Type": "停用恢复", + "Content": "通讯器停用恢复" + }, + { + "Id": "3552", + "Level": "5", + "Type": "停用恢复", + "Content": "无线发射器停用恢复" + }, + { + "Id": "3570", + "Level": "5", + "Type": "旁路恢复", + "Content": "防区旁路恢复" + }, + { + "Id": "3571", + "Level": "5", + "Type": "旁路恢复", + "Content": "火警旁路恢复" + }, + { + "Id": "3572", + "Level": "5", + "Type": "旁路恢复", + "Content": "24小时防区旁路恢复" + }, + { + "Id": "3573", + "Level": "5", + "Type": "旁路恢复", + "Content": "窃盗旁路恢复" + }, + { + "Id": "3574", + "Level": "5", + "Type": "旁路恢复", + "Content": "集体旁路恢复" + }, + { + "Id": "3580", + "Level": "5", + "Type": "旁路恢复", + "Content": "旁路操作恢复" + }, + { + "Id": "3601", + "Level": "6", + "Type": "测试恢复", + "Content": "手动测试恢复" + }, + { + "Id": "3602", + "Level": "6", + "Type": "测试恢复", + "Content": "定期测试恢复" + }, + { + "Id": "3603", + "Level": "6", + "Type": "测试恢复", + "Content": "定期无线发射器测试恢复" + }, + { + "Id": "3604", + "Level": "6", + "Type": "测试恢复", + "Content": "火警测试恢复" + }, + { + "Id": "3605", + "Level": "6", + "Type": "测试恢复", + "Content": "状态报告恢复" + }, + { + "Id": "3606", + "Level": "6", + "Type": "测试恢复", + "Content": "监听恢复" + }, + { + "Id": "3607", + "Level": "6", + "Type": "测试恢复", + "Content": "步行测试模式恢复" + }, + { + "Id": "3609", + "Level": "6", + "Type": "测试恢复", + "Content": "图像传输恢复" + }, + { + "Id": "3630", + "Level": "6", + "Type": "测试恢复", + "Content": "改动时间表恢复" + }, + { + "Id": "3631", + "Level": "6", + "Type": "测试恢复", + "Content": "改动例外时间表恢复" + }, + { + "Id": "3632", + "Level": "6", + "Type": "测试恢复", + "Content": "改动出入时间表恢复" + }, + { + "Id": "3695", + "Level": "6", + "Type": "用户恢复", + "Content": "提早布防恢复" + }, + { + "Id": "3696", + "Level": "6", + "Type": "用户恢复", + "Content": "未及时布防恢复" + }, + { + "Id": "3697", + "Level": "6", + "Type": "用户恢复", + "Content": "提早撤防恢复" + }, + { + "Id": "3698", + "Level": "6", + "Type": "用户恢复", + "Content": "未及时撤防恢复" + }, + { + "Id": "3699", + "Level": "6", + "Type": "用户恢复", + "Content": "超过测试间隔信号恢复" + }, + { + "Id": "36B0", + "Level": "6", + "Type": "测试恢复", + "Content": "手动测试操作恢复" + } ] \ No newline at end of file diff --git a/JiLinApp/Components/CameraRealPlay.xaml b/JiLinApp/Components/CameraRealPlay.xaml new file mode 100644 index 0000000..43602e7 --- /dev/null +++ b/JiLinApp/Components/CameraRealPlay.xaml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/JiLinApp/Components/HikRealPlay.xaml.cs b/JiLinApp/Components/CameraRealPlay.xaml.cs similarity index 84% rename from JiLinApp/Components/HikRealPlay.xaml.cs rename to JiLinApp/Components/CameraRealPlay.xaml.cs index 50cf8ee..7ded6a4 100644 --- a/JiLinApp/Components/HikRealPlay.xaml.cs +++ b/JiLinApp/Components/CameraRealPlay.xaml.cs @@ -7,25 +7,20 @@ using System.Windows.Interop; namespace JiLinApp.Components; /// -/// HikRealPlay.xaml 的交互逻辑 +/// CameraRealPlay.xaml 的交互逻辑 /// -public partial class HikRealPlay : Window +public partial class CameraRealPlay : Window { #region - private HiKSDK hikSdk { get; } + private ICameraSDK CameraSdk { get; } #endregion - public HikRealPlay(HiKSDK hikSdk) + public CameraRealPlay(ICameraSDK cameraSdk) { InitializeComponent(); - this.hikSdk = hikSdk; - } - - ~HikRealPlay() - { - StopPlay(); + CameraSdk = cameraSdk; } #region Base @@ -33,15 +28,16 @@ public partial class HikRealPlay : Window public void StartPlay() { IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(player)).Handle; - hikSdk.StartPlay(hwnd); + CameraSdk.StartPlay(hwnd); } public void StopPlay() { - hikSdk.StopPlay(); + CameraSdk.StopPlay(); } #endregion + private const int GWL_STYLE = -16; private const int WS_MAXIMIZEBOX = 0x10000; private const int WS_MINIMIZEBOX = 0x20000; @@ -84,5 +80,14 @@ public partial class HikRealPlay : Window SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); } + public bool IsClosed { get; private set; } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + IsClosed = true; + StopPlay(); + } + #endregion } \ No newline at end of file diff --git a/JiLinApp/Components/HikRealPlay.xaml b/JiLinApp/Components/HikRealPlay.xaml deleted file mode 100644 index 045d75c..0000000 --- a/JiLinApp/Components/HikRealPlay.xaml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/JiLinApp/Core/Global.cs b/JiLinApp/Core/Global.cs index 48ab7e0..14b5d91 100644 --- a/JiLinApp/Core/Global.cs +++ b/JiLinApp/Core/Global.cs @@ -45,6 +45,7 @@ public static class Global public static void Init() { + LogUnit.Init(); AlarmCodeHelper.Init(); } } \ No newline at end of file diff --git a/JiLinApp/Core/LogUnit.cs b/JiLinApp/Core/LogUnit.cs index a349e14..64d7e66 100644 --- a/JiLinApp/Core/LogUnit.cs +++ b/JiLinApp/Core/LogUnit.cs @@ -1,5 +1,7 @@ using log4net; +using log4net.Config; using System; +using System.IO; namespace JiLinApp.Core; @@ -9,8 +11,13 @@ public static class LogUnit static LogUnit() { - log4net.Config.XmlConfigurator.Configure(); - logger = LogManager.GetLogger("root"); + string fileName = Path.Combine("config", "log4net.Config"); + XmlConfigurator.Configure(new FileInfo(fileName)); + logger = LogManager.GetLogger(typeof(LogUnit)); + } + + public static void Init() + { } public static void Debug(string msg) diff --git a/JiLinApp/JiLinApp.csproj b/JiLinApp/JiLinApp.csproj index 7e150c4..8b6341e 100644 --- a/JiLinApp/JiLinApp.csproj +++ b/JiLinApp/JiLinApp.csproj @@ -20,7 +20,6 @@ true - diff --git a/JiLinApp/Mvvm/ViewModelBase.cs b/JiLinApp/Mvvm/ViewModelBase.cs index 7bca07d..56185ca 100644 --- a/JiLinApp/Mvvm/ViewModelBase.cs +++ b/JiLinApp/Mvvm/ViewModelBase.cs @@ -11,7 +11,7 @@ public abstract class AbstractViewModelBase : BindableBase protected IRegionManager _region { get; set; } protected IEventAggregator _ea { get; set; } - #endregion fields + #endregion Fields public AbstractViewModelBase(IRegionManager region, IEventAggregator ea) { diff --git a/JiLinApp/Pages/FenceServerManage/Main.xaml b/JiLinApp/Pages/FenceServerManage/Main.xaml index 1319fc8..a809010 100644 --- a/JiLinApp/Pages/FenceServerManage/Main.xaml +++ b/JiLinApp/Pages/FenceServerManage/Main.xaml @@ -27,15 +27,9 @@ - - - - + - - - diff --git a/JiLinApp/Pages/FenceServerManage/Main.xaml.cs b/JiLinApp/Pages/FenceServerManage/Main.xaml.cs index 27c023d..dd7531a 100644 --- a/JiLinApp/Pages/FenceServerManage/Main.xaml.cs +++ b/JiLinApp/Pages/FenceServerManage/Main.xaml.cs @@ -1,5 +1,4 @@ -using JiLinApp.Core; -using JiLinApp.Docking.FenceAlarm; +using JiLinApp.Docking.FenceAlarm; using System; using System.Windows; using System.Windows.Controls; @@ -32,8 +31,8 @@ public partial class Main : UserControl MainViewModel vm = DataContext as MainViewModel; vm.SetView(this); - //Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState; - //Manager.OnUdpAlarmSectionState += vm.OnUdpAlarmSectionState; + Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState; + Manager.OnUdpAlarmSectionState += vm.OnUdpAlarmSectionState; Manager.OnUdpAlarmEvent += vm.OnUdpAlarmEvent; } } @@ -62,9 +61,7 @@ public partial class Main : UserControl { UdpManagerConfig config = new() { - ServerIp = ServerIp.Text, ServerPort = int.Parse(ServerPort.Text), - DevicePort = int.Parse(DevicePort.Text), DeviceHeartKeep = int.Parse(DeviceHeartKeep.Text) }; Manager.StartServer(config); diff --git a/JiLinApp/Pages/Main/MainWindow.xaml b/JiLinApp/Pages/Main/MainWindow.xaml index 42b777f..567764b 100644 --- a/JiLinApp/Pages/Main/MainWindow.xaml +++ b/JiLinApp/Pages/Main/MainWindow.xaml @@ -35,7 +35,7 @@ - + diff --git a/JiLinApp/Pages/PtzManage/Main.xaml b/JiLinApp/Pages/PtzManage/Main.xaml index f6ce88a..2d103f7 100644 --- a/JiLinApp/Pages/PtzManage/Main.xaml +++ b/JiLinApp/Pages/PtzManage/Main.xaml @@ -161,7 +161,7 @@ - +