Browse Source

2023年4月24日18:00:12

master
fajiao 1 year ago
parent
commit
174efc6a82
  1. 2
      JiLinApp.Biz/TransmitAlarm/Common/AlarmServiceFactory.cs
  2. 9
      JiLinApp.Biz/TransmitAlarm/Common/Config.cs
  3. 28
      JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs
  4. 32
      JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs
  5. 88
      JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs
  6. 5
      JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs
  7. 2
      JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs
  8. 72
      JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs
  9. 148
      JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHost.cs
  10. 172
      JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs
  11. 10
      JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs
  12. 269
      JiLinApp.Docking/FenceAlarm/Service/AlarmEncode.cs
  13. 1159
      JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs
  14. 94
      JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs
  15. 2
      JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs
  16. 2
      JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs
  17. 2
      JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs
  18. 83
      JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs
  19. 182
      JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs
  20. 4
      JiLinApp/Core/Config.cs
  21. 4
      JiLinApp/Core/Global.cs
  22. 8
      JiLinApp/Pages/FenceServerManage/Main.xaml.cs
  23. 4
      JiLinApp/Pages/FenceServerManage/MainViewModel.cs
  24. 8
      JiLinApp/Pages/PtzManage/Main.xaml.cs
  25. 4
      JiLinApp/Pages/VibrateServerManage/MainViewModel.cs
  26. 14
      JiLinApp/config/config.json

2
JiLinApp.Biz/TransmitAlarm/Common/AlarmServiceFactory.cs

