diff --git a/EC.Util/CameraSDK/DaHua/DaHuaOriSdk.cs b/EC.Util/CameraSDK/DaHua/DaHuaOriSdk.cs
index 6bedde1..0245c9e 100644
--- a/EC.Util/CameraSDK/DaHua/DaHuaOriSdk.cs
+++ b/EC.Util/CameraSDK/DaHua/DaHuaOriSdk.cs
@@ -39,7 +39,7 @@ public static class DaHuaOriSdk
if (InitSuccess) return true;
bool ret = CLIENT_InitEx(null, IntPtr.Zero, IntPtr.Zero);
InitSuccess = ret;
- if (!ret) throw new Exception("DaHuaOriSDK global init failure.");
+ if (!ret) throw new Exception("DaHuaOriSdk global init failure.");
return ret;
}
diff --git a/EC.Util/CameraSDK/HiK/HiKSdk.cs b/EC.Util/CameraSDK/HiK/HiKSdk.cs
index a6acd39..6f50986 100644
--- a/EC.Util/CameraSDK/HiK/HiKSdk.cs
+++ b/EC.Util/CameraSDK/HiK/HiKSdk.cs
@@ -39,8 +39,8 @@ public class HiKSdk : ICameraSdk
ret = ConnectSuccess();
if (ret) HiKOriSdk.NET_DVR_SetReconnect(10000, 1);
else BuildException();
- //HiKOriSDK.NET_DVR_DEVICEINFO_V30 deviceInfo = new();
- //LoginId = HiKOriSDK.NET_DVR_Login_V30(CameraInfo.Ip, CameraInfo.Port, CameraInfo.UserName, CameraInfo.Password, ref deviceInfo);
+ //HiKOriSdk.NET_DVR_DEVICEINFO_V30 deviceInfo = new();
+ //LoginId = HiKOriSdk.NET_DVR_Login_V30(CameraInfo.Ip, CameraInfo.Port, CameraInfo.UserName, CameraInfo.Password, ref deviceInfo);
return ret;
}
diff --git a/EC.Util/CameraSDK/YuShi/YuShiOriSdk.cs b/EC.Util/CameraSDK/YuShi/YuShiOriSdk.cs
index ea9bbcf..b784210 100644
--- a/EC.Util/CameraSDK/YuShi/YuShiOriSdk.cs
+++ b/EC.Util/CameraSDK/YuShi/YuShiOriSdk.cs
@@ -39,7 +39,7 @@ public class YuShiOriSdk
if (InitSuccess) return true;
bool ret = NETDEV_Init();
InitSuccess = ret;
- if (!ret) throw new Exception("YuShiOriSDK global init failure.");
+ if (!ret) throw new Exception("YuShiOriSdk global init failure.");
return ret;
}
diff --git a/EC.Util/CameraSDK/YuShi/YuShiSdk.cs b/EC.Util/CameraSDK/YuShi/YuShiSdk.cs
index eb7d3d1..c14fc89 100644
--- a/EC.Util/CameraSDK/YuShi/YuShiSdk.cs
+++ b/EC.Util/CameraSDK/YuShi/YuShiSdk.cs
@@ -111,9 +111,9 @@ public class YuShiSdk : ICameraSdk
{
hPlayWnd = hwnd,
dwChannelID = Channel,
- dwStreamType = 0, // YuShiOriSDK.NETDEV_LIVE_STREAM_INDEX_E
- dwLinkMode = 1, // YuShiOriSDK.NETDEV_PROTOCAL_E
- dwFluency = 0, // YuShiOriSDK.NETDEV_PICTURE_FLUENCY_E
+ 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();
diff --git a/JiLinApp.Biz/JiLinApp.Biz.csproj b/JiLinApp.Biz/JiLinApp.Biz.csproj
new file mode 100644
index 0000000..d655145
--- /dev/null
+++ b/JiLinApp.Biz/JiLinApp.Biz.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/JiLinApp.Biz/TransmitAlarm/Common/AlarmServiceFactory.cs b/JiLinApp.Biz/TransmitAlarm/Common/AlarmServiceFactory.cs
new file mode 100644
index 0000000..37fdfb1
--- /dev/null
+++ b/JiLinApp.Biz/TransmitAlarm/Common/AlarmServiceFactory.cs
@@ -0,0 +1,14 @@
+namespace JiLinApp.Biz.TransmitAlarm;
+
+public class AlarmServiceFactory
+{
+ public static IAlarmService CreateService(AlarmPlatformConfig config)
+ {
+ IAlarmService service = (config.Type) switch
+ {
+ "mqtt" => new AlarmMqttService(config.Mqtt),
+ _ => throw new NotSupportedException(),
+ }; ;
+ return service;
+ }
+}
\ No newline at end of file
diff --git a/JiLinApp.Biz/TransmitAlarm/Common/Config.cs b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs
new file mode 100644
index 0000000..49e0095
--- /dev/null
+++ b/JiLinApp.Biz/TransmitAlarm/Common/Config.cs
@@ -0,0 +1,48 @@
+namespace JiLinApp.Biz.TransmitAlarm;
+
+public class AlarmPlatformConfig
+{
+ public bool RealPlay { get; set; }
+
+ public string Type { get; set; }
+
+ public MqttConfig Mqtt { get; set; }
+}
+
+public class MqttConfig
+{
+ //public bool Local { get; set; }
+
+ public string Ip { get; set; }
+
+ public int Port { get; set; }
+
+ public string UserName { get; set; }
+
+ public string Password { get; set; }
+
+ public string ClientId { get; set; }
+
+ public int RetryTime { get; set; }
+
+ public int RetryInterval { get; set; }
+
+ public string PubAlarmTopic { 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
+{
+ public string AlarmPubAddr { get; set; }
+
+ public string AlarmPubTopic { get; set; }
+}
\ No newline at end of file
diff --git a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs
new file mode 100644
index 0000000..dc32f16
--- /dev/null
+++ b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs
@@ -0,0 +1,34 @@
+namespace JiLinApp.Biz.TransmitAlarm;
+
+public class AlarmMessage
+{
+ /** (必填)传感器设备编码*/
+ public string LabelCode { get; set; }
+ public string ChannelId { get; set; }
+ /** (必填)报警类型((1-视频报警,2-雷达报警;3-微振动警报,4-电子围网警报,9-其他报警))*/
+ public int WarnType { get; set; }
+ /** (必填)报警级别(1-5)*/
+ public int WarnLevel { get; set; }
+ /** (必填)报警内容*/
+ public string WarnContent { get; set; }
+ /** 处置方式*/
+ public int DealWay { get; set; }
+ /** (必填)处置状态(1-未处理,2-已处理)*/
+ public int DealStatus { get; set; }
+ /** (必填)发生地点*/
+ public string CameraLoc { get; set; }
+ /** (必填)发生时间*/
+ public DateTime CreateTime { get; set; }
+ /** 负责人*/
+ public string Director { get; set; }
+ /** (必填)类型(1-预警,2-报警,3-故障,)*/
+ public int Kind { get; set; }
+ /** 现场照片*/
+ public string ImgUrl { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format("{{ labelCode:{0}, channelId:{1}, warnType:{2}, warnLevel:{3}, warnContent:{4}, createTime:{5} }}",
+ LabelCode, ChannelId, WarnType, WarnLevel, WarnContent, CreateTime);
+ }
+}
\ No newline at end of file
diff --git a/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs
new file mode 100644
index 0000000..26ebaa1
--- /dev/null
+++ b/JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs
@@ -0,0 +1,42 @@
+using JiLinApp.Docking.Alarm;
+using JiLinApp.Docking.FenceAlarm;
+using JiLinApp.Docking.VibrateAlarm;
+
+namespace JiLinApp.Biz.TransmitAlarm;
+
+public static class AlarmMessageHelper
+{
+ public static AlarmMessage ToAlarmMessage(this TcpAlarmHostMessage msg)
+ {
+ AlarmCode code = AlarmCodeHelper.Get(msg.CID);
+ AlarmMessage obj = new()
+ {
+ LabelCode = Convert.ToString(msg.DeviceID),
+ ChannelId = msg.SensorAddr,
+ WarnType = 3,
+ WarnLevel = code.Level,
+ WarnContent = code.Content,
+ DealStatus = 1,
+ CreateTime = Convert.ToDateTime(msg.AlarmTime),
+ Kind = 2,
+ };
+ return obj;
+ }
+
+ public static AlarmMessage ToAlarmMessage(this UdpAlarmHostMessage msg)
+ {
+ AlarmCode code = AlarmCodeHelper.Get(msg.CID);
+ AlarmMessage obj = new()
+ {
+ LabelCode = Convert.ToString(msg.DeviceId),
+ ChannelId = Convert.ToString(msg.SectorId),
+ WarnType = 4,
+ WarnLevel = code.Level,
+ WarnContent = code.Content,
+ DealStatus = 1,
+ CreateTime = Convert.ToDateTime(msg.AlarmTime),
+ Kind = 2,
+ };
+ return obj;
+ }
+}
\ No newline at end of file
diff --git a/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs
new file mode 100644
index 0000000..609b5db
--- /dev/null
+++ b/JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs
@@ -0,0 +1,332 @@
+using EC.Util.Common;
+using MQTTnet;
+using MQTTnet.Client;
+using MQTTnet.Exceptions;
+using MQTTnet.Protocol;
+using MQTTnet.Server;
+using NewLife.Serialization;
+using Newtonsoft.Json.Linq;
+using System.Text;
+
+namespace JiLinApp.Biz.TransmitAlarm;
+
+public class AlarmMqttService : IAlarmService
+{
+ #region Fields
+
+ private MqttConfig Config { get; }
+
+ //private MqttServer? Server { get; }
+
+ private IMqttClient Client { get; }
+
+ //private MqttServerOptions ServerOptions { 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)
+ {
+ MqttFactory factory = new();
+
+ ClientOptions = factory.CreateClientOptionsBuilder()
+ .WithTcpServer(config.Ip, config.Port)
+ .WithClientId(config.ClientId)
+ .WithCredentials(config.UserName, config.Password)
+ .WithCleanSession(false)
+ .WithKeepAlivePeriod(TimeSpan.FromSeconds(60))
+ .Build();
+ SubscribeOptions = factory.CreateSubscribeOptionsBuilder()
+ .WithTopicFilter(f => f.WithTopic(config.SubCmdTopic))
+ .Build();
+
+ //if (config.Local)
+ //{
+ // ServerOptions = factory.CreateServerOptionsBuilder()
+ // .WithDefaultEndpoint()
+ // .WithDefaultEndpointPort(config.Port)
+ // .Build();
+ // MqttServer server = factory.CreateMqttServer(ServerOptions);
+ // server.ValidatingConnectionAsync += Server_ValidatingConnectionAsync;
+ // server.ClientConnectedAsync += Server_ClientConnectedAsync;
+ // server.ClientDisconnectedAsync += Server_ClientDisconnectedAsync;
+ // server.ClientAcknowledgedPublishPacketAsync += Server_ClientAcknowledgedPublishPacketAsync;
+ // Server = server;
+ //}
+
+ IMqttClient client = factory.CreateMqttClient();
+ client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
+
+ Config = config;
+ Client = client;
+ }
+
+ ~AlarmMqttService()
+ {
+ Close();
+ }
+
+ #region Base
+
+ public void Start()
+ {
+ if (IsRuning()) return;
+ 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()
+ {
+ if (!IsRuning()) return;
+ Client.DisconnectAsync().Wait();
+ }
+
+ public bool IsRuning()
+ {
+ return Client != null && Client.IsConnected;
+ }
+
+ private object StartAtomObj { get; } = new();
+
+ private bool StartAtom()
+ {
+ lock (StartAtomObj)
+ {
+ if (!IsRuning()) Start();
+ }
+ return IsRuning();
+ }
+
+ #endregion Base
+
+ #region Server Event
+
+ private Task Server_ValidatingConnectionAsync(ValidatingConnectionEventArgs arg)
+ {
+ if (arg.ClientId.Length == 0) arg.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
+ else if (arg.UserName != Config.UserName) arg.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
+ else if (arg.Password != Config.Password) arg.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
+ return Task.CompletedTask;
+ }
+
+ private Task Server_ClientConnectedAsync(ClientConnectedEventArgs arg)
+ {
+ return Task.CompletedTask;
+ }
+
+ private Task Server_ClientDisconnectedAsync(ClientDisconnectedEventArgs arg)
+ {
+ return Task.CompletedTask;
+ }
+
+ private Task Server_ClientAcknowledgedPublishPacketAsync(ClientAcknowledgedPublishPacketEventArgs arg)
+ {
+ string clientId = arg.ClientId;
+ ushort packetIdentifier = arg.PublishPacket.PacketIdentifier;
+ string topic = arg.PublishPacket.Topic;
+ string msg = Encoding.UTF8.GetString(arg.PublishPacket.Payload);
+ return Task.CompletedTask;
+ }
+
+ #endregion Server Event
+
+ #region Client Event
+
+ 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 Client Event
+
+ #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(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);
+ }
+ }
+ }
+ }
+
+ public void SendAlarm(AlarmMessage msg)
+ {
+ Send(Config.PubAlarmTopic, msg);
+ }
+
+ public void SendDevices(DeviceType type, List