diff --git a/EC.Util/CameraSDK/Common/ICameraSDK.cs b/EC.Util/CameraSDK/Common/ICameraSDK.cs index aea8e44..60efa38 100644 --- a/EC.Util/CameraSDK/Common/ICameraSDK.cs +++ b/EC.Util/CameraSDK/Common/ICameraSDK.cs @@ -36,7 +36,7 @@ public abstract class ICameraSDK /// /// 构建异常 /// - public abstract void BuildException(); + internal abstract void BuildException(); #endregion Base Method diff --git a/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs b/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs index 7b43898..a8c352d 100644 --- a/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs +++ b/EC.Util/CameraSDK/DaHua/DaHuaOriSDK.cs @@ -622,67 +622,67 @@ public static class DaHuaOriSDK /// Up /// 上 /// - UP_CONTROL = 0, + UP = 0, /// /// Down /// 下 /// - DOWN_CONTROL, + DOWN, /// /// Left /// 左 /// - LEFT_CONTROL, + LEFT, /// /// Right /// 右 /// - RIGHT_CONTROL, + RIGHT, /// /// +Zoom in /// 变倍+ /// - ZOOM_ADD_CONTROL, + ZOOM_ADD, /// /// -Zoom out /// 变倍- /// - ZOOM_DEC_CONTROL, + ZOOM_DEC, /// /// +Focus /// 调焦+ /// - FOCUS_ADD_CONTROL, + FOCUS_ADD, /// /// -Focus /// 调焦- /// - FOCUS_DEC_CONTROL, + FOCUS_DEC, /// /// + Aperture /// 光圈+ /// - APERTURE_ADD_CONTROL, + APERTURE_ADD, /// /// -Aperture /// 光圈- /// - APERTURE_DEC_CONTROL, + APERTURE_DEC, /// /// Go to preset /// 转至预置点 /// - POINT_MOVE_CONTROL, + POINT_MOVE, /// /// Set diff --git a/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs b/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs index 28610de..bcb7cfc 100644 --- a/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs +++ b/EC.Util/CameraSDK/DaHua/DaHuaSDK.cs @@ -59,7 +59,7 @@ public class DaHuaSDK : ICameraSDK return LoginId != IntPtr.Zero; } - public override void BuildException() + internal override void BuildException() { uint errCode = (uint)DaHuaOriSDK.CLIENT_GetLastError(); if (errCode == 0) return; @@ -137,28 +137,21 @@ public class DaHuaSDK : ICameraSDK 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; + int channel = 0; + bool stopFlag = stop == 1; + bool flag = DaHuaOriSDK.CLIENT_DHPTZControlEx2(LoginId, channel, (uint)cmd, speed, speed, 0, stopFlag, IntPtr.Zero); + //if (flag) BuildException(); + return flag; } 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; + int channel = 0; + bool flag = DaHuaOriSDK.CLIENT_DHPTZControlEx2(LoginId, channel, (uint)DaHuaOriSDK.EM_EXTPTZ_ControlType.POINT_MOVE, 0, presetId, 0, false, IntPtr.Zero); + if (flag) BuildException(); + return flag; } #endregion Ptz Method diff --git a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs index 3076f50..9e02c65 100644 --- a/EC.Util/CameraSDK/HiK/HiKOriSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKOriSDK.cs @@ -55,6 +55,13 @@ public static class HiKOriSDK #region PtzMove + public const int ZOOM_IN = 11;// 焦距以速度SS变大(倍率变大) + public const int ZOOM_OUT = 12;// 焦距以速度SS变小(倍率变小) + public const int FOCUS_NEAR = 13;// 焦点以速度SS前调 + public const int FOCUS_FAR = 14;// 焦点以速度SS后调 + public const int IRIS_OPEN = 15;// 光圈以速度SS扩大 + public const int IRIS_CLOSE = 16;// 光圈以速度SS缩小 + public const int TILT_UP = 21; /* 云台以SS的速度上仰 */ public const int TILT_DOWN = 22; /* 云台以SS的速度下俯 */ public const int PAN_LEFT = 23; /* 云台以SS的速度左转 */ diff --git a/EC.Util/CameraSDK/HiK/HiKSDK.cs b/EC.Util/CameraSDK/HiK/HiKSDK.cs index ad92565..320ec28 100644 --- a/EC.Util/CameraSDK/HiK/HiKSDK.cs +++ b/EC.Util/CameraSDK/HiK/HiKSDK.cs @@ -46,7 +46,7 @@ public class HiKSDK : ICameraSDK return LoginId >= 0; } - public override void BuildException() + internal override void BuildException() { uint errCode = HiKOriSDK.NET_DVR_GetLastError(); if (errCode == 0) return; @@ -125,7 +125,9 @@ public class HiKSDK : ICameraSDK { if (!ConnectSuccess()) return false; int lChannel = 1; - return HiKOriSDK.NET_DVR_PTZControlWithSpeed_Other(LoginId, lChannel, (uint)cmd, (uint)stop, (uint)speed); + bool flag = HiKOriSDK.NET_DVR_PTZControlWithSpeed_Other(LoginId, lChannel, (uint)cmd, (uint)stop, (uint)speed); + //if (flag) BuildException(); + return flag; } public override bool PtzPreset(int cmd, int presetId) diff --git a/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs b/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs index 0343a95..991cb12 100644 --- a/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs +++ b/EC.Util/CameraSDK/YuShi/YuShiOriSDK.cs @@ -53,6 +53,14 @@ public static class YuShiOriSDK public const int NETDEV_LEN_260 = 260; /* NETDEV_PTZ_E */ + public const int IRISCLOSE_STOP = 0x0101; /* Iris close stop */ + public const int IRISCLOSE = 0x0102; /* Iris close */ + public const int IRISOPEN_STOP = 0x0103; /* Iris open stop */ + public const int IRISOPEN = 0x0104; /* Iris open */ + public const int FOCUSNEAR_STOP = 0x0201; /* Focus near stop */ + public const int FOCUSNEAR = 0x0202; /* Focus near */ + public const int FOCUSFAR_STOP = 0x0203; /* Focus far stop */ + public const int FOCUSFAR = 0x0204; /* Focus far */ 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 */ diff --git a/EC.Util/CameraSDK/YuShi/YuShiSDK.cs b/EC.Util/CameraSDK/YuShi/YuShiSDK.cs index 655bf8b..53c2711 100644 --- a/EC.Util/CameraSDK/YuShi/YuShiSDK.cs +++ b/EC.Util/CameraSDK/YuShi/YuShiSDK.cs @@ -49,7 +49,7 @@ public class YuShiSDK : ICameraSDK return LoginId != IntPtr.Zero; } - public override void BuildException() + internal override void BuildException() { int errCode = YuShiOriSDK.NETDEV_GetLastError(); if (errCode == 0) return; @@ -91,6 +91,7 @@ public class YuShiSDK : ICameraSDK if (stop == 1) cmd = YuShiOriSDK.ALLSTOP; int channel = 1; int flag = YuShiOriSDK.NETDEV_PTZControl_Other(LoginId, channel, cmd, speed); + //if (flag) BuildException(); return flag == YuShiOriSDK.TRUE; } diff --git a/JiLinApp.Biz/TransmitAlarm/Common/Config.cs b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs index b35b574..6427bb3 100644 --- a/JiLinApp.Biz/TransmitAlarm/Common/Config.cs +++ b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs @@ -21,10 +21,21 @@ public class MqttConfig public string ClientId { get; set; } + public int RetryTime { get; set; } + + public int RetryInterval { get; set; } + public string PubAlarmTopic { get; set; } - public string SubTopic { get; set; } + public string PubDevicesTopic { get; set; } + + public string PubSensorsTopic { get; set; } + + public string PubDeviceStateTopic { get; set; } + + public string PubSensorStateTopic { get; set; } + public string SubCmdTopic { get; set; } } public class ZmqConfig diff --git a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs index 501c0ba..1da84a6 100644 --- a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs +++ b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs @@ -1,6 +1,9 @@ using EC.Util.Common; using MQTTnet; using MQTTnet.Client; +using MQTTnet.Exceptions; +using NewLife.Serialization; +using Newtonsoft.Json.Linq; using System.Text; namespace JiLinApp.Biz.TransmitAlarm; @@ -11,14 +14,20 @@ public class AlarmMqttService : IAlarmService private MqttConfig Config { get; } - //private MqttServer Server { get; } - private IMqttClient Client { get; } private MqttClientOptions ClientOptions { get; } private MqttClientSubscribeOptions SubscribeOptions { get; } + public event IAlarmService.HandleRecvEvent? OnFenceUdpSendDevices; + + public event IAlarmService.HandleRecvEvent? OnVibrateTcpSendDevices; + + public event IAlarmService.HandleRecvEvent? OnFenceUdpSendSensors; + + public event IAlarmService.HandleRecvEvent? OnVibrateTcpSendSensors; + #endregion Fields public AlarmMqttService(MqttConfig config) @@ -34,7 +43,7 @@ public class AlarmMqttService : IAlarmService .WithKeepAlivePeriod(TimeSpan.FromSeconds(60)) .Build(); SubscribeOptions = factory.CreateSubscribeOptionsBuilder() - .WithTopicFilter(f => f.WithTopic("mqttnet/samples/topic/1")) + .WithTopicFilter(f => f.WithTopic(config.SubCmdTopic)) .Build(); Config = config; @@ -51,8 +60,30 @@ public class AlarmMqttService : IAlarmService public void Start() { if (IsRuning()) return; - MqttClientConnectResult connResult = Client.ConnectAsync(ClientOptions, CancellationToken.None).Result; - MqttClientSubscribeResult subResult = Client.SubscribeAsync(SubscribeOptions, CancellationToken.None).Result; + int retryTime = Config.RetryTime, retryInterval = Config.RetryInterval; + for (int i = 1; i <= retryTime; i++) + { + MqttClientConnectResult connResult = Client.ConnectAsync(ClientOptions, CancellationToken.None).Result; + if (connResult.ResultCode == MqttClientConnectResultCode.Success) break; + if (i == retryTime) throw new MqttCommunicationTimedOutException(); + Thread.Sleep(retryInterval); + } + for (int i = 1; i <= retryTime; i++) + { + MqttClientSubscribeResult subResult = Client.SubscribeAsync(SubscribeOptions, CancellationToken.None).Result; + bool flag = true; + foreach (var item in subResult.Items) + { + if (item.ResultCode > MqttClientSubscribeResultCode.GrantedQoS2) + { + flag = false; + break; + } + } + if (flag) break; + if (i == retryTime) throw new MqttCommunicationTimedOutException(); + Thread.Sleep(retryInterval); + } } public void Close() @@ -66,11 +97,108 @@ public class AlarmMqttService : IAlarmService return Client != null && Client.IsConnected; } - public void SendAlarmMessage(AlarmMessage msg) + private object StartAtomObj { get; } = new(); + + private bool StartAtom() + { + lock (StartAtomObj) + { + if (!IsRuning()) Start(); + } + return IsRuning(); + } + + #endregion Base + + #region Receive + + private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg) + { + string topic = arg.ApplicationMessage.Topic; + string msg = Encoding.UTF8.GetString(arg.ApplicationMessage.Payload); + string qos = arg.ApplicationMessage.QualityOfServiceLevel.ToString(); + string retained = arg.ApplicationMessage.Retain.ToString(); + if (topic.Equals(Config.SubCmdTopic)) + { + HandleRecvSubCmdTopic(topic, msg); + } + return Task.CompletedTask; + } + + private void HandleRecvSubCmdTopic(string topic, string reqJson) + { + JObject reqObj = JsonUtil.ToJObject(reqJson); + string cmd = reqObj.GetValue("cmd", StringComparison.OrdinalIgnoreCase)?.ToString() ?? ""; + DeviceType type = (DeviceType)(reqObj.GetValue("type", StringComparison.OrdinalIgnoreCase).ToInt()); + switch (cmd.Trim().ToLower()) + { + case "getdevices": + switch (type) + { + case DeviceType.Vibrate: + OnVibrateTcpSendDevices?.Invoke(reqObj); + break; + + case DeviceType.Fence: + OnFenceUdpSendDevices?.Invoke(reqObj); + break; + } + break; + + case "getsensors": + switch (type) + { + case DeviceType.Vibrate: + OnVibrateTcpSendSensors?.Invoke(reqObj); + break; + + case DeviceType.Fence: + OnFenceUdpSendSensors?.Invoke(reqObj); + break; + } + break; + } + } + + #endregion Receive + + #region Send + + private int Frame { get; set; } = 0; + + private int IncFrame + { get { return ++Frame % int.MaxValue; } } + + private void Send(string topic, object obj) + { + MqttApplicationMessage mqttMsg = new MqttApplicationMessageBuilder() + .WithTopic(topic) + .WithPayload(obj.ToJson()) + .Build(); + MqttClientPublishResult? pubResult = null; + while (pubResult == null || !pubResult.IsSuccess) + { + try + { + pubResult = Client.PublishAsync(mqttMsg, CancellationToken.None).Result; + } + catch (Exception) + { + while (!IsRuning()) + { + if (StartAtom()) break; + Thread.Sleep(100); + } + } + } + } + + private void SendByFrame(string topic, object obj) { + //((dynamic)obj).Frame = IncFrame;// no work, transto dict, add frame, transto json MqttApplicationMessage mqttMsg = new MqttApplicationMessageBuilder() - .WithTopic(Config.PubAlarmTopic) - .WithPayload(JsonUtil.ToJson(msg)) + .WithTopic(topic) + .WithPayload(obj.ToJson()) .Build(); MqttClientPublishResult? pubResult = null; while (pubResult == null || !pubResult.IsSuccess) @@ -81,24 +209,71 @@ public class AlarmMqttService : IAlarmService } catch (Exception) { - Start(); - Thread.Sleep(100); + while (!IsRuning()) + { + if (StartAtom()) break; + Thread.Sleep(100); + } } } } - #endregion Base + public void SendAlarm(AlarmMessage msg) + { + Send(Config.PubAlarmTopic, msg); + } - #region Receive + public void SendDevices(DeviceType type, List deviceList) + { + object obj = new + { + type = type, + data = deviceList, + frame = IncFrame + }; + Send(Config.PubDevicesTopic, obj); + } - private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg) + public void SendSensors(DeviceType type, int deviceId, List sensorList) { - string topic = arg.ApplicationMessage.Topic; - string text = Encoding.UTF8.GetString(arg.ApplicationMessage.Payload); - string qos = arg.ApplicationMessage.QualityOfServiceLevel.ToString(); - string retained = arg.ApplicationMessage.Retain.ToString(); - return Task.CompletedTask; + object obj = new + { + type = type, + deviceId = deviceId, + data = sensorList, + frame = IncFrame + }; + Send(Config.PubSensorsTopic, obj); } - #endregion Receive + public void SendDeviceState(DeviceType type, object device) + { + object obj = new + { + type = type, + data = device, + frame = IncFrame + }; + Send(Config.PubDeviceStateTopic, obj); + } + + public void SendSensorState(DeviceType type, object sensor) + { + object obj = new + { + type = type, + data = sensor, + frame = IncFrame + }; + Send(Config.PubSensorStateTopic, obj); + } + + #endregion Send +} + +public enum DeviceType : int +{ + Unknown = 0, + Vibrate = 3, + Fence = 4, } \ No newline at end of file diff --git a/JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs b/JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs index db09aac..c9ec46d 100644 --- a/JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs +++ b/JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs @@ -2,6 +2,11 @@ public class AlarmZmqService : IAlarmService { + public event IAlarmService.HandleRecvEvent? OnFenceUdpSendDevices; + public event IAlarmService.HandleRecvEvent? OnVibrateTcpSendDevices; + public event IAlarmService.HandleRecvEvent? OnFenceUdpSendSensors; + public event IAlarmService.HandleRecvEvent? OnVibrateTcpSendSensors; + public void Start() { throw new NotImplementedException(); @@ -17,7 +22,27 @@ public class AlarmZmqService : IAlarmService throw new NotImplementedException(); } - public void SendAlarmMessage(AlarmMessage msg) + public void SendAlarm(AlarmMessage msg) + { + throw new NotImplementedException(); + } + + public void SendDevices(DeviceType type, List deviceList) + { + throw new NotImplementedException(); + } + + public void SendSensors(DeviceType type, int deviceId, List sensorList) + { + throw new NotImplementedException(); + } + + public void SendDeviceState(DeviceType type, object device) + { + throw new NotImplementedException(); + } + + public void SendSensorState(DeviceType type, object sensor) { throw new NotImplementedException(); } diff --git a/JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs b/JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs index 3c65d34..32c6342 100644 --- a/JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs +++ b/JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs @@ -1,12 +1,44 @@ -namespace JiLinApp.Biz.TransmitAlarm; +using Newtonsoft.Json.Linq; + +namespace JiLinApp.Biz.TransmitAlarm; public interface IAlarmService { + #region Event + + public delegate void HandleRecvEvent(JObject reqObj); + + public event HandleRecvEvent? OnFenceUdpSendDevices; + + public event HandleRecvEvent? OnVibrateTcpSendDevices; + + public event HandleRecvEvent? OnFenceUdpSendSensors; + + public event HandleRecvEvent? OnVibrateTcpSendSensors; + + #endregion Event + + #region Base + void Start(); void Close(); bool IsRuning(); - void SendAlarmMessage(AlarmMessage msg); + #endregion Base + + #region Send + + void SendAlarm(AlarmMessage msg); + + void SendDevices(DeviceType type, List deviceList); + + void SendSensors(DeviceType type, int deviceId, List sensorList); + + void SendDeviceState(DeviceType type, object device); + + void SendSensorState(DeviceType type, object sensor); + + #endregion Send } \ No newline at end of file diff --git a/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs b/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs index 80918cf..a67e255 100644 --- a/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs +++ b/JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs @@ -4,6 +4,8 @@ public class SectorState { #region Fields + public int DeviceId { get; set; } + public int Id { get; set; }//防区号 /// @@ -64,8 +66,9 @@ public class SectorState #endregion Fields - public SectorState(int id, byte data) + public SectorState(int deviceId, int id, byte data) { + DeviceId = deviceId; Id = id; State = data & 0x0F; Type = data >> 4; diff --git a/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs b/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs index df57a8a..257faf6 100644 --- a/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs +++ b/JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs @@ -4,7 +4,6 @@ namespace JiLinApp.Docking.FenceAlarm; public class UdpAlarmHostMessage { - public int Id { get; set; } public string AlarmTime { get; set; }//报警时间 public string CID { get; set; }//CID代码 diff --git a/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs b/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs index 0d4de82..508f7fd 100644 --- a/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs +++ b/JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Concurrent; +using JiLinApp.Docking.VibrateAlarm; +using System.Collections.Concurrent; using System.Net; using System.Timers; using Timer = System.Timers.Timer; @@ -19,17 +20,17 @@ public class UdpManager #region Event - public delegate void UDPAlarmDeviceStateEvent(int deviceId, int state); + public delegate void FenceUdpDeviceStateEvent(UdpAlarmHost device); - public delegate void UDPAlarmSectorStateEvent(int deviceId, int sectorId, int state); + public delegate void FenceUdpSectorStateEvent(SectorState sector); - public delegate void UDPAlarmEvent(UdpAlarmHostMessage msg); + public delegate void FenceUdpAlarmEvent(UdpAlarmHostMessage msg); - public event UDPAlarmDeviceStateEvent? OnUdpAlarmDeviceState; + public event FenceUdpDeviceStateEvent? OnFenceUdpDeviceState; - public event UDPAlarmSectorStateEvent? OnUdpAlarmSectorState; + public event FenceUdpSectorStateEvent? OnFenceUdpSectorState; - public event UDPAlarmEvent? OnUdpAlarm; + public event FenceUdpAlarmEvent? OnFenceUdpAlarm; #endregion Event @@ -44,16 +45,10 @@ public class UdpManager public void Start(UdpManagerConfig config) { if (IsRunning()) return; - try - { - Server = new(config.ServerPort); - Server.DatagramReceived += Server_DatagramReceived; - Server.Start(); - } - catch (Exception) - { - return; - } + Server = new(config.ServerPort); + Server.DatagramReceived += Server_DatagramReceived; + Server.Start(); + PtzCheckTimer.Interval = 1000;//1s PtzCheckTimer.Elapsed += PTZCheckTimer_Elapsed; PtzCheckTimer.Enabled = true; @@ -94,17 +89,11 @@ public class UdpManager /// private void PTZCheckTimer_Elapsed(object? sender, ElapsedEventArgs e) { - foreach (var item in DeviceDict.Values) + foreach (var key in DeviceDict.Keys) { - if (item.KeepLive >= 0) - { - item.KeepLive--; - } - else - { - item.OnlineState = 0; - OnUdpAlarmDeviceState?.Invoke(item.DeviceId, 0); - } + UdpAlarmHost device = DeviceDict[key]; + if (device.KeepLive >= 0) device.KeepLive--; + else ProcessDeviceStateEvent(ref device, 0, device.DefenceState); } } @@ -113,32 +102,34 @@ public class UdpManager IPEndPoint ipep = e.Ipep; //解码 byte[] msg = AlarmEncode.DecodeMessage(e.Datagram); - if (msg[2] != AlarmEncode.Head[0] && msg[3] != AlarmEncode.Head[1]) return; - //Console.WriteLine("Receive protocol:" + msg[4]); + bool vaild = msg.Length >= 8 && msg[2] == AlarmEncode.Head[0] && msg[3] == AlarmEncode.Head[1]; + if (!vaild) return; + Console.WriteLine("Receive from {0}:{1} => {2}", ipep.Address.ToString(), ipep.Port, DataMessage.ToHexString(msg)); //解析 - switch (msg[4]) + DeviceCmd deviceCmd = (DeviceCmd)msg[4]; + switch (deviceCmd) { - case (byte)DeviceCmd.HeartBeatCmd://心跳信息 + case DeviceCmd.HeartBeatCmd://心跳信息 AnalysisHeartMessage(ipep, msg); break; - case (byte)DeviceCmd.AlarmCmd://报警信息 + case DeviceCmd.AlarmCmd://报警信息 AnalysisAlarmMessage(ipep, msg); break; - case (byte)DeviceCmd.AllSectorStateCmd://防区信息 + case DeviceCmd.AllSectorStateCmd://防区信息 AnalysisAllSectorMessage(ipep, msg); break; - case (byte)DeviceCmd.RtSectorStateCmd://张力防区信息 + case DeviceCmd.RtSectorStateCmd://张力防区信息 AnalysisSectorMessage(ipep, msg); break; - case (byte)DeviceCmd.MaxSectorTotalCmd://最大防区信息 + case DeviceCmd.MaxSectorTotalCmd://最大防区信息 AnalysisMaxSectorMessage(ipep, msg); break; - case (byte)DeviceCmd.BackSettingsCmd://返回报警主机设置参数回服务器,无需解析 + case DeviceCmd.BackSettingsCmd://返回报警主机设置参数回服务器,无需解析 break; default: @@ -170,11 +161,7 @@ public class UdpManager AddDevice(deviceId, device); } byte defenceState = msg[17]; - if (device.DefenceState != defenceState && OnUdpAlarmDeviceState != null) - { - OnUdpAlarmDeviceState?.Invoke(device.DeviceId, defenceState); - } - device.DefenceState = msg[17]; + ProcessDeviceStateEvent(ref device, 1, defenceState); device.WorkState = msg[18]; //设备状态1 device.CellState = GetBit(msg[19], 0); @@ -200,11 +187,6 @@ public class UdpManager device.SectorTotal = msg[25]; //在线状态 device.KeepLive = Config.DeviceHeartKeep; - if (device.OnlineState == 0) - { - device.OnlineState = 1; - OnUdpAlarmDeviceState?.Invoke(device.DeviceId, device.OnlineState); - } } private void AnalysisAlarmMessage(IPEndPoint ipep, byte[] msg) @@ -268,21 +250,18 @@ public class UdpManager int sectorNum = msg[19], startIndex = msg[20]; for (int i = 0; i < sectorNum; i++) { - int index = i + startIndex;//防区序号 + int sectorId = i + startIndex;//防区序号 int pos = 21 + i;//防区信息所在byte数组未知 - SectorState sector = new(index, msg[pos]); - if (device.SectorDict.ContainsKey(sector.Id)) + SectorState curSector = new(device.DeviceId, sectorId, msg[pos]); + if (device.SectorDict.TryGetValue(sectorId, out SectorState? sector)) { - if (device.SectorDict[sector.Id].State != sector.State) - { - device.SectorDict[sector.Id] = sector; - ReportSectorState(deviceId, sector.Id, sector.State); - } + ProcessSectorStateEvent(ref sector, curSector.State); } else { + sector = curSector; device.SectorDict[sector.Id] = sector; - ReportSectorState(deviceId, sector.Id, sector.State); + //ProcessSectorStateEvent(ref sector); } } } @@ -329,14 +308,44 @@ public class UdpManager device.SectorTotal = msg[17] * 256 + msg[18]; } - private void ReportAlarm(UdpAlarmHostMessage msg) + private void ProcessDeviceStateEvent(ref UdpAlarmHost device, int onlineState, int defenceState) { - OnUdpAlarm?.Invoke(msg); + bool reportFlag = false; + if (device.OnlineState != onlineState) + { + reportFlag = true; + device.OnlineState = onlineState; + } + if (device.DefenceState != defenceState) + { + reportFlag = true; + device.DefenceState = defenceState; + } + if (reportFlag) ReportDeviceState(device); + } + + private void ProcessSectorStateEvent(ref SectorState sector, int state) + { + if (sector.State != state) + { + sector.State = state; + ReportSectorState(sector); + } + } + + private void ReportDeviceState(UdpAlarmHost device) + { + OnFenceUdpDeviceState?.Invoke(device); } - private void ReportSectorState(int deviceId, int sectorId, int state) + private void ReportSectorState(SectorState sector) + { + OnFenceUdpSectorState?.Invoke(sector); + } + + private void ReportAlarm(UdpAlarmHostMessage msg) { - OnUdpAlarmSectorState?.Invoke(deviceId, sectorId, state); + OnFenceUdpAlarm?.Invoke(msg); } #endregion Analysis @@ -592,17 +601,17 @@ public class UdpManager #region DeviceDict - private bool ContainsDevice(int deviceId) + public bool ContainsDevice(int deviceId) { return DeviceDict.ContainsKey(deviceId); } - private UdpAlarmHost GetDevice(int deviceId) + public UdpAlarmHost GetDevice(int deviceId) { return DeviceDict[deviceId]; } - private bool TryGetDevice(int deviceId, out UdpAlarmHost device) + public bool TryGetDevice(int deviceId, out UdpAlarmHost device) { return DeviceDict.TryGetValue(deviceId, out device); } @@ -624,7 +633,7 @@ public class UdpManager return DeviceDict.Remove(deviceId, out _); } - private List GetDeviceList() + public List GetDeviceList() { return DeviceDict.Values.ToList(); } diff --git a/JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs b/JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs index 5f64209..0d14389 100644 --- a/JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs +++ b/JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using JiLinApp.Docking.VibrateAlarm; +using System.ComponentModel; using System.Net; using System.Net.Sockets; @@ -86,7 +87,6 @@ public class UdpServer private void RaiseDatagramReceived(IPEndPoint ipep, byte[] datagram) { DatagramReceived?.Invoke(this, new UdpDatagramReceivedEventArgs(ipep, datagram)); - //DatagramReceived?.Invoke(ipep, datagram); } #endregion Events @@ -113,11 +113,12 @@ public class UdpServer #region Send - public bool SendMessage(string ip, int port, byte[] byteMsg) + public bool SendMessage(string ip, int port, byte[] msg) { IPEndPoint ipep = new(IPAddress.Parse(ip), port); - int result = SendUdp.Send(byteMsg, byteMsg.Length, ipep); - bool flag = result >= byteMsg.Length; + int result = SendUdp.Send(msg, msg.Length, ipep); + bool flag = result >= msg.Length; + Console.WriteLine("Send to {0}:{1} => {2}, {3}", ip, port, DataMessage.ToHexString(msg), flag); return flag; } diff --git a/JiLinApp.Docking/Ptz/PtzCmd.cs b/JiLinApp.Docking/Ptz/PtzCmd.cs index 0c7e366..c4bf47d 100644 --- a/JiLinApp.Docking/Ptz/PtzCmd.cs +++ b/JiLinApp.Docking/Ptz/PtzCmd.cs @@ -10,7 +10,7 @@ public class PtzCmd { "PelcoD" => PtzControlType.PelcoD, "PelcoP" => PtzControlType.PelcoP, - "DCamera" => PtzControlType.PelcoP, + "DCamera" => PtzControlType.DCamera, "CameraSdk" => PtzControlType.CameraSdk, _ => PtzControlType.None }; @@ -20,17 +20,22 @@ public class PtzCmd { return cmdStr switch { - "Top" => PtzCmdType.Top, - "Down" => PtzCmdType.Down, "Left" => PtzCmdType.Left, "Right" => PtzCmdType.Right, - "TopLeft" => PtzCmdType.LeftTop, - "TopRight" => PtzCmdType.RightTop, - "DownLeft" => PtzCmdType.LeftDown, - "DownRight" => PtzCmdType.RightDown, + "Top" => PtzCmdType.Top, + "Down" => PtzCmdType.Down, + "LeftTop" => PtzCmdType.LeftTop, + "LeftDown" => PtzCmdType.LeftDown, + "RightTop" => PtzCmdType.RightTop, + "RightDown" => PtzCmdType.RightDown, "Stop" => PtzCmdType.Stop, - "AutoStart" => PtzCmdType.AutoStart, - "AutoStop" => PtzCmdType.AutoStop, + "AutoMove" => PtzCmdType.AutoMove, + "ZoomIn" => PtzCmdType.ZoomIn, + "ZoomOut" => PtzCmdType.ZoomOut, + "FocusNear" => PtzCmdType.FocusNear, + "FocusFar" => PtzCmdType.FocusFar, + "IrisOpen" => PtzCmdType.IrisOpen, + "IrisClose" => PtzCmdType.IrisClose, "PresetSet" => PtzCmdType.PresetSet, "PresetClear" => PtzCmdType.PresetClear, "PresetGoto" => PtzCmdType.PresetGoto, @@ -78,8 +83,8 @@ public class PtzComCmd PtzCmdType.RightTop => PelcoD.CameraPan(addr, PelcoD.Pan.RightUp, panSpeed), PtzCmdType.RightDown => PelcoD.CameraPan(addr, PelcoD.Pan.RightDown, panSpeed), PtzCmdType.Stop => PelcoD.CameraStop(addr), - PtzCmdType.AutoStart => PelcoD.CameraScan(addr, PelcoD.Scan.Auto), - PtzCmdType.AutoStop => PelcoD.CameraScan(addr, PelcoD.Scan.Manual), + PtzCmdType.AutoMove => PelcoD.CameraScan(addr, PelcoD.Scan.Auto), + //PtzCmdType.AutoStop => PelcoD.CameraScan(addr, PelcoD.Scan.Manual), PtzCmdType.PresetGoto => PelcoD.Preset(addr, PelcoD.PresetAction.Goto, (byte)args[1]), _ => Array.Empty(), }; @@ -102,8 +107,8 @@ public class PtzComCmd PtzCmdType.RightTop => PelcoP.CameraPanTilt(addr, PelcoP.Pan.Right, panSpeed, PelcoP.Tilt.Up, tiltSpeed), PtzCmdType.RightDown => PelcoP.CameraPanTilt(addr, PelcoP.Pan.Right, panSpeed, PelcoP.Tilt.Down, tiltSpeed), PtzCmdType.Stop => PelcoP.CameraStop(addr), - PtzCmdType.AutoStart => PelcoP.AutoScan(addr, PelcoP.Action.Start), - PtzCmdType.AutoStop => PelcoP.AutoScan(addr, PelcoP.Action.Stop), + PtzCmdType.AutoMove => PelcoP.AutoScan(addr, PelcoP.Action.Start), + //PtzCmdType.AutoStop => PelcoP.AutoScan(addr, PelcoP.Action.Stop), PtzCmdType.PresetGoto => PelcoP.Preset(addr, PelcoP.PresetAction.Goto, (byte)args[1]), _ => Array.Empty(), }; @@ -124,7 +129,6 @@ public class PtzComCmd PtzCmdType.RightTop => DCamera.RightUp(speed, speed), PtzCmdType.RightDown => DCamera.RightDown(speed, speed), PtzCmdType.Stop => DCamera.Stop(), - //PtzCmdType.PresetGoto => DCamera.Up(speed), _ => Array.Empty(), }; return cmd; @@ -135,7 +139,7 @@ public class PtzCameraCmd { public static void PtzMove(ICameraSDK sdk, PtzCmdType cmdType, int[] args) { - if (sdk == null || args == null) return; + if (sdk == null || !sdk.ConnectSuccess() || args == null) return; switch (sdk.CameraInfo.GetManufactor) { case CameraManufactor.HiK: @@ -193,10 +197,34 @@ public class PtzCameraCmd sdk.PtzMove(HiKOriSDK.DOWN_RIGHT, stop, speed); break; - case PtzCmdType.AutoStart: + case PtzCmdType.AutoMove: sdk.PtzMove(HiKOriSDK.PAN_AUTO, stop, speed); break; + case PtzCmdType.ZoomIn: + sdk.PtzMove(HiKOriSDK.ZOOM_IN, stop, speed); + break; + + case PtzCmdType.ZoomOut: + sdk.PtzMove(HiKOriSDK.ZOOM_OUT, stop, speed); + break; + + case PtzCmdType.FocusNear: + sdk.PtzMove(HiKOriSDK.FOCUS_NEAR, stop, speed); + break; + + case PtzCmdType.FocusFar: + sdk.PtzMove(HiKOriSDK.FOCUS_FAR, stop, speed); + break; + + case PtzCmdType.IrisOpen: + sdk.PtzMove(HiKOriSDK.IRIS_OPEN, stop, speed); + break; + + case PtzCmdType.IrisClose: + sdk.PtzMove(HiKOriSDK.IRIS_CLOSE, stop, speed); + break; + case PtzCmdType.PresetGoto: sdk.PtzPreset(HiKOriSDK.GOTO_PRESET, presetId); break; @@ -213,19 +241,19 @@ public class PtzCameraCmd switch (cmdType) { case PtzCmdType.Left: - sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.LEFT_CONTROL, stop, speed); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.LEFT, stop, speed); break; case PtzCmdType.Right: - sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHT_CONTROL, stop, speed); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHT, stop, speed); break; case PtzCmdType.Top: - sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.UP_CONTROL, stop, speed); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.UP, stop, speed); break; case PtzCmdType.Down: - sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.DOWN_CONTROL, stop, speed); + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.DOWN, stop, speed); break; case PtzCmdType.LeftTop: @@ -244,8 +272,32 @@ public class PtzCameraCmd sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.RIGHTDOWN, stop, speed); break; - case PtzCmdType.AutoStart: - sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.HORSECTORSCAN, stop, speed); + case PtzCmdType.AutoMove: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.STARTPANCRUISE, stop, speed); + break; + + case PtzCmdType.ZoomIn: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.ZOOM_ADD, stop, speed); + break; + + case PtzCmdType.ZoomOut: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.ZOOM_DEC, stop, speed); + break; + + case PtzCmdType.FocusNear: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.FOCUS_ADD, stop, speed); + break; + + case PtzCmdType.FocusFar: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.FOCUS_DEC, stop, speed); + break; + + case PtzCmdType.IrisOpen: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.APERTURE_ADD, stop, speed); + break; + + case PtzCmdType.IrisClose: + sdk.PtzMove((int)DaHuaOriSDK.EM_EXTPTZ_ControlType.APERTURE_DEC, stop, speed); break; case PtzCmdType.PresetGoto: @@ -295,6 +347,30 @@ public class PtzCameraCmd sdk.PtzMove(YuShiOriSDK.RIGHTDOWN, stop, speed); break; + case PtzCmdType.ZoomIn: + sdk.PtzMove(YuShiOriSDK.ZOOMTELE, stop, speed); + break; + + case PtzCmdType.ZoomOut: + sdk.PtzMove(YuShiOriSDK.ZOOMWIDE, stop, speed); + break; + + case PtzCmdType.FocusNear: + sdk.PtzMove(YuShiOriSDK.FOCUSNEAR, stop, speed); + break; + + case PtzCmdType.FocusFar: + sdk.PtzMove(YuShiOriSDK.FOCUSFAR, stop, speed); + break; + + case PtzCmdType.IrisOpen: + sdk.PtzMove(YuShiOriSDK.IRISOPEN, stop, speed); + break; + + case PtzCmdType.IrisClose: + sdk.PtzMove(YuShiOriSDK.IRISCLOSE, stop, speed); + break; + case PtzCmdType.PresetGoto: sdk.PtzPreset(YuShiOriSDK.PRESET_GOTO, presetId); break; @@ -316,17 +392,22 @@ public enum PtzControlType public enum PtzCmdType { - Top, - Down, Left, Right, + Top, + Down, LeftTop, LeftDown, RightTop, RightDown, Stop, - AutoStart, - AutoStop, + AutoMove, + ZoomIn, + ZoomOut, + FocusNear, + FocusFar, + IrisOpen, + IrisClose, PresetSet, PresetClear, PresetGoto, diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs b/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs index 152c1c1..69b6801 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections.Concurrent; using System.Net.Sockets; namespace JiLinApp.Docking.VibrateAlarm; @@ -11,22 +11,6 @@ public class ClientMessage public TcpAlarmHost Host { get; set; } - public List DataList { get; } = new(); - - public Hashtable SectionTable { get; } = new(); - - public List SensorList { get; set; } - - public bool SensorListEmpty - { - get - { - return SensorList == null || SensorList.Count == 0; - } - } - - public ReaderWriterLockSlim SensorListLock { get; } = new(); - public string Ip { get @@ -47,6 +31,30 @@ public class ClientMessage } } + public int OnlineState { get; set; }//设备在线状态 + + public int SensorTotal + { + get + { + return SensorDict.Count; + } + } + + public ConcurrentDictionary SensorDict { get; } = new(); + + public bool SensorsEmpty + { + get + { + return SensorDict == null || SensorDict.IsEmpty; + } + } + + public ReaderWriterLockSlim SensorsLock { get; } = new(); + + public List DataList { get; } = new(); + #endregion Fields public ClientMessage() diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs b/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs index 1057dcd..7ea4aa5 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/SensorState.cs @@ -2,16 +2,27 @@ public class SensorState { - public int deviceID { get; set; } + public int DeviceId { get; set; } - public string channel { get; set; } - public int online { get; set; } + public int Addr { get; set; } - public string onLine_str + public int OfflineState { get; set; } + + public int OnlineState + { + get + { + if (OfflineState == 0) return 1; + else if (OfflineState == 1) return 0; + else return 0; + } + } + + public string OnlineStateStr { get { - if (online == 0) + if (OfflineState == 0) { return "在线"; } @@ -22,13 +33,13 @@ public class SensorState } } - public int alarm { get; set; } + public int AlarmState { get; set; } - public string alarm_str + public string AlarmStateStr { get { - if (alarm == 0) + if (AlarmState == 0) { return "消警"; } @@ -39,19 +50,19 @@ public class SensorState } } - public SensorState(int id, int chan, int state) + public SensorState(int deviceId, int sensorAddr, int state) { - deviceID = id; - channel = chan.ToString(); - online = state % 2; - alarm = state / 2 % 2; + DeviceId = deviceId; + Addr = sensorAddr; + OfflineState = state % 2; + AlarmState = state / 2 % 2; } - public SensorState(int id, int chan, int on, int a) + public SensorState(int deviceId, int sensorAddr, int offlineState, int alarmState) { - deviceID = id; - channel = chan.ToString(); - online = on; - alarm = a; + DeviceId = deviceId; + Addr = sensorAddr; + OfflineState = offlineState; + AlarmState = alarmState; } } \ No newline at end of file diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs index a948ee0..9536cec 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs @@ -4,7 +4,13 @@ public class TcpAlarmHost { public int Id { get; set; } - public string Name { get; set; } + public string Name + { + get + { + return "设备" + Id; + } + } public string Ip { get; set; } diff --git a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs index f704ddc..ccfe099 100644 --- a/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs +++ b/JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs @@ -4,7 +4,6 @@ namespace JiLinApp.Docking.VibrateAlarm; public class TcpAlarmHostMessage { - public int Id { get; set; } public string AlarmTime { get; set; }//报警时间 public string CID { get; set; }//CID代码 diff --git a/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs b/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs index 4c19364..92490ba 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs @@ -199,7 +199,7 @@ public class AsyncTcpServer : IDisposable } catch (Exception) { - throw; + return; } if (listener == null || client == null || !client.Connected) return; diff --git a/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs b/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs index 5ae332e..36d484b 100644 --- a/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs +++ b/JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs @@ -14,7 +14,7 @@ public class TcpManager private TcpManagerConfig Config { get; set; } - private ConcurrentDictionary ClientMessageDict { get; } = new(); + private ConcurrentDictionary DeviceDict { get; } = new(); private Timer HeartTimer { get; } = new(); @@ -22,21 +22,17 @@ public class TcpManager #region Event - public delegate void TcpDeviceMessageEvent(TcpAlarmHost host, string msg); + public delegate void VibrateTcpDeviceStateEvent(ClientMessage device); - public delegate void TcpSensorMessageEvent(TcpAlarmHost host, TcpSensorTable section, string msg); + public delegate void VibrateTcpSensorStateEvent(SensorState sensor); - public delegate void TcpSensorStateChangeEvent(SensorState state); + public delegate void VibrateTcpAlarmEvent(TcpAlarmHostMessage msg); - public delegate void TcpSensorAlarmEvent(TcpAlarmHostMessage msg); + public event VibrateTcpDeviceStateEvent? OnVibrateTcpDeviceState; - public event TcpDeviceMessageEvent? OnTcpDeviceMessage; + public event VibrateTcpSensorStateEvent? OnVibrateTcpSensorState; - public event TcpSensorMessageEvent? OnTcpSensorMessage; - - public event TcpSensorStateChangeEvent? OnTcpSensorStateChange; - - public event TcpSensorAlarmEvent? OnTcpSensorAlarm; + public event VibrateTcpAlarmEvent? OnVibrateTcpAlarm; #endregion Event @@ -51,18 +47,12 @@ public class TcpManager public void Start(TcpManagerConfig config) { if (IsRunning()) return; - try - { - Server = new(IPAddress.Any, config.ServerPort); - Server.ClientConnected += Server_ClientConnected; - Server.ClientDisconnected += Server_ClientDisconnected; - Server.DatagramReceived += Server_DatagramReceived; - Server.Start(); - } - catch (Exception) - { - return; - } + Server = new(IPAddress.Any, 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; @@ -84,7 +74,7 @@ public class TcpManager Server.ClientDisconnected -= Server_ClientDisconnected; Server.DatagramReceived -= Server_DatagramReceived; Server = null; - ClientMessageDict.Clear(); + DeviceDict.Clear(); HeartTimer.Stop(); HeartTimer.Elapsed -= HeartTimer_Elapsed; } @@ -101,20 +91,12 @@ public class TcpManager private void HeartTimer_Elapsed(object? sender, ElapsedEventArgs e) { - foreach (var clientMsg in ClientMessageDict.Values) + foreach (var clientMsg in DeviceDict.Values) { SendHostHeart_01(clientMsg); } } - private void StateSpanTimer_Elapsed(object? sender, ElapsedEventArgs e) - { - foreach (var clientMsg in ClientMessageDict.Values) - { - RequestSensorState_04(clientMsg); - } - } - private void Server_ClientConnected(object? sender, TcpClientConnectedEventArgs e) { string clientKey = e.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; @@ -122,19 +104,18 @@ public class TcpManager string clientIp = clientKey.Split(':')[0]; string clientPort = clientKey.Split(':')[1]; Console.WriteLine("上线:{0}", clientIp); - if (!TryGetClientMessage(clientIp, out ClientMessage clientMsg)) + if (!TryGetDevice(clientIp, out ClientMessage clientMsg)) { clientMsg = new() { Client = e.TcpClient, - Host = new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" } + Host = new() { Id = -1, Ip = clientIp, Port = clientPort } }; - AddClientMessage(clientIp, clientMsg); + AddDeivce(clientIp, clientMsg); } - if (OnTcpDeviceMessage != null) + else { - TcpAlarmHost host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; - OnTcpDeviceMessage(host, "报警主机上线"); + ProcessDeviceStateEvent(ref clientMsg, 1); } } @@ -145,14 +126,9 @@ public class TcpManager string clientIp = clientKey.Split(':')[0]; string clientPort = clientKey.Split(':')[1]; Console.WriteLine("下线:{0}", clientIp); - if (TryGetClientMessage(clientIp, out ClientMessage clientMsg)) + if (TryGetDevice(clientIp, out ClientMessage clientMsg)) { - RemoveClientMessage(clientIp); - if (OnTcpDeviceMessage != null) - { - TcpAlarmHost host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; - OnTcpDeviceMessage(host, "报警主机下线"); - } + ProcessDeviceStateEvent(ref clientMsg, 0); } } @@ -161,61 +137,60 @@ public class TcpManager string clientKey = e.TcpClient.TcpClient.Client.RemoteEndPoint?.ToString() ?? ""; if (clientKey == "") return; string clientIp = clientKey.Split(':')[0]; - if (TryGetClientMessage(clientIp, out ClientMessage clientMsg)) + if (TryGetDevice(clientIp, out ClientMessage clientMsg)) { clientMsg.AddData(e.Datagram); - AnalysisClientMessage(clientMsg); + AnalysisClientMessage(ref clientMsg); } } #endregion Events - #region Analysis + #region Analysisbo - private void AnalysisClientMessage(ClientMessage clientMsg) + private void AnalysisClientMessage(ref ClientMessage clientMsg) { - //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++) { + byte[] msg = msglist[i]; + bool vaild = msg.Length >= 19 && msg[0] == 0xAA && msg[1] == 0xAA; + if (!vaild) continue; 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)); - TcpAlarmHost host; switch (mm.FunctionNum) { 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); + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString() }; + UpdateDevice(clientMsg.Ip, clientMsg.Host); + ProcessDeviceStateEvent(ref clientMsg, 1); } ResponseHostLogin_10(clientMsg, mm); - if (clientMsg.SensorListEmpty && clientMsg.SensorListLock.TryEnterWriteLock(1000)) + ClientMessage clientMsg2 = clientMsg; + if (clientMsg2.SensorsEmpty && clientMsg2.SensorsLock.TryEnterWriteLock(1000)) { Task.Run(() => { - while (clientMsg.SensorListEmpty) + while (clientMsg2.SensorsEmpty) { - RequestSensorList_07(clientMsg); + RequestSensorList_07(clientMsg2); Thread.Sleep(1000); } - clientMsg.SensorListLock.ExitWriteLock(); + clientMsg2.SensorsLock.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); + ProcessDeviceStateEvent(ref clientMsg, 1); break; case 0x12: @@ -236,17 +211,11 @@ public class TcpManager 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); + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString() }; + UpdateDevice(clientMsg.Ip, clientMsg.Host); } - ProcessOnlineEvent(clientMsg, mm, sensorAddr, online); - ProcessAlarmEvent(clientMsg, mm, sensorAddr, alarm); - UpdateOnLineAlarm(clientMsg, sensorAddr, online, alarm); + ProcessSensorStateEvent(ref clientMsg, mm, sensorAddr, online, alarm); SetDataRequest(mm, 0x04); - if (alarm == 1) - { - RequestSensorReset_05(clientMsg); - } break; case 0x15: @@ -258,18 +227,17 @@ public class TcpManager 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); + clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString() }; + UpdateDevice(clientMsg.Ip, clientMsg.Host); } - if (clientMsg.SensorListEmpty) + if (clientMsg.SensorsEmpty) { - List sensorList = new(); for (int j = 2; j < mm.Data.Length; j++) { - sensorList.Add(Convert.ToByte((mm.Data[j] + mm.Data[++j] * 256))); + sensorAddr = Convert.ToByte((mm.Data[j] + mm.Data[++j] * 256)); + SensorState sensor = new(mm.DeviceId, sensorAddr, 0, 0); + clientMsg.SensorDict[sensorAddr] = sensor; } - clientMsg.SensorList = sensorList; - UpdateClientMessage(clientMsg.Ip, sensorList); RequestSensorState_04(clientMsg); } SetDataRequest(mm, 0x07); @@ -278,70 +246,66 @@ public class TcpManager } } - private void ProcessOnlineEvent(ClientMessage client, DataMessage mm, int channel, int online) + private void ProcessDeviceStateEvent(ref ClientMessage device, int online) { - if (client.SectionTable.ContainsKey(channel)) + if (device.OnlineState != online) { - SensorState oldState = client.SectionTable[channel] as SensorState; - if (oldState.online == online) return; + device.OnlineState = online; + ReportDeviceState(device); } - TcpAlarmHost host = client.Host; - TcpSensorTable section = new() { DeviceId = host.Id, Name = "未知传感器", Channel = channel.ToString() }; - OnTcpSensorMessage?.Invoke(host, section, online == 0 ? "传感器上线" : "传感器离线"); } - private void ProcessAlarmEvent(ClientMessage client, DataMessage mm, int channel, int alarm) + private void ProcessSensorStateEvent(ref ClientMessage client, DataMessage mm, int sensorAddr, int offline, int alarm) { - if (client.SectionTable.ContainsKey(channel)) + if (!client.SensorDict.TryGetValue(sensorAddr, out SensorState? sensor)) + { + sensor = new(mm.DeviceId, sensorAddr, offline, alarm); + client.SensorDict[sensorAddr] = sensor; + ReportSensorState(sensor); + } + else if (sensor.OfflineState != offline || sensor.AlarmState != alarm) { - SensorState oldState = client.SectionTable[channel] as SensorState; - if (oldState.alarm == alarm) return; + sensor.OfflineState = offline; + sensor.AlarmState = alarm; + ReportSensorState(sensor); } - TcpAlarmHost host = client.Host; if (alarm == 1) { - ProcessAlarm(host.Id, channel); + ReportAlarm(sensor.DeviceId, sensorAddr); + //RequestSensorReset_05(clientMsg, sensorAddr); } } - private void UpdateOnLineAlarm(ClientMessage client, int channel, int online, int alarm) + private void ReportDeviceState(ClientMessage device) { - if (client.SectionTable.ContainsKey(channel)) - { - SensorState oldState = client.SectionTable[channel] as SensorState; - oldState.online = online; - oldState.alarm = alarm; - OnTcpSensorStateChange?.Invoke(oldState); - } - else - { - TcpAlarmHost host = client.Host; - SensorState state = new(host.Id, channel, online, alarm); - client.SectionTable[channel] = state; - OnTcpSensorStateChange?.Invoke(state); - } + OnVibrateTcpDeviceState?.Invoke(device); + } + + private void ReportSensorState(SensorState sensor) + { + OnVibrateTcpSensorState?.Invoke(sensor); } - private void ProcessAlarm(int deviceId, int channel) + private void ReportAlarm(int deviceId, int sensorAddr) { TcpAlarmHostMessage alarmMsg = new() { AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), CID = "1151", DeviceID = deviceId, - SensorAddr = channel.ToString() + SensorAddr = sensorAddr.ToString() }; - OnTcpSensorAlarm?.Invoke(alarmMsg); + OnVibrateTcpAlarm?.Invoke(alarmMsg); } - #endregion Analysis + #endregion Analysisbo #region Send public bool SendMessage(string ip, byte[] bytes) { if (Server == null || !Server.IsRunning()) return false; - if (!TryGetClientMessage(ip, out ClientMessage clientMsg)) return false; + if (!TryGetDevice(ip, out ClientMessage clientMsg)) return false; string cmd = DataMessage.ToHexString(bytes); DataMessage mm = new(); mm.Decode(bytes); @@ -398,12 +362,12 @@ public class TcpManager public bool RequestSensorState_04(ClientMessage client) { if (client.Host == null || client.Host.Id < 0) return false; - if (client.SensorListEmpty) return false; + if (client.SensorsEmpty) return false; DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x04, 2); - foreach (var item in client.SensorList) + foreach (var item in client.SensorDict.Values) { - int channel = item; - msg.Data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; + int sensorAddr = item.Addr; + msg.Data = new byte[] { (byte)(sensorAddr % 256), (byte)(sensorAddr / 256) }; DataRequest request = new() { Request = msg @@ -413,21 +377,17 @@ public class TcpManager return true; } - public bool RequestSensorReset_05(ClientMessage client) + public bool RequestSensorReset_05(ClientMessage client, int sensorAddr) { if (client.Host == null || client.Host.Id < 0) return false; - if (client.SensorListEmpty) return false; + if (client.SensorsEmpty) return false; DataMessage msg = GetSendMessageHead(client.Host.Id, client, 0x05, 2); - foreach (var item in client.SensorList) + msg.Data = new byte[] { (byte)(sensorAddr % 256), (byte)(sensorAddr / 256) }; + DataRequest request = new() { - int channel = item; - msg.Data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) }; - DataRequest request = new() - { - Request = msg - }; - SendRequest(ref request); - } + Request = msg + }; + SendRequest(ref request); return true; } @@ -454,50 +414,62 @@ public class TcpManager #region ClientMessage - private bool ContainsClientMessage(string clientIp) + public bool ContainsDevice(string clientIp) + { + return DeviceDict.ContainsKey(clientIp); + } + + public ClientMessage GetDevice(string clientIp) { - return ClientMessageDict.ContainsKey(clientIp); + return DeviceDict[clientIp]; } - private ClientMessage GetClientMessage(string clientIp) + public bool TryGetDevice(string clientIp, out ClientMessage clientMsg) { - return ClientMessageDict[clientIp]; + return DeviceDict.TryGetValue(clientIp, out clientMsg); } - private bool TryGetClientMessage(string clientIp, out ClientMessage clientMsg) + public bool TryGetDevice(int deviceId, out ClientMessage clientMsg) { - return ClientMessageDict.TryGetValue(clientIp, out clientMsg); + foreach (var item in DeviceDict.Values) + { + if (item.Host.Id == deviceId) + { + clientMsg = item; + return true; + } + } + clientMsg = null; + return false; } - private bool AddClientMessage(string clientIp, ClientMessage clientMsg) + private bool AddDeivce(string clientIp, ClientMessage clientMsg) { - if (ContainsClientMessage(clientIp)) return false; - ClientMessageDict[clientIp] = clientMsg; + if (ContainsDevice(clientIp)) return false; + DeviceDict[clientIp] = clientMsg; return true; } - private void SetClientMessage(string clientIp, ClientMessage clientMsg) + private void SetDevice(string clientIp, ClientMessage clientMsg) { - ClientMessageDict[clientIp] = clientMsg; + DeviceDict[clientIp] = clientMsg; } - private bool RemoveClientMessage(string clientIp) + private bool RemoveDevice(string clientIp) { - return ClientMessageDict.Remove(clientIp, out _); + return DeviceDict.Remove(clientIp, out _); } - private bool UpdateClientMessage(string clientIp, TcpAlarmHost host) + private bool UpdateDevice(string clientIp, TcpAlarmHost host) { - if (!ClientMessageDict.ContainsKey(clientIp)) return false; - ClientMessageDict[clientIp].Host = host; + if (!DeviceDict.ContainsKey(clientIp)) return false; + DeviceDict[clientIp].Host = host; return true; } - private bool UpdateClientMessage(string clientIp, List sensorList) + public List GetDeviceList() { - if (!ClientMessageDict.ContainsKey(clientIp)) return false; - ClientMessageDict[clientIp].SensorList = sensorList; - return true; + return DeviceDict.Values.ToList(); } #endregion ClientMessage diff --git a/JiLinApp.Docking/config/alarmcode.json b/JiLinApp.Docking/config/alarmcode.json index 7b30c3c..53c3382 100644 --- a/JiLinApp.Docking/config/alarmcode.json +++ b/JiLinApp.Docking/config/alarmcode.json @@ -219,18 +219,24 @@ "Id": "1151", "Level": "1", "Type": "警报", - "Content": "挖掘报警" + "Content": "震动报警" }, { "Id": "1152", "Level": "1", "Type": "警报", - "Content": "步行报警" + "Content": "挖掘报警" }, { "Id": "1153", "Level": "1", "Type": "警报", + "Content": "步行报警" + }, + { + "Id": "1154", + "Level": "1", + "Type": "警报", "Content": "行车报警" }, { diff --git a/JiLinApp/Components/CameraRealPlay.xaml b/JiLinApp/Components/CameraRealPlay.xaml index 43602e7..888dba7 100644 --- a/JiLinApp/Components/CameraRealPlay.xaml +++ b/JiLinApp/Components/CameraRealPlay.xaml @@ -1,10 +1,131 @@  - - + Title="RealPlay" ShowInTaskbar="False" Width="769" Height="397"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/JiLinApp/Components/CameraRealPlay.xaml.cs b/JiLinApp/Components/CameraRealPlay.xaml.cs index 7ded6a4..8f8a982 100644 --- a/JiLinApp/Components/CameraRealPlay.xaml.cs +++ b/JiLinApp/Components/CameraRealPlay.xaml.cs @@ -1,7 +1,11 @@ using EC.Util.CameraSDK; +using JiLinApp.Docking.Ptz; using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; using System.Windows.Interop; namespace JiLinApp.Components; @@ -21,14 +25,30 @@ public partial class CameraRealPlay : Window { InitializeComponent(); CameraSdk = cameraSdk; + Init(); } + #region Init + + private void Init() + { + // 绑定云台响应事件 + List