@ -2,7 +2,7 @@
public class AlarmServiceFactory public class AlarmServiceFactory
{ {
public static IAlarmService CreateService(TransmitAlarmConfig config) public static IAlarmService CreateService(AlarmPlatformConfig config)
{ {
IAlarmService service = (config.Type) switch IAlarmService service = (config.Type) switch
{ {

9
JiLinApp.Biz/TransmitAlarm/Common/Config.cs

@ -1,6 +1,6 @@
namespace JiLinApp.Biz.TransmitAlarm; namespace JiLinApp.Biz.TransmitAlarm;
public class TransmitAlarmConfig public class AlarmPlatformConfig
{ {
public bool RealPlay { get; set; } public bool RealPlay { get; set; }
@ -11,6 +11,8 @@ public class TransmitAlarmConfig
public class MqttConfig public class MqttConfig
{ {
public string Ip { get; set; }
public int Port { get; set; } public int Port { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
@ -19,7 +21,10 @@ public class MqttConfig
public string ClientId { get; set; } public string ClientId { get; set; }
public string TransmitTopic { get; set; } public string PubAlarmTopic { get; set; }
public string SubTopic { get; set; }
} }
public class ZmqConfig public class ZmqConfig

28
JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessage.cs

@ -3,32 +3,32 @@
public class AlarmMessage public class AlarmMessage
{ {
/** (必填)传感器设备编码*/ /** (必填)传感器设备编码*/
public string labelCode; public string LabelCode { get; set; }
public int ChannelId { get; set; }
/** (必填)报警类型((1-视频报警,2-雷达报警;3-微振动警报,4-电子围网警报,9-其他报警))*/ /** (必填)报警类型((1-视频报警,2-雷达报警;3-微振动警报,4-电子围网警报,9-其他报警))*/
public int warnType; public int WarnType { get; set; }
/** (必填)报警级别(1-5)*/ /** (必填)报警级别(1-5)*/
public int warnLevel; public int WarnLevel { get; set; }
/** (必填)报警内容*/ /** (必填)报警内容*/
public string warnContent; public string WarnContent { get; set; }
public int ChannelNum;
/** 处置方式*/ /** 处置方式*/
public int dealWay; public int DealWay { get; set; }
/** (必填)处置状态(1-未处理,2-已处理)*/ /** (必填)处置状态(1-未处理,2-已处理)*/
public int dealStatus; public int DealStatus { get; set; }
/** (必填)发生地点*/ /** (必填)发生地点*/
public string cameraLoc; public string CameraLoc { get; set; }
/** (必填)发生时间*/ /** (必填)发生时间*/
public DateTime createTime; public DateTime CreateTime { get; set; }
/** 负责人*/ /** 负责人*/
public string director; public string Director { get; set; }
/** (必填)类型(1-预警,2-报警,3-故障,)*/ /** (必填)类型(1-预警,2-报警,3-故障,)*/
public int kind; public int Kind { get; set; }
/** 现场照片*/ /** 现场照片*/
public string imgUrl; public string ImgUrl { get; set; }
public override string ToString() public override string ToString()
{ {
return string.Format("{{ labelCode:{0}, warnType:{1}, warnLevel:{2}, warnContent:{3}, createTime:{4} }}", return string.Format("{{ labelCode:{0}, channelId:{1}, warnType:{2}, warnLevel:{3}, warnContent:{4}, createTime:{5} }}",
labelCode, warnType, warnLevel, warnContent, createTime); LabelCode, ChannelId, WarnType, WarnLevel, WarnContent, CreateTime);
} }
} }

32
JiLinApp.Biz/TransmitAlarm/Entity/AlarmMessageHelper.cs

@ -11,14 +11,14 @@ public static class AlarmMessageHelper
AlarmCode code = AlarmCodeHelper.Get(msg.CID); AlarmCode code = AlarmCodeHelper.Get(msg.CID);
AlarmMessage obj = new() AlarmMessage obj = new()
{ {
labelCode = Convert.ToString(msg.DeviceID), LabelCode = Convert.ToString(msg.DeviceID),
warnType = 3, ChannelId = Convert.ToInt32(msg.SensorAddr),
warnLevel = code.Level, WarnType = 3,
warnContent = code.Content, WarnLevel = code.Level,
ChannelNum = Convert.ToInt32(msg.ChannelNum), WarnContent = code.Content,
dealStatus = 1, DealStatus = 1,
createTime = Convert.ToDateTime(msg.AlarmTime), CreateTime = Convert.ToDateTime(msg.AlarmTime),
kind = 2, Kind = 2,
}; };
return obj; return obj;
} }
@ -28,14 +28,14 @@ public static class AlarmMessageHelper
AlarmCode code = AlarmCodeHelper.Get(msg.CID); AlarmCode code = AlarmCodeHelper.Get(msg.CID);
AlarmMessage obj = new() AlarmMessage obj = new()
{ {
labelCode = Convert.ToString(msg.DeviceID), LabelCode = Convert.ToString(msg.DeviceId),
warnType = 4, ChannelId = msg.SectorId,
warnLevel = code.Level, WarnType = 4,
warnContent = code.Content, WarnLevel = code.Level,
ChannelNum = msg.ChannelNum, WarnContent = code.Content,
dealStatus = 1, DealStatus = 1,
createTime = Convert.ToDateTime(msg.AlarmTime), CreateTime = Convert.ToDateTime(msg.AlarmTime),
kind = 2, Kind = 2,
}; };
return obj; return obj;
} }

88
JiLinApp.Biz/TransmitAlarm/Service/AlarmMqttService.cs

@ -1,8 +1,6 @@
using EC.Util.Common; using EC.Util.Common;
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
using MQTTnet.Protocol;
using MQTTnet.Server;
using System.Text; using System.Text;
namespace JiLinApp.Biz.TransmitAlarm; namespace JiLinApp.Biz.TransmitAlarm;
@ -13,28 +11,33 @@ public class AlarmMqttService : IAlarmService
private MqttConfig Config { get; } private MqttConfig Config { get; }
private MqttServer Server { get; } //private MqttServer Server { get; }
private IMqttClient Client { get; } private IMqttClient Client { get; }
private MqttClientOptions ClientOptions { get; }
private MqttClientSubscribeOptions SubscribeOptions { get; }
#endregion Fields #endregion Fields
public AlarmMqttService(MqttConfig config) public AlarmMqttService(MqttConfig config)
{ {
MqttFactory factory = new(); MqttFactory factory = new();
MqttServerOptions options = new MqttServerOptionsBuilder()
.WithDefaultEndpoint()
.WithDefaultEndpointPort(config.Port)
.Build();
MqttServer server = factory.CreateMqttServer(options);
server.ValidatingConnectionAsync += Server_ValidatingConnectionAsync;
server.ClientConnectedAsync += Server_ClientConnectedAsync;
server.ClientDisconnectedAsync += Server_ClientDisconnectedAsync;
server.ClientAcknowledgedPublishPacketAsync += Server_ClientAcknowledgedPublishPacketAsync;
IMqttClient client = factory.CreateMqttClient(); IMqttClient client = factory.CreateMqttClient();
client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
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("mqttnet/samples/topic/1"))
.Build();
Config = config; Config = config;
Server = server;
Client = client; Client = client;
} }
@ -47,43 +50,38 @@ public class AlarmMqttService : IAlarmService
public void Start() public void Start()
{ {
Server.StartAsync().Wait(); if (IsRuning()) return;
ClientConnServer(); MqttClientConnectResult connResult = Client.ConnectAsync(ClientOptions, CancellationToken.None).Result;
MqttClientSubscribeResult subResult = Client.SubscribeAsync(SubscribeOptions, CancellationToken.None).Result;
} }
public void Close() public void Close()
{ {
if (!IsRuning()) return;
Client.DisconnectAsync().Wait(); Client.DisconnectAsync().Wait();
Server.StopAsync().Wait();
} }
private void ClientConnServer() public bool IsRuning()
{ {
if (Client.IsConnected) return; return Client != null && Client.IsConnected;
MqttClientOptions mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("127.0.0.1", Config.Port)
.WithClientId(Config.ClientId)
.WithCredentials(Config.UserName, Config.Password)
.Build();
Client.ConnectAsync(mqttClientOptions, CancellationToken.None);
} }
public void SendAlarmMessage(AlarmMessage msg) public void SendAlarmMessage(AlarmMessage msg)
{ {
MqttApplicationMessage mqttMsg = new MqttApplicationMessageBuilder() MqttApplicationMessage mqttMsg = new MqttApplicationMessageBuilder()
.WithTopic(Config.TransmitTopic) .WithTopic(Config.PubAlarmTopic)
.WithPayload(JsonUtil.ToJson(msg)) .WithPayload(JsonUtil.ToJson(msg))
.Build(); .Build();
MqttClientPublishResult? result = null; MqttClientPublishResult? pubResult = null;
while (result == null || !result.IsSuccess) while (pubResult == null || !pubResult.IsSuccess)
{ {
try try
{ {
result = Client.PublishAsync(mqttMsg, CancellationToken.None).Result; pubResult = Client.PublishAsync(mqttMsg, CancellationToken.None).Result;
} }
catch (Exception) catch (Exception)
{ {
ClientConnServer(); Start();
Thread.Sleep(100); Thread.Sleep(100);
} }
} }
@ -91,34 +89,16 @@ public class AlarmMqttService : IAlarmService
#endregion Base #endregion Base
#region Server Event #region Receive
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) private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
{ {
string clientId = arg.ClientId; string topic = arg.ApplicationMessage.Topic;
ushort packetIdentifier = arg.PublishPacket.PacketIdentifier; string text = Encoding.UTF8.GetString(arg.ApplicationMessage.Payload);
string topic = arg.PublishPacket.Topic; string qos = arg.ApplicationMessage.QualityOfServiceLevel.ToString();
string msg = Encoding.UTF8.GetString(arg.PublishPacket.Payload); string retained = arg.ApplicationMessage.Retain.ToString();
return Task.CompletedTask; return Task.CompletedTask;
} }
#endregion Server Event #endregion Receive
} }

5
JiLinApp.Biz/TransmitAlarm/Service/AlarmZmqService.cs

@ -12,6 +12,11 @@ public class AlarmZmqService : IAlarmService
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool IsRuning()
{
throw new NotImplementedException();
}
public void SendAlarmMessage(AlarmMessage msg) public void SendAlarmMessage(AlarmMessage msg)
{ {
throw new NotImplementedException(); throw new NotImplementedException();

2
JiLinApp.Biz/TransmitAlarm/Service/Interfaces/IAlarmService.cs

@ -6,5 +6,7 @@ public interface IAlarmService
void Close(); void Close();
bool IsRuning();
void SendAlarmMessage(AlarmMessage msg); void SendAlarmMessage(AlarmMessage msg);
} }

72
JiLinApp.Docking/FenceAlarm/Entity/SectorState.cs

@ -5,58 +5,60 @@ public class SectorState
#region Fields #region Fields
public int Id { get; set; }//防区号 public int Id { get; set; }//防区号
/*0使
1 /// <summary>
2 /// 0: 防区未使用
3 /// 1: 防区撤防
4 /// 2: 防区布防
5线 /// 3: 防区旁路
6线(线线) /// 4: 防区报警
*/ /// 5: 无线防区欠压
/// 6: 防区掉线(与主线总线脱离)
/// </summary>
public int State { get; set; }//防区状态 public int State { get; set; }//防区状态
public string StateStr public string StateStr
{ {
get get
{ {
switch (State) return State switch
{ {
case 0: return "防区未使用"; 0 => "防区未使用",
case 1: return "防区撤防"; 1 => "防区撤防",
case 2: return "防区布防"; 2 => "防区布防",
case 3: return "防区旁路"; 3 => "防区旁路",
case 4: return "防区报警"; 4 => "防区报警",
case 5: return "无线防区欠压"; 5 => "无线防区欠压",
case 6: return "防区掉线"; 6 => "防区掉线",
default: return "未知状态:" + State; _ => "未知状态:" + State,
} };
} }
} }
/* /// <summary>
0: /// 0: 普通防区,无特殊参数
1线线 /// 1: 张力防区需要单独查询因为这个防区显示张力线值每条线状态
2 /// 2: 脉冲围栏
3 /// 3: 振动光纤
4 /// 4: 泄漏电缆
5线 /// 5: 网络或总线多子防区模块
*/ /// </summary>
public int Type { get; set; }//防区类型,特殊参数需单独查询 public int Type { get; set; }//防区类型,特殊参数需单独查询
public string TypeStr public string TypeStr
{ {
get get
{ {
switch (Type) return Type switch
{ {
case 0: return "普通防区"; 0 => "普通防区",
case 1: return "张力防区"; 1 => "张力防区",
case 2: return "脉冲围栏"; 2 => "脉冲围栏",
case 3: return "振动光纤"; 3 => "振动光纤",
case 4: return "泄漏电缆"; 4 => "泄漏电缆",
case 5: return "网络或总线多子防区模块"; 5 => "网络或总线多子防区模块",
default: return "未知类型:" + Type; _ => "未知类型:" + Type,
} };
} }
} }

148
JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHost.cs

@ -0,0 +1,148 @@
using System.Collections.Concurrent;
namespace JiLinApp.Docking.FenceAlarm;
public class UdpAlarmHost
{
public int DeviceId { get; set; }
public string Ip { get; set; }
public int Port { get; set; }
public int GroupId { get; set; }//分组号,报警主机可划入不同组
public int UserId { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分
/// <summary>
/// 0x00: 撤防状态
/// 0x01: 外出布防(普通布防最常用)
/// 0x02: 即时布防(所有防区没有延时)
/// 0x04: 在家布防(留守布防有些防区可能是在旁路状态)
/// 0x08: 即时留守布防(有些防区可能旁路, 但是没有旁路防区没有延时)
/// 0x09: 部分防区布防部分防区撤防
/// </summary>
public int DefenceState { get; set; }//主机布撤状态
public string DefenceStateStr
{
get
{
return DefenceState switch
{
0x00 => "撤防状态",
0x01 => "外出布防",
0x02 => "即时布防",
0x04 => "在家布防",
0x08 => "即时留守布防",
0x09 => "部分防区布防",
_ => "未知状态号:" + DefenceState,
};
}
}
/// <summary>
/// 0x00:此设备处于常规工作状态,正常报警
/// 0x01:工作在设置模式,不会处理报警,用户这进行设置,设置完一般很快退出
/// 0x02:用户正在查询当前报警信息
/// 0x03:用户正在设置时钟
/// 0x04:工作在用户密码修改模式下
/// </summary>
public int WorkState { get; set; }//设备工作状态
public string WorkStateStr
{
get
{
return DefenceState switch
{
0x00 => "常规工作状态",
0x01 => "在设置模式",
0x02 => "用户正在查询报警",
0x03 => "用户正在设置时钟",
0x04 => "用户密码修改模式",
_ => "未知状态号:" + WorkState,
};
}
}
public int CellState { get; set; }//电池状态 1=电池故障 0=电池正常
public int ElectricityState { get; set; }//交流状态 1=交流掉电 0=交流正常
public int FuseState { get; set; }//警保险丝状态 1=外接警号断了0=正常
public int SectorState { get; set; }//有线防区触发了 1=其中有线防区触发了 0=所有有线防区准备好
public int CellTestState { get; set; }//正在电池载能测试 1=主机正在进行电池载能测试 0=无(主机会降低电压到电池12V以下,来测试电池负载特性需要2分钟)
public int DeviceElectricityState { get; set; }//设备交流电状态1=交流掉电,目前电池供电0=正常 这是即时状态
public int SoundState { get; set; }//设备声音输出状态(=0关闭声音) =1 输出声音) 用于布防和报警延时
public int TestState { get; set; }//主机本地测试状态1=主机在本地测试(用于测试探测好坏是没有报警记录的)0=无
public int CriticalAlarmState { get; set; }//软防区紧急报警状态1=有紧急报警(用户通过手动按下主机自带装置报警) 0=无
public int FireAlarmState { get; set; }//软防区火警报警状态1=有火警报警(用户通过手动按下主机自带装置报警) 0=无
public int StealAlarmState { get; set; }//软防区盗警报警状态1=有盗警报警(用户通过手动按下主机自带装置报警) 0=无
public int DeviceFireAlarmState { get; set; }//设备中有火警报警状态 1=其中有火警防区触发了 0=无 整体状态
public int DeviceAlarmState { get; set; }//设备有报警发生 1=指设备有报警状态,任一一种0=无报警
public int DeviceBywayState { get; set; }//设备有旁路防区1=指设备某些防区有旁路了(这时软件可以要求上传具体旁路的防区) 2=无防区旁路
public int BusOfflineState { get; set; }//有总线防区掉线状态1=指某些总线防区掉线了0=无
public int NetOfflineState { get; set; }//有网络防区掉线状态1=指某些网络防区掉线了0=无
/// <summary>
/// 00: 通用设备兼容没有设置或未知设备
/// 01: EH508报警主机
/// 02: EH508NP网络模块
/// 03: NETLINKBOARD32路网络模块
/// 04: EH508NETCILENT网络终端
/// 05: EH8008路光纤主机
/// 06: EH508NP_UDP私有服务器网络模块
/// 07: EH508CILENT_UDP私有服务器接警终端
/// 08: EH508SEVER_UDP私有服务器主机
/// 09: EH508MAP_UDP私有服务器电子地图
/// 0A: EH508_UDP私有服务器用EH508主机
/// 0x32: H768_IP系列网络模块
/// 0x33: D238C_IP网络模块
/// 0x34: H778S+系列报警主机
/// 0x35: H778S系列报警主机
/// 0x36: N201N202网络模块
/// </summary>
public int DevideType { get; set; }//设备类型:区分不同的设备类型 增强可控,防止混乱,具体的设备类型见附加说明表格
public int SignalIntensity { get; set; }//31:信号最强,如果设备类型不是这种不需要显示 指主要带有GPRS模块设备跟据设备类型来的
//-------------------------------防区信息-----------------------------//
public int SectorTotal { get; set; }//分区总数量
public ConcurrentDictionary<int, SectorState> SectorDict { get; }
public int OnlineState { get; set; }//设备在线状态
public int KeepLive { get; set; }//设备在线状态
public UdpAlarmHost()
{
DeviceId = 0;
GroupId = 0;
UserId = 0;
DefenceState = -1;
WorkState = 0;
CellState = 0;
ElectricityState = 0;
FuseState = 0;
SectorState = 0;
CellTestState = 0;
DeviceElectricityState = 0;
SoundState = 0;
TestState = 0;
CriticalAlarmState = 0;
FireAlarmState = 0;
StealAlarmState = 0;
DeviceFireAlarmState = 0;
DeviceAlarmState = 0;
DeviceBywayState = 0;
BusOfflineState = 0;
NetOfflineState = 0;
DevideType = 0;
SignalIntensity = 0;
SectorTotal = 0;
OnlineState = 0;
SectorDict = new();
}
}

172
JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostDevice.cs

@ -1,172 +0,0 @@
namespace JiLinApp.Docking.FenceAlarm;
public class UdpAlarmHostDevice
{
public int deviceID { get; set; }//设备唯一ID
public string Ip { get; set; }//设备Ip
public int Port { get; set; } //设备端口
public int GroupID { get; set; }//分组号,报警主机可划入不同组
public int UserID { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分
/*0x00:
0x04: ()
0x02:()
0x08 :(,)
0x01:()
0x09:
*/
public int deviceState { get; set; }//主机布撤状态,
public string deviceStateStr
{
get
{
switch (deviceState)
{
case 0x00:
return "撤防状态";
case 0x01:
return "外出布防";
case 0x02:
return "即时布防";
case 0x04:
return "在家布防";
case 0x08:
return "即时留守布防";
case 0x09:
return "部分防区布防";
default:
return "未知状态号:" + deviceState;
}
}
}
/*0x00,
0x01,,,退
0x02
0x03
0x04
*/
public int deviceWorkState { get; set; }//设备工作状态
public string deviceWorkStateStr
{
get
{
switch (deviceState)
{
case 0x00:
return "常规工作状态";
case 0x01:
return "在设置模式";
case 0x02:
return "用户正在查询报警";
case 0x03:
return "用户正在设置时钟";
case 0x04:
return "用户密码修改模式";
default:
return "未知状态号:" + deviceWorkState;
}
}
}
public int cellState { get; set; }//电池状态 1=电池故障 0=电池正常
public int electricityState { get; set; }//交流状态 1=交流掉电 0=交流正常
public int fuseState { get; set; }//警保险丝状态 1=外接警号断了0=正常
public int sectorState { get; set; }//有线防区触发了 1=其中有线防区触发了 0=所有有线防区准备好
public int cellTestState { get; set; }//正在电池载能测试 1=主机正在进行电池载能测试 0=无(主机会降低电压到电池12V以下,来测试电池负载特性需要2分钟)
public int deviceElectricityState { get; set; }//设备交流电状态1=交流掉电,目前电池供电0=正常 这是即时状态
public int soundState { get; set; }//设备声音输出状态(=0关闭声音) =1 输出声音) 用于布防和报警延时
public int testState { get; set; }//主机本地测试状态1=主机在本地测试(用于测试探测好坏是没有报警记录的)0=无
public int criticalAlarmState { get; set; }//软防区紧急报警状态1=有紧急报警(用户通过手动按下主机自带装置报警) 0=无
public int fireAlarmState { get; set; }//软防区火警报警状态1=有火警报警(用户通过手动按下主机自带装置报警) 0=无
public int stealAlarmState { get; set; }//软防区盗警报警状态1=有盗警报警(用户通过手动按下主机自带装置报警) 0=无
public int deviceFireAlarmState { get; set; }//设备中有火警报警状态 1=其中有火警防区触发了 0=无 整体状态
public int deviceAlarmState { get; set; }//设备有报警发生 1=指设备有报警状态,任一一种0=无报警
public int deviceBywayState { get; set; }//设备有旁路防区1=指设备某些防区有旁路了(这时软件可以要求上传具体旁路的防区) 2=无防区旁路
public int busOfflineState { get; set; }//有总线防区掉线状态1=指某些总线防区掉线了0=无
public int netOfflineState { get; set; }//有网络防区掉线状态1=指某些网络防区掉线了0=无
/*00:
01:EH508报警主机
02:EH508NP网络模块
03: NETLINKBOARD32路网络模块
04: EH508NETCILENT网络终端
05: EH800 8
06: EH508NP_UDP
07: EH508CILENT_UDP
08: EH508SEVER_UDP
09: EH508MAP_UDP
0A: EH508_UDP EH508主机
0x32: H768_IP系列网络模块
0x33: D238C_IP网络模块
0x34: H778S+
0x35: H778S系列报警主机
0x36:N201 N202网络模块
*/
public int devideType { get; set; }//设备类型:区分不同的设备类型 增强可控,防止混乱,具体的设备类型见附加说明表格
public int signalIntensity { get; set; }//31:信号最强,如果设备类型不是这种不需要显示 指主要带有GPRS模块设备跟据设备类型来的
public int channelNum { get; set; }//分区数量
public List<int> channelState { get; set; }//分区布防撤防状态,0为撤防,1为布防
public List<int> channelAlarmState { get; set; }//分区报警状态,0为报警中,1为未报警
//-------------------------------防区信息-----------------------------//
public int maxSectorNum { get; set; }//最大防区号
public List<SectorState> sectorList { get; set; }
public int deviceOnlineState { get; set; }//设备在线状态
public int keep_live { get; set; }//设备在线状态
public UdpAlarmHostDevice()
{
deviceID = 0;
GroupID = 0;
UserID = 0;
deviceState = -1;
deviceWorkState = 0;
cellState = 0;
electricityState = 0;
fuseState = 0;
sectorState = 0;
cellTestState = 0;
deviceElectricityState = 0;
soundState = 0;
testState = 0;
criticalAlarmState = 0;
fireAlarmState = 0;
stealAlarmState = 0;
deviceFireAlarmState = 0;
deviceAlarmState = 0;
deviceBywayState = 0;
busOfflineState = 0;
netOfflineState = 0;
devideType = 0;
signalIntensity = 0;
channelNum = 0;
channelState = null;
channelAlarmState = null;
sectorList = null;
deviceOnlineState = 0;
}
}

10
JiLinApp.Docking/FenceAlarm/Entity/UdpAlarmHostMessage.cs

@ -9,12 +9,12 @@ public class UdpAlarmHostMessage
public string CID { get; set; }//CID代码 public string CID { get; set; }//CID代码
/*设备信息*/ /*设备信息*/
public int DeviceID { get; set; }//设备唯一ID public int DeviceId { get; set; }//设备唯一ID
public int ChannelNum { get; set; }//防区号
public int SubChannelNum { get; set; }//子防区号
public string Ip { get; set; }//设备IP public string Ip { get; set; }//设备IP
public int GroupID { get; set; }//分组号,报警主机可划入不同组 public int SectorId { get; set; }//防区号
public int UserID { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分 public int SubSectorId { get; set; }//子防区号
public int GroupId { get; set; }//分组号,报警主机可划入不同组
public int UserId { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分
public int LinkOut { get; set; }//联动输出 public int LinkOut { get; set; }//联动输出
public string ExtendArgs { get; set; }//扩展参数 public string ExtendArgs { get; set; }//扩展参数

269
JiLinApp.Docking/FenceAlarm/Service/AlarmEncode.cs

@ -2,65 +2,66 @@
public class AlarmEncode public class AlarmEncode
{ {
private static byte[] TEA_key = new byte[16] { #region Fields
public static readonly byte Version = 0x12;
public static readonly byte[] Head = new byte[] { 0xF0, 0xFA };
public static readonly byte End = 0x0D;
public static readonly byte[] TEA_key = new byte[16] {
0x08,0x01,0x08,0x06,0x07,0x08,0x07,0x08, 0x08,0x01,0x08,0x06,0x07,0x08,0x07,0x08,
0x08,0x90,0xC5,0x04,0x0D,0x0E,0x0F,0x10 0x08,0x90,0xC5,0x04,0x0D,0x0E,0x0F,0x10
}; };
public static byte[] encodeMessage(byte[] msg) #endregion Fields
public static byte[] EncodeMessage(byte[] msg)
{ {
if (!checkMessage(msg)) return null; if (!CheckMessage(msg)) return Array.Empty<byte>();
return getMessage(msg[0], btea_encrypt(getContent(msg, msg[0] - 1))); return GetMessage(msg[0], BteaEncrypt(GetContent(msg, msg[0] - 1)));
} }
public static byte[] decodeMessage(byte[] msg) public static byte[] DecodeMessage(byte[] msg)
{ {
if (!checkMessage(msg)) return null; if (!CheckMessage(msg)) return Array.Empty<byte>();
return getMessage(msg[0], btea_decrpyt(getContent(msg, msg[0] - 1))); return GetMessage(msg[0], BteaDecrpyt(GetContent(msg, msg[0] - 1)));
} }
public static byte[] CRC16(byte[] data) private static bool CheckMessage(byte[] msg)
{ {
int len = data.Length; if (msg == null) return false;
if (len > 0) if (msg[0] > msg.Length) return false;
{ return true;
ushort crc = 0xFFFF;
for (int i = 0; i < len; i++)
{
crc = (ushort)(crc ^ (data[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
return new byte[] { hi, lo };
}
return new byte[] { 0, 0 };
} }
private static byte version = 0x12; private static byte[] GetMessage(byte msgLen, byte[] msg)
private static byte[] head = new byte[] { 0xF0, 0xFA };
private static byte end = 0x0D;
public static byte[] getSendMessage(byte command, byte[] data)
{ {
byte[] msg = null; byte[] outMsg = new byte[msg.Length + 1];
if (data == null) outMsg[0] = msgLen;
for (int i = 0; i < msg.Length; i++)
{ {
msg = new byte[8]; outMsg[i + 1] = msg[i];
} }
else return outMsg;
}
private static byte[] GetContent(byte[] msg, int len)
{
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++)
{ {
msg = new byte[data.Length + 8]; bytes[i] = msg[i + 1];
} }
return bytes;
}
public static byte[] GetSendMessage(byte command, byte[] data)
{
byte[] msg = data != null ? new byte[data.Length + 8] : new byte[8];
msg[0] = (byte)msg.Length; msg[0] = (byte)msg.Length;
msg[1] = version; msg[1] = Version;
msg[2] = head[0]; msg[2] = Head[0];
msg[3] = head[1]; msg[3] = Head[1];
msg[4] = command; msg[4] = command;
if (data != null) if (data != null)
{ {
@ -69,55 +70,40 @@ public class AlarmEncode
msg[i + 5] = data[i]; msg[i + 5] = data[i];
} }
} }
byte[] subMsg = null; byte[] subMsg = data != null ? new byte[data.Length + 4] : new byte[4];
if (data == null)
{
subMsg = new byte[4];
}
else
{
subMsg = new byte[4 + data.Length];
}
for (int i = 0; i < subMsg.Length; i++) for (int i = 0; i < subMsg.Length; i++)
{ {
subMsg[i] = msg[i + 1]; subMsg[i] = msg[i + 1];
} }
byte[] crc = CRC16(subMsg); byte[] crc = CRC16(subMsg);
msg[msg.Length - 3] = crc[1]; msg[^3] = crc[1];
msg[msg.Length - 2] = crc[0]; msg[^2] = crc[0];
msg[msg.Length - 1] = end; msg[^1] = End;
return msg; return msg;
} }
private static bool checkMessage(byte[] msg) public static byte[] CRC16(byte[] data)
{
if (msg == null) return false;
if (msg[0] > msg.Length) return false;
return true;
}
private static byte[] getContent(byte[] msg, int len)
{
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++)
{
bytes[i] = msg[i + 1];
}
return bytes;
}
private static byte[] getMessage(byte msgLen, byte[] msg)
{ {
byte[] out_msg = new byte[msg.Length + 1]; int len = data.Length;
out_msg[0] = msgLen; if (len > 0)
for (int i = 0; i < msg.Length; i++)
{ {
out_msg[i + 1] = msg[i]; ushort crc = 0xFFFF;
for (int i = 0; i < len; i++)
{
crc = (ushort)(crc ^ (data[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
return new byte[] { hi, lo };
} }
return out_msg; return new byte[] { 0, 0 };
} }
private static byte[] btea_encrypt(byte[] bytes) private static byte[] BteaEncrypt(byte[] bytes)
{ {
byte[] output = new byte[bytes.Length]; byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++) for (int i = 0; i < bytes.Length; i++)
@ -128,7 +114,7 @@ public class AlarmEncode
return output; return output;
} }
private static byte[] btea_decrpyt(byte[] bytes) private static byte[] BteaDecrpyt(byte[] bytes)
{ {
byte[] output = new byte[bytes.Length]; byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++) for (int i = 0; i < bytes.Length; i++)
@ -138,4 +124,133 @@ public class AlarmEncode
} }
return output; return output;
} }
}
public enum DeviceCmd : byte
{
/// <summary>
/// 心跳
/// </summary>
HeartBeatCmd = 0x01,
/// <summary>
/// 报警
/// </summary>
AlarmCmd = 0x02,
/// <summary>
/// 所有防区状态
/// </summary>
AllSectorStateCmd = 0x03,
/// <summary>
/// 实时防区状态
/// </summary>
RtSectorStateCmd = 0x04,
/// <summary>
/// 最大防区号
/// </summary>
MaxSectorTotalCmd = 0x05,
/// <summary>
/// 报警主机设置参数返回服务器
/// </summary>
BackSettingsCmd = 0x08,
/// <summary>
/// 布防指令
/// </summary>
DefenceCmd = 0x80,
/// <summary>
/// 校对时间指令
/// </summary>
CheckTimeCmd = 0x8D,
/// <summary>
/// 正确应答指令
/// </summary>
OkCmd = 0x8F,
/// <summary>
/// 主机重启指令
/// </summary>
RebootCmd = 0xA0,
}
public enum DeviceSectorType : byte
{
/// <summary>
/// 防区未使用
/// </summary>
NotUsed = 0x00,
/// <summary>
/// 防区撤防
/// </summary>
Withdraw = 0x01,
/// <summary>
/// 防区布防
/// </summary>
Deploy = 0x02,
/// <summary>
/// 防区旁路
/// </summary>
Byway = 0x03,
/// <summary>
/// 防区报警
/// </summary>
Alarm = 0x04,
/// <summary>
/// 无线防区欠压
/// </summary>
Undervoltage = 0x05,
/// <summary>
/// 防区掉线(与主线总线脱离)
/// </summary>
OffBus = 0x06,
/// <summary>
/// 未准备就绪
/// </summary>
Unprepared = 0x07,
}
public enum DeviceDefenceState : byte
{
/// <summary>
/// 撤防状态
/// </summary>
Withdraw = 0x00,
/// <summary>
/// 外出布防(普通布防最常用)
/// </summary>
GoOut = 0x01,
/// <summary>
/// 即时布防(所有防区没有延时)
/// </summary>
Immediately = 0x02,
/// <summary>
/// 在家布防(留守布防有些防区可能是在旁路状态)
/// </summary>
Home = 0x04,
/// <summary>
/// 即时留守布防(有些防区可能旁路,但是没有旁路防区没有延时)
/// </summary>
HomeImmediately = 0x08,
/// <summary>
/// 部分防区布防部分防区撤防
/// </summary>
Part = 0x09
} }

1159
JiLinApp.Docking/FenceAlarm/Service/UdpManager.cs

File diff suppressed because it is too large

94
JiLinApp.Docking/FenceAlarm/Service/Udp.cs → JiLinApp.Docking/FenceAlarm/Service/UdpServer.cs

@ -4,12 +4,10 @@ using System.Net.Sockets;
namespace JiLinApp.Docking.FenceAlarm; namespace JiLinApp.Docking.FenceAlarm;
public class Udp public class UdpServer
{ {
#region Fields #region Fields
private BackgroundWorker BackWorker { get; }
/// <summary> /// <summary>
/// 用于UDP接收的网络服务类 /// 用于UDP接收的网络服务类
/// </summary> /// </summary>
@ -20,27 +18,38 @@ public class Udp
/// </summary> /// </summary>
private UdpClient SendUdp { get; } private UdpClient SendUdp { get; }
private BackgroundWorker Worker { get; }
#region Properties
public string RecvIp { get; private set; }
public int RecvPort { get; private set; }
#endregion Properties
#endregion Fields #endregion Fields
#region Ctors #region Ctors
public Udp(int port) : this("0.0.0.0", port) public UdpServer(int port) : this("0.0.0.0", port)
{ {
} }
public Udp(string ip, int port) public UdpServer(string ip, int port)
{ {
RecvIp = ip;
RecvPort = port;
RecvUdp = new(new IPEndPoint(IPAddress.Parse(ip), port)); RecvUdp = new(new IPEndPoint(IPAddress.Parse(ip), port));
SendUdp = new(new IPEndPoint(IPAddress.Any, 0)); SendUdp = new(new IPEndPoint(IPAddress.Any, 0));
BackWorker = new BackgroundWorker Worker = new()
{ {
WorkerSupportsCancellation = true WorkerSupportsCancellation = true
}; };
BackWorker.DoWork += Back_DoWork; Worker.DoWork += Back_DoWork;
BackWorker.RunWorkerAsync();
} }
~Udp() ~UdpServer()
{ {
Stop(); Stop();
} }
@ -49,24 +58,55 @@ public class Udp
#region Server #region Server
public void Start()
{
if (IsRunning()) return;
Worker.RunWorkerAsync();
}
public void Stop() public void Stop()
{ {
BackWorker?.CancelAsync(); if (!IsRunning()) return;
RecvUdp?.Close(); Worker.CancelAsync();
SendUdp?.Close(); RecvUdp.Close();
SendUdp.Close();
} }
#endregion Server public bool IsRunning()
{
return Worker != null && Worker.IsBusy;
}
#region Receive #endregion Server
public delegate void UDPReceive(IPEndPoint ipep, byte[] str); #region Events
public event UDPReceive DatagramReceived; public event EventHandler<UdpDatagramReceivedEventArgs<byte[]>>? DatagramReceived;
private void RaiseDatagramReceived(IPEndPoint ipep, byte[] datagram) private void RaiseDatagramReceived(IPEndPoint ipep, byte[] datagram)
{ {
DatagramReceived?.Invoke(ipep, datagram); DatagramReceived?.Invoke(this, new UdpDatagramReceivedEventArgs<byte[]>(ipep, datagram));
//DatagramReceived?.Invoke(ipep, datagram);
}
#endregion Events
#region Receive
private void Back_DoWork(object? sender, DoWorkEventArgs e)
{
IPEndPoint remoteIpep = new(IPAddress.Any, 0);
while (Worker != null && !Worker.CancellationPending)
{
try
{
byte[] bytRecv = RecvUdp.Receive(ref remoteIpep);
RaiseDatagramReceived(remoteIpep, bytRecv);
}
catch
{
}
}
} }
#endregion Receive #endregion Receive
@ -75,10 +115,9 @@ public class Udp
public bool SendMessage(string ip, int port, byte[] byteMsg) public bool SendMessage(string ip, int port, byte[] byteMsg)
{ {
IPEndPoint ipep = new(IPAddress.Parse(ip), port); // 发送到的IP地址和端口号 IPEndPoint ipep = new(IPAddress.Parse(ip), port);
int result = SendUdp.Send(byteMsg, byteMsg.Length, ipep); int result = SendUdp.Send(byteMsg, byteMsg.Length, ipep);
bool flag = result >= byteMsg.Length; bool flag = result >= byteMsg.Length;
Console.WriteLine("Send ok: {0}", flag);
return flag; return flag;
} }
@ -89,21 +128,4 @@ public class Udp
} }
#endregion Send #endregion Send
private void Back_DoWork(object? sender, DoWorkEventArgs e)
{
IPEndPoint remoteIpep = new(IPAddress.Any, 0);
while (BackWorker != null && !BackWorker.CancellationPending)
{
try
{
byte[] bytRecv = RecvUdp.Receive(ref remoteIpep);
DatagramReceived(remoteIpep, bytRecv);
}
catch
{
throw;
}
}
}
} }

2
JiLinApp.Docking/VibrateAlarm/Entity/ClientMessage.cs

@ -9,7 +9,7 @@ public class ClientMessage
public TcpClient Client { get; set; } public TcpClient Client { get; set; }
public TcpAlarmHostTable Host { get; set; } public TcpAlarmHost Host { get; set; }
public List<byte> DataList { get; } = new(); public List<byte> DataList { get; } = new();

2
JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostTable.cs → JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHost.cs

@ -1,6 +1,6 @@
namespace JiLinApp.Docking.VibrateAlarm; namespace JiLinApp.Docking.VibrateAlarm;
public class TcpAlarmHostTable public class TcpAlarmHost
{ {
public int Id { get; set; } public int Id { get; set; }

2
JiLinApp.Docking/VibrateAlarm/Entity/TcpAlarmHostMessage.cs

@ -10,7 +10,7 @@ public class TcpAlarmHostMessage
/*设备信息*/ /*设备信息*/
public int DeviceID { get; set; }//设备唯一ID public int DeviceID { get; set; }//设备唯一ID
public string ChannelNum { get; set; }//防区号 public string SensorAddr { get; set; }//防区号
public string Mode { get; set; } public string Mode { get; set; }
public string Sensitivity { get; set; } public string Sensitivity { get; set; }

83
JiLinApp.Docking/VibrateAlarm/Service/AsyncTcpServer.cs

@ -103,15 +103,8 @@ public class AsyncTcpServer : IDisposable
public void Start(int backlog) public void Start(int backlog)
{ {
if (IsRunning()) return; if (IsRunning()) return;
try Listener.Start(backlog);
{ AcceptTcpClient(Listener);
Listener.Start(backlog);
AcceptTcpClient(Listener);
}
catch (Exception)
{
throw;
}
} }
/// <summary> /// <summary>
@ -125,10 +118,6 @@ public class AsyncTcpServer : IDisposable
{ {
Listener.Stop(); Listener.Stop();
} }
catch (Exception)
{
throw;
}
finally finally
{ {
foreach (var client in Clients.Values) foreach (var client in Clients.Values)
@ -151,6 +140,40 @@ public class AsyncTcpServer : IDisposable
#endregion Server #endregion Server
#region Events
/// <summary>
/// 与客户端的连接已建立事件
/// </summary>
public event EventHandler<TcpClientConnectedEventArgs>? ClientConnected;
/// <summary>
/// 与客户端的连接已断开事件
/// </summary>
public event EventHandler<TcpClientDisconnectedEventArgs>? ClientDisconnected;
/// <summary>
/// 接收到数据报文事件
/// </summary>
public event EventHandler<TcpDatagramReceivedEventArgs<byte[]>>? DatagramReceived;
private void RaiseClientConnected(TcpClient client)
{
ClientConnected?.Invoke(this, new TcpClientConnectedEventArgs(client));
}
private void RaiseClientDisconnected(TcpClient client)
{
ClientDisconnected?.Invoke(this, new TcpClientDisconnectedEventArgs(client));
}
private void RaiseDatagramReceived(TcpClientState sender, byte[] datagram)
{
DatagramReceived?.Invoke(this, new TcpDatagramReceivedEventArgs<byte[]>(sender, datagram));
}
#endregion Events
#region Receive #region Receive
private void AcceptTcpClient(TcpListener listener) private void AcceptTcpClient(TcpListener listener)
@ -252,40 +275,6 @@ public class AsyncTcpServer : IDisposable
#endregion Receive #endregion Receive
#region Register Events
/// <summary>
/// 与客户端的连接已建立事件
/// </summary>
public event EventHandler<TcpClientConnectedEventArgs>? ClientConnected;
/// <summary>
/// 与客户端的连接已断开事件
/// </summary>
public event EventHandler<TcpClientDisconnectedEventArgs>? ClientDisconnected;
/// <summary>
/// 接收到数据报文事件
/// </summary>
public event EventHandler<TcpDatagramReceivedEventArgs<byte[]>>? DatagramReceived;
private void RaiseClientConnected(TcpClient client)
{
ClientConnected?.Invoke(this, new TcpClientConnectedEventArgs(client));
}
private void RaiseClientDisconnected(TcpClient client)
{
ClientDisconnected?.Invoke(this, new TcpClientDisconnectedEventArgs(client));
}
private void RaiseDatagramReceived(TcpClientState sender, byte[] datagram)
{
DatagramReceived?.Invoke(this, new TcpDatagramReceivedEventArgs<byte[]>(sender, datagram));
}
#endregion Register Events
#region Send #region Send
/// <summary> /// <summary>

182
JiLinApp.Docking/VibrateAlarm/Service/TcpManager.cs

@ -12,27 +12,33 @@ public class TcpManager
private AsyncTcpServer Server { get; set; } private AsyncTcpServer Server { get; set; }
private TcpManagerConfig Config { get; set; }
private ConcurrentDictionary<string, ClientMessage> ClientMessageDict { get; } = new(); private ConcurrentDictionary<string, ClientMessage> ClientMessageDict { get; } = new();
private Timer HeartTimer { get; } = new(); private Timer HeartTimer { get; } = new();
private Timer StateSpanTimer { get; } = new(); private Timer StateSpanTimer { get; } = new();
public delegate void TcpDeviceMessageEvent(TcpAlarmHostTable host, string msg); #region Event
public delegate void TcpDeviceMessageEvent(TcpAlarmHost host, string msg);
public delegate void TcpSensorMessageEvent(TcpAlarmHostTable host, TcpSensorTable section, string msg); public delegate void TcpSensorMessageEvent(TcpAlarmHost host, TcpSensorTable section, string msg);
public delegate void TcpSensorStateChangeEvent(SensorState state); public delegate void TcpSensorStateChangeEvent(SensorState state);
public delegate void TcpSensorAlarmEvent(TcpAlarmHostMessage msg); public delegate void TcpSensorAlarmEvent(TcpAlarmHostMessage msg);
public event TcpDeviceMessageEvent OnTcpDeviceMessage; public event TcpDeviceMessageEvent? OnTcpDeviceMessage;
public event TcpSensorMessageEvent OnTcpSensorMessage; public event TcpSensorMessageEvent? OnTcpSensorMessage;
public event TcpSensorStateChangeEvent OnTcpSensorStateChange; public event TcpSensorStateChangeEvent? OnTcpSensorStateChange;
public event TcpSensorAlarmEvent OnTcpSensorAlarm; public event TcpSensorAlarmEvent? OnTcpSensorAlarm;
#endregion Event
#endregion Fields #endregion Fields
@ -45,23 +51,43 @@ public class TcpManager
public void Start(TcpManagerConfig config) public void Start(TcpManagerConfig config)
{ {
if (IsRunning()) return; if (IsRunning()) return;
Server = new AsyncTcpServer(IPAddress.Any, config.ServerPort); try
Server.ClientConnected += Server_ClientConnected; {
Server.ClientDisconnected += Server_ClientDisconnected; Server = new(IPAddress.Any, config.ServerPort);
Server.DatagramReceived += Server_DatagramReceived; Server.ClientConnected += Server_ClientConnected;
Server.Start(); Server.ClientDisconnected += Server_ClientDisconnected;
Server.DatagramReceived += Server_DatagramReceived;
Server.Start();
}
catch (Exception)
{
return;
}
HeartTimer.Close(); HeartTimer.Close();
HeartTimer.Interval = 1000 * config.DeviceHeartKeep; HeartTimer.Interval = 1000 * config.DeviceHeartKeep;
HeartTimer.Elapsed += HeartTimer_Elapsed; HeartTimer.Elapsed += HeartTimer_Elapsed;
HeartTimer.Enabled = true;
HeartTimer.Start(); HeartTimer.Start();
Config = config;
} }
public void Stop() public void Stop()
{ {
HeartTimer.Enabled = false; if (!IsRunning()) return;
if (IsRunning()) Server.Stop(); try
{
Server.Stop();
}
finally
{
Server.ClientConnected -= Server_ClientConnected;
Server.ClientDisconnected -= Server_ClientDisconnected;
Server.DatagramReceived -= Server_DatagramReceived;
Server = null;
ClientMessageDict.Clear();
HeartTimer.Stop();
HeartTimer.Elapsed -= HeartTimer_Elapsed;
}
} }
public bool IsRunning() public bool IsRunning()
@ -71,7 +97,7 @@ public class TcpManager
#endregion Server #endregion Server
#region Register Event #region Events
private void HeartTimer_Elapsed(object? sender, ElapsedEventArgs e) private void HeartTimer_Elapsed(object? sender, ElapsedEventArgs e)
{ {
@ -107,7 +133,7 @@ public class TcpManager
} }
if (OnTcpDeviceMessage != null) if (OnTcpDeviceMessage != null)
{ {
TcpAlarmHostTable host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; TcpAlarmHost host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" };
OnTcpDeviceMessage(host, "报警主机上线"); OnTcpDeviceMessage(host, "报警主机上线");
} }
} }
@ -124,7 +150,7 @@ public class TcpManager
RemoveClientMessage(clientIp); RemoveClientMessage(clientIp);
if (OnTcpDeviceMessage != null) if (OnTcpDeviceMessage != null)
{ {
TcpAlarmHostTable host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" }; TcpAlarmHost host = clientMsg.Host ?? new() { Id = -1, Ip = clientIp, Port = clientPort, Name = "未知设备" };
OnTcpDeviceMessage(host, "报警主机下线"); OnTcpDeviceMessage(host, "报警主机下线");
} }
} }
@ -142,57 +168,7 @@ public class TcpManager
} }
} }
#endregion Register Event #endregion Events
#region ClientMessage
private bool ContainsClientMessage(string clientIp)
{
return ClientMessageDict.ContainsKey(clientIp);
}
private ClientMessage GetClientMessage(string clientIp)
{
return ClientMessageDict[clientIp];
}
private bool TryGetClientMessage(string clientIp, out ClientMessage clientMsg)
{
return ClientMessageDict.TryGetValue(clientIp, out clientMsg);
}
private bool AddClientMessage(string clientIp, ClientMessage clientMsg)
{
if (ContainsClientMessage(clientIp)) return false;
ClientMessageDict[clientIp] = clientMsg;
return true;
}
private void SetClientMessage(string clientIp, ClientMessage clientMsg)
{
ClientMessageDict[clientIp] = clientMsg;
}
private bool RemoveClientMessage(string clientIp)
{
return ClientMessageDict.Remove(clientIp, out _);
}
private bool UpdateClientMessage(string clientIp, TcpAlarmHostTable host)
{
if (!ClientMessageDict.ContainsKey(clientIp)) return false;
ClientMessageDict[clientIp].Host = host;
return true;
}
private bool UpdateClientMessage(string clientIp, List<byte> sensorList)
{
if (!ClientMessageDict.ContainsKey(clientIp)) return false;
ClientMessageDict[clientIp].SensorList = sensorList;
return true;
}
#endregion ClientMessage
#region Analysis #region Analysis
@ -208,7 +184,7 @@ public class TcpManager
DataMessage mm = new(); DataMessage mm = new();
mm.Decode(msglist[i]); mm.Decode(msglist[i]);
Console.WriteLine("Receive from {0}:{1} => {2}, {3}", clientMsg.Ip, clientMsg.Port, DataMessage.ToHexString(msglist[i]), JsonUtil.ToJson(mm)); Console.WriteLine("Receive from {0}:{1} => {2}, {3}", clientMsg.Ip, clientMsg.Port, DataMessage.ToHexString(msglist[i]), JsonUtil.ToJson(mm));
TcpAlarmHostTable host; TcpAlarmHost host;
switch (mm.FunctionNum) switch (mm.FunctionNum)
{ {
case 0x00: case 0x00:
@ -254,7 +230,7 @@ public class TcpManager
case 0x14: case 0x14:
Console.WriteLine("传感器状态响应:{0}", clientMsg.Ip); Console.WriteLine("传感器状态响应:{0}", clientMsg.Ip);
int channel = mm.Data[0] + mm.Data[1] * 256; int sensorAddr = mm.Data[0] + mm.Data[1] * 256;
int state = mm.Data[2] + mm.Data[3] * 256; int state = mm.Data[2] + mm.Data[3] * 256;
int online = state % 2; int online = state % 2;
int alarm = state / 2 % 2; int alarm = state / 2 % 2;
@ -263,9 +239,9 @@ public class TcpManager
clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "未知设备" }; clientMsg.Host = new() { Id = mm.DeviceId, Ip = mm.SendIp, Port = mm.SendPort.ToString(), Name = "未知设备" };
UpdateClientMessage(clientMsg.Ip, clientMsg.Host); UpdateClientMessage(clientMsg.Ip, clientMsg.Host);
} }
ProcessOnlineEvent(clientMsg, mm, channel, online); ProcessOnlineEvent(clientMsg, mm, sensorAddr, online);
ProcessAlarmEvent(clientMsg, mm, channel, alarm); ProcessAlarmEvent(clientMsg, mm, sensorAddr, alarm);
UpdateOnLineAlarm(clientMsg, channel, online, alarm); UpdateOnLineAlarm(clientMsg, sensorAddr, online, alarm);
SetDataRequest(mm, 0x04); SetDataRequest(mm, 0x04);
if (alarm == 1) if (alarm == 1)
{ {
@ -309,7 +285,7 @@ public class TcpManager
SensorState oldState = client.SectionTable[channel] as SensorState; SensorState oldState = client.SectionTable[channel] as SensorState;
if (oldState.online == online) return; if (oldState.online == online) return;
} }
TcpAlarmHostTable host = client.Host; TcpAlarmHost host = client.Host;
TcpSensorTable section = new() { DeviceId = host.Id, Name = "未知传感器", Channel = channel.ToString() }; TcpSensorTable section = new() { DeviceId = host.Id, Name = "未知传感器", Channel = channel.ToString() };
OnTcpSensorMessage?.Invoke(host, section, online == 0 ? "传感器上线" : "传感器离线"); OnTcpSensorMessage?.Invoke(host, section, online == 0 ? "传感器上线" : "传感器离线");
} }
@ -321,7 +297,7 @@ public class TcpManager
SensorState oldState = client.SectionTable[channel] as SensorState; SensorState oldState = client.SectionTable[channel] as SensorState;
if (oldState.alarm == alarm) return; if (oldState.alarm == alarm) return;
} }
TcpAlarmHostTable host = client.Host; TcpAlarmHost host = client.Host;
if (alarm == 1) if (alarm == 1)
{ {
ProcessAlarm(host.Id, channel); ProcessAlarm(host.Id, channel);
@ -339,7 +315,7 @@ public class TcpManager
} }
else else
{ {
TcpAlarmHostTable host = client.Host; TcpAlarmHost host = client.Host;
SensorState state = new(host.Id, channel, online, alarm); SensorState state = new(host.Id, channel, online, alarm);
client.SectionTable[channel] = state; client.SectionTable[channel] = state;
OnTcpSensorStateChange?.Invoke(state); OnTcpSensorStateChange?.Invoke(state);
@ -353,7 +329,7 @@ public class TcpManager
AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
CID = "1151", CID = "1151",
DeviceID = deviceId, DeviceID = deviceId,
ChannelNum = channel.ToString() SensorAddr = channel.ToString()
}; };
OnTcpSensorAlarm?.Invoke(alarmMsg); OnTcpSensorAlarm?.Invoke(alarmMsg);
} }
@ -476,6 +452,56 @@ public class TcpManager
#endregion Send #endregion Send
#region ClientMessage
private bool ContainsClientMessage(string clientIp)
{
return ClientMessageDict.ContainsKey(clientIp);
}
private ClientMessage GetClientMessage(string clientIp)
{
return ClientMessageDict[clientIp];
}
private bool TryGetClientMessage(string clientIp, out ClientMessage clientMsg)
{
return ClientMessageDict.TryGetValue(clientIp, out clientMsg);
}
private bool AddClientMessage(string clientIp, ClientMessage clientMsg)
{
if (ContainsClientMessage(clientIp)) return false;
ClientMessageDict[clientIp] = clientMsg;
return true;
}
private void SetClientMessage(string clientIp, ClientMessage clientMsg)
{
ClientMessageDict[clientIp] = clientMsg;
}
private bool RemoveClientMessage(string clientIp)
{
return ClientMessageDict.Remove(clientIp, out _);
}
private bool UpdateClientMessage(string clientIp, TcpAlarmHost host)
{
if (!ClientMessageDict.ContainsKey(clientIp)) return false;
ClientMessageDict[clientIp].Host = host;
return true;
}
private bool UpdateClientMessage(string clientIp, List<byte> sensorList)
{
if (!ClientMessageDict.ContainsKey(clientIp)) return false;
ClientMessageDict[clientIp].SensorList = sensorList;
return true;
}
#endregion ClientMessage
#region Set #region Set
private List<DataRequest> Reqlist { get; } = new(); private List<DataRequest> Reqlist { get; } = new();

4
JiLinApp/Core/Config.cs

@ -9,11 +9,11 @@ public class AppConfig
{ {
public BaseConfig Base { get; set; } public BaseConfig Base { get; set; }
public List<PtzControlTypeConfig> ptzCtrlTypes { get; set; } public List<PtzControlTypeConfig> PtzCtrlTypes { get; set; }
public List<CameraInfo> CameraList { get; set; } public List<CameraInfo> CameraList { get; set; }
public TransmitAlarmConfig TransmitAlarm { get; set; } public AlarmPlatformConfig AlarmPlatform { get; set; }
} }
public class BaseConfig public class BaseConfig

4
JiLinApp/Core/Global.cs

@ -32,9 +32,9 @@ public static class Global
// 控制台 // 控制台
if (AppConfig.Base.Console) SystemUtil.AllocConsole(); if (AppConfig.Base.Console) SystemUtil.AllocConsole();
// ptzCtrlTypes // ptzCtrlTypes
PtzControlTypeConfigHelper.Init(AppConfig.ptzCtrlTypes); PtzControlTypeConfigHelper.Init(AppConfig.PtzCtrlTypes);
AlarmService = AlarmServiceFactory.CreateService(AppConfig.TransmitAlarm); AlarmService = AlarmServiceFactory.CreateService(AppConfig.AlarmPlatform);
AlarmService?.Start(); AlarmService?.Start();
} }
catch (Exception) catch (Exception)

8
JiLinApp/Pages/FenceServerManage/Main.xaml.cs

@ -32,8 +32,8 @@ public partial class Main : UserControl
vm.SetView(this); vm.SetView(this);
Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState; Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState;
Manager.OnUdpAlarmSectionState += vm.OnUdpAlarmSectionState; Manager.OnUdpAlarmSectorState += vm.OnUdpAlarmSectionState;
Manager.OnUdpAlarmEvent += vm.OnUdpAlarmEvent; Manager.OnUdpAlarm += vm.OnUdpAlarmEvent;
} }
} }
@ -64,7 +64,7 @@ public partial class Main : UserControl
ServerPort = int.Parse(ServerPort.Text), ServerPort = int.Parse(ServerPort.Text),
DeviceHeartKeep = int.Parse(DeviceHeartKeep.Text) DeviceHeartKeep = int.Parse(DeviceHeartKeep.Text)
}; };
Manager.StartServer(config); Manager.Start(config);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -78,7 +78,7 @@ public partial class Main : UserControl
{ {
try try
{ {
Manager.StopServer(); Manager.Stop();
} }
catch (Exception) catch (Exception)
{ {

4
JiLinApp/Pages/FenceServerManage/MainViewModel.cs

@ -25,11 +25,11 @@ public class MainViewModel : ViewModelBase
#region ConnEvent #region ConnEvent
internal void OnUdpAlarmDeviceState(int deviceId, string state) internal void OnUdpAlarmDeviceState(int deviceId, int state)
{ {
} }
internal void OnUdpAlarmSectionState(int deviceId, int channel, string state) internal void OnUdpAlarmSectionState(int deviceId, int sectorId, int state)
{ {
} }

8
JiLinApp/Pages/PtzManage/Main.xaml.cs

@ -62,7 +62,7 @@ public partial class Main : UserControl
TaskUtil.RunCatch(() => Dispatcher.Invoke(LoadCameraList)); TaskUtil.RunCatch(() => Dispatcher.Invoke(LoadCameraList));
// 初始化云台控制类型 // 初始化云台控制类型
foreach (var cfg in Global.AppConfig.ptzCtrlTypes) foreach (var cfg in Global.AppConfig.PtzCtrlTypes)
{ {
ControlTypeName.Items.Add(new ComboBoxItem { Content = cfg.Name }); ControlTypeName.Items.Add(new ComboBoxItem { Content = cfg.Name });
} }
@ -249,7 +249,7 @@ public partial class Main : UserControl
private void TestBtn_Click(object sender, RoutedEventArgs e) private void TestBtn_Click(object sender, RoutedEventArgs e)
{ {
AlarmMessage alarm = new(); AlarmMessage alarm = new();
alarm.ChannelNum = Convert.ToInt32(PresetId.Text); alarm.ChannelId = Convert.ToInt32(PresetId.Text);
if (PresetId.Text == "5") if (PresetId.Text == "5")
{ {
PresetId.Text = "6"; PresetId.Text = "6";
@ -323,14 +323,14 @@ public partial class Main : UserControl
{ {
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
if (Global.AppConfig.TransmitAlarm.RealPlay) if (Global.AppConfig.AlarmPlatform.RealPlay)
{ {
PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ControlTypeName.Text); PtzControlType ctrlType = PtzControlTypeConfigHelper.GetControlType(ControlTypeName.Text);
if (ctrlType == PtzControlType.CameraSdk) ShowLiveVideo(); if (ctrlType == PtzControlType.CameraSdk) ShowLiveVideo();
} }
if (alarm != null) if (alarm != null)
{ {
if (alarm.ChannelNum <= 5) if (alarm.ChannelId <= 5)
{ {
PresetId.Text = "5"; PresetId.Text = "5";
} }

4
JiLinApp/Pages/VibrateServerManage/MainViewModel.cs

@ -25,11 +25,11 @@ public class MainViewModel : ViewModelBase
#region ConnEvent #region ConnEvent
internal void OnTcpDeviceMessage(TcpAlarmHostTable host, string msg) internal void OnTcpDeviceMessage(TcpAlarmHost host, string msg)
{ {
} }
internal void OnTcpSectionMessage(TcpAlarmHostTable host, TcpSensorTable section, string msg) internal void OnTcpSectionMessage(TcpAlarmHost host, TcpSensorTable section, string msg)
{ {
} }

14
JiLinApp/config/config.json

@ -17,7 +17,7 @@
}, },
{ {
"type": "DCamera", "type": "DCamera",
"Name": "协议D" "Name": "协议D508"
} }
], ],
@ -44,15 +44,21 @@
"password": "hk123456" "password": "hk123456"
} }
], ],
"transmitAlarm": { "alarmPlatform": {
"realPlay": true, "realPlay": true,
"type": "mqtt", "type": "mqtt",
"mqtt": { "mqtt": {
"ip": "192.168.1.200",
"port": "1883", "port": "1883",
"username": "admin", "username": "admin",
"password": "public", "password": "public",
"clientId": "alarmClient", "clientId": "alarm-platform1",
"transmitTopic": "alarm/transmit" "pubAlarmTopic": "PPS/AlarmMessage/Fence",
"subDevicesTopic": "PPS/AlarmMessage/Fence",
"subSensorsTopic": "PPS/AlarmMessage/Fence",
"subDeviceStateTopic": "PPS/AlarmMessage/Fence",
"subSensorStateTopic": "PPS/AlarmMessage/Fence",
"subCmdTopic": ""
} }
} }
} }
Loading…
Cancel
Save