Browse Source

update frame

master
fajiao 1 year ago
parent
commit
2e1aba0c13
  1. 13
      JiLinApp/App.xaml.cs
  2. 11
      JiLinApp/Core/Config.cs
  3. 26
      JiLinApp/Core/Global.cs
  4. 45
      JiLinApp/Core/LogUnit.cs
  5. 25
      JiLinApp/Core/TaskUtil.cs
  6. 64
      JiLinApp/Docking/AlarmMessage.cs
  7. 19
      JiLinApp/JiLinApp.csproj
  8. 2
      JiLinApp/Mvvm/ViewModelBase.cs
  9. 141
      JiLinApp/Pages/FenceServerManage/Core/AlarmEncode.cs
  10. 31
      JiLinApp/Pages/FenceServerManage/Core/Entity/DeviceStateMessage.cs
  11. 67
      JiLinApp/Pages/FenceServerManage/Core/Entity/SectorState.cs
  12. 172
      JiLinApp/Pages/FenceServerManage/Core/Entity/UdpAlarmHostDevice.cs
  13. 30
      JiLinApp/Pages/FenceServerManage/Core/Entity/UdpAlarmHostMessage.cs
  14. 12
      JiLinApp/Pages/FenceServerManage/Core/Entity/UdpManagerConfig.cs
  15. 71
      JiLinApp/Pages/FenceServerManage/Core/Udp.cs
  16. 885
      JiLinApp/Pages/FenceServerManage/Core/UdpManager.cs
  17. 22
      JiLinApp/Pages/FenceServerManage/Main.xaml.cs
  18. 6
      JiLinApp/Pages/FenceServerManage/MainViewModel.cs
  19. 4
      JiLinApp/Pages/Main/Core/MessageEvent.cs
  20. 4
      JiLinApp/Pages/Main/MainWindow.xaml
  21. 242
      JiLinApp/Pages/PtzManage/Core/PelcoD.cs
  22. 364
      JiLinApp/Pages/PtzManage/Core/PelcoP.cs
  23. 191
      JiLinApp/Pages/PtzManage/Core/PtzCmd.cs
  24. 1
      JiLinApp/Pages/PtzManage/Main.xaml
  25. 40
      JiLinApp/Pages/PtzManage/Main.xaml.cs
  26. 53
      JiLinApp/Pages/PtzManage/MainViewModel.cs
  27. 525
      JiLinApp/Pages/ShakeServerManage/Core/AsyncTcpServer.cs
  28. 51
      JiLinApp/Pages/ShakeServerManage/Core/CRC8.cs
  29. 74
      JiLinApp/Pages/ShakeServerManage/Core/Entity/ClientMessage.cs
  30. 90
      JiLinApp/Pages/ShakeServerManage/Core/Entity/DataMessage.cs
  31. 14
      JiLinApp/Pages/ShakeServerManage/Core/Entity/DataRequest.cs
  32. 57
      JiLinApp/Pages/ShakeServerManage/Core/Entity/SectionState.cs
  33. 20
      JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpAlarmHostMessage.cs
  34. 22
      JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpAlarmHostTable.cs
  35. 10
      JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpManagerConfig.cs
  36. 23
      JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpSectionTable.cs
  37. 31
      JiLinApp/Pages/ShakeServerManage/Core/TcpClientConnectedEventArgs.cs
  38. 31
      JiLinApp/Pages/ShakeServerManage/Core/TcpClientDisconnectedEventArgs.cs
  39. 48
      JiLinApp/Pages/ShakeServerManage/Core/TcpClientState.cs
  40. 34
      JiLinApp/Pages/ShakeServerManage/Core/TcpDatagramReceivedEventArgs.cs
  41. 753
      JiLinApp/Pages/ShakeServerManage/Core/TcpManager.cs
  42. 2
      JiLinApp/Pages/VibrateServerManage/Main.xaml
  43. 18
      JiLinApp/Pages/VibrateServerManage/Main.xaml.cs
  44. 7
      JiLinApp/Pages/VibrateServerManage/MainViewModel.cs
  45. 17
      JiLinApp/Properties/AssemblyInfo.cs
  46. 26
      JiLinApp/config.json
  47. 25
      JiLinApp/config/config.json
  48. 26
      JiLinApp/config/log4net.config

13
JiLinApp/App.xaml.cs

@ -1,6 +1,5 @@
using JiLinApp.Core;
using JiLinApp.Pages.Main;
using NewLife.Log;
using Prism.Ioc;
using Prism.Modularity;
using System;
@ -17,7 +16,7 @@ public partial class App
{
public App() : base()
{
RegisterEvents();
RegisterHandleEvents();
Global.Init();
}
@ -48,7 +47,7 @@ public partial class App
#region Bind
private void RegisterEvents()
private void RegisterHandleEvents()
{
//UI线程未捕获异常处理事件(UI主线程)
DispatcherUnhandledException += App_DispatcherUnhandledException;
@ -62,17 +61,19 @@ public partial class App
private static void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
XTrace.Log.Error("{0}", e.Exception.Message);
LogUnit.Error(e.Exception);
e.Handled = true;
}
private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
XTrace.Log.Error("{0}", e.Exception.Message);
LogUnit.Error(e.Exception);
e.SetObserved();
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
XTrace.Log.Error("{0}", ((Exception)e.ExceptionObject).Message);
LogUnit.Error(e.ExceptionObject as Exception);
}
#endregion Bind

11
JiLinApp/Core/Config.cs

@ -5,11 +5,20 @@ namespace JiLinApp.Core;
public class AppConfig
{
public ZmqConfig Zmq { get; set; }
public BaseConfig Base { get; set; }
public List<CameraInfo> CameraList { get; set; }
}
public class BaseConfig
{
public bool Console { get; set; }
}
public class MqttConfig
{
}
public class ZmqConfig
{
public string AlarmPubAddr { get; set; }

26
JiLinApp/Core/Global.cs

@ -1,42 +1,40 @@
using NetMQ.Sockets;
using EC.Util.Common;
using JiLinApp.Docking.Alarm;
using NewLife.Configuration;
using System;
using System.Windows;
using System.IO;
namespace JiLinApp.Core;
public static class Global
{
#region fields
#region Fields
public static readonly JsonConfigProvider ConfigProvider;
public static readonly AppConfig AppConfig;
private static JsonConfigProvider ConfigProvider { get; }
public static AppConfig AppConfig { get; }
public static readonly PublisherSocket AlarmPubSocket;
#endregion fields
#endregion Fields
static Global()
{
try
{
// Config
ConfigProvider = new() { FileName = "config.json" };
ConfigProvider = new() { FileName = Path.Combine("config", "config.json") };
AppConfig = new AppConfig();
ConfigProvider.Bind(AppConfig);
// Zmq
AlarmPubSocket = new();
AlarmPubSocket.Connect(AppConfig.Zmq.AlarmPubAddr);
// 控制台
if (AppConfig.Base.Console) SystemUtil.AllocConsole();
}
catch (Exception ex)
catch (Exception)
{
MessageBox.Show(ex.ToString());
throw;
}
}
public static void Init()
{
AlarmCodeHelper.Init();
}
}

45
JiLinApp/Core/LogUnit.cs

@ -0,0 +1,45 @@
using log4net;
using System;
namespace JiLinApp.Core;
public static class LogUnit
{
private static readonly ILog logger;
static LogUnit()
{
log4net.Config.XmlConfigurator.Configure();
logger = LogManager.GetLogger("root");
}
public static void Debug(string msg)
{
logger.Debug(msg);
}
public static void Info(string msg)
{
logger.Info(msg);
}
public static void Warn(string msg)
{
logger.Warn(msg);
}
public static void Error(string msg)
{
logger.Error(msg);
}
public static void Fatal(string msg)
{
logger.Fatal(msg);
}
public static void Error(Exception e)
{
logger.Error(e);
}
}

25
JiLinApp/Core/TaskUtil.cs

@ -1,5 +1,4 @@
using NewLife.Log;
using System;
using System;
using System.Threading.Tasks;
namespace JiLinApp.Core;
@ -7,6 +6,16 @@ namespace JiLinApp.Core;
public static class TaskUtil
{
public static Task Run(Action action)
{
return Task.Run(action);
}
/// <summary>
/// 相比于 Run,直接捕获并记录异常
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public static Task RunCatch(Action action)
{
return Task.Run(() =>
{
@ -16,8 +25,18 @@ public static class TaskUtil
}
catch (Exception e)
{
XTrace.Log.Error("{0}", e.Message);
LogUnit.Error(e);
}
});
}
/// <summary>
/// 相比于 Run,能及时抛出并全局捕获异常
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public static Task LongRun(Action action)
{
return Task.Factory.StartNew(action, TaskCreationOptions.LongRunning);
}
}

64
JiLinApp/Docking/AlarmMessage.cs

@ -1,64 +0,0 @@
using JiLinApp.Pages.FenceServerManage;
using JiLinApp.Pages.ShakeServerManage;
using System;
namespace JiLinApp.Docking;
public class AlarmMessage
{
/** (必填)传感器设备编码*/
public string labelCode;
/** (必填)报警类型((1-视频报警,2-雷达报警;3-微振动警报,4-电子围网警报,9-其他报警))*/
public int warnType;
/** (必填)报警级别(1-5)*/
public int warnLevel;
/** (必填)报警内容*/
public string warnContent;
/** 处置方式*/
public int dealWay;
/** (必填)处置状态(1-未处理,2-已处理)*/
public int dealStatus;
/** (必填)发生地点*/
public string cameraLoc;
/** (必填)发生时间*/
public DateTime createTime;
/** 负责人*/
public string director;
/** (必填)类型(1-预警,2-报警)*/
public int kind;
/** 现场照片*/
public string imgUrl;
}
public static class AlarmMessageHelper
{
public static AlarmMessage ToAlarmMessage(this TcpAlarmHostMessage msg)
{
AlarmMessage obj = new()
{
labelCode = Convert.ToString(msg.Id),
warnType = 3,
warnLevel = 1,
warnContent = msg.AlarmId,
dealStatus = 1,
createTime = Convert.ToDateTime(msg.AlarmTime),
kind = 1,
};
return obj;
}
public static AlarmMessage ToAlarmMessage(this UdpAlarmHostMessage msg)
{
AlarmMessage obj = new()
{
labelCode = Convert.ToString(msg.Id),
warnType = 4,
warnLevel = 1,
warnContent = msg.CID,
dealStatus = 1,
createTime = Convert.ToDateTime(msg.AlarmTime),
kind = 1,
};
return obj;
}
}

19
JiLinApp/JiLinApp.csproj

@ -4,20 +4,29 @@
<TargetFramework>net6.0-windows</TargetFramework>
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
<UseWPF>true</UseWPF>
<AssemblyVersion></AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MaterialDesignColors" Version="2.1.2" />
<PackageReference Include="MaterialDesignThemes" Version="4.8.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="MaterialDesignColors" Version="2.1.2">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="MaterialDesignThemes" Version="4.8.0">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="NewLife.Core" Version="10.2.2023.301" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EC.Util\EC.Util.csproj" />
<ProjectReference Include="..\JiLinApp.Biz\JiLinApp.Biz.csproj" />
<ProjectReference Include="..\JiLinApp.Docking\JiLinApp.Docking.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="config.json">
<None Update="config\config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="config\log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

2
JiLinApp/Mvvm/ViewModelBase.cs

@ -6,7 +6,7 @@ namespace JiLinApp.Mvvm;
public abstract class AbstractViewModelBase : BindableBase
{
#region fields
#region Fields
protected IRegionManager _region { get; set; }
protected IEventAggregator _ea { get; set; }

141
JiLinApp/Pages/FenceServerManage/Core/AlarmEncode.cs

@ -1,141 +0,0 @@
namespace JiLinApp.Pages.FenceServerManage;
public class AlarmEncode
{
private static byte[] TEA_key = new byte[16] {
0x08,0x01,0x08,0x06,0x07,0x08,0x07,0x08,
0x08,0x90,0xC5,0x04,0x0D,0x0E,0x0F,0x10
};
public static byte[] encodeMessage(byte[] msg)
{
if (!checkMessage(msg)) return null;
return getMessage(msg[0], btea_encrypt(getContent(msg, msg[0] - 1)));
}
public static byte[] decodeMessage(byte[] msg)
{
if (!checkMessage(msg)) return null;
return getMessage(msg[0], btea_decrpyt(getContent(msg, msg[0] - 1)));
}
public static byte[] CRC16(byte[] data)
{
int len = data.Length;
if (len > 0)
{
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[] head = new byte[] { 0xF0, 0xFA };
private static byte end = 0x0D;
public static byte[] getSendMessage(byte command, byte[] data)
{
byte[] msg = null;
if (data == null)
{
msg = new byte[8];
}
else
{
msg = new byte[data.Length + 8];
}
msg[0] = (byte)msg.Length;
msg[1] = version;
msg[2] = head[0];
msg[3] = head[1];
msg[4] = command;
if (data != null)
{
for (int i = 0; i < data.Length; i++)
{
msg[i + 5] = data[i];
}
}
byte[] subMsg = null;
if (data == null)
{
subMsg = new byte[4];
}
else
{
subMsg = new byte[4 + data.Length];
}
for (int i = 0; i < subMsg.Length; i++)
{
subMsg[i] = msg[i + 1];
}
byte[] crc = CRC16(subMsg);
msg[msg.Length - 3] = crc[1];
msg[msg.Length - 2] = crc[0];
msg[msg.Length - 1] = end;
return msg;
}
private static bool checkMessage(byte[] msg)
{
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];
out_msg[0] = msgLen;
for (int i = 0; i < msg.Length; i++)
{
out_msg[i + 1] = msg[i];
}
return out_msg;
}
private static byte[] btea_encrypt(byte[] bytes)
{
byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
{
byte abyte = (byte)(bytes[i] ^ TEA_key[i % 16]);
output[i] = (byte)(((byte)(abyte >> 3)) | ((byte)(abyte << 5)));
}
return output;
}
private static byte[] btea_decrpyt(byte[] bytes)
{
byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
{
byte abyte = (byte)(((byte)(bytes[i] << 3)) | ((byte)(bytes[i] >> 5)));
output[i] = (byte)(abyte ^ TEA_key[i % 16]);
}
return output;
}
}

31
JiLinApp/Pages/FenceServerManage/Core/Entity/DeviceStateMessage.cs

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.FenceServerManage;
public class DeviceStateMessage
{
public int deviceID { get; set; }//设备唯一ID
public string StatusTime { get; set; }//时间
public int channel { get; set; }//防区
public int StatusType { get; set; }//状态
public DeviceStateMessage(int id, DateTime time, int Channel, int statusType)
{
this.deviceID = id;
this.StatusTime = time.ToString("yyyy-MM-dd HH:mm:ss");
this.channel = Channel;
this.StatusType = statusType;
}
public DeviceStateMessage()
{
this.deviceID = -1;
this.StatusTime = "";
this.channel = -1;
this.StatusType = -1;
}
}

67
JiLinApp/Pages/FenceServerManage/Core/Entity/SectorState.cs

@ -1,67 +0,0 @@
namespace JiLinApp.Pages.FenceServerManage;
public class SectorState
{
public int id { get; set; }//防区号
/*0使
1
2
3
4
5线
6线(线线)
*/
public int state { get; set; }//防区状态
public string stateStr
{
get
{
switch (state)
{
case 0: return "防区未使用";
case 1: return "防区撤防";
case 2: return "防区布防";
case 3: return "防区旁路";
case 4: return "防区报警";
case 5: return "无线防区欠压";
case 6: return "防区掉线";
default: return "未知状态:" + state;
}
}
}
/*
0:
1线线
2
3
4
5线
*/
public int type { get; set; }//防区类型,特殊参数需单独查询
public string typeStr
{
get
{
switch (type)
{
case 0: return "普通防区";
case 1: return "张力防区";
case 2: return "脉冲围栏";
case 3: return "振动光纤";
case 4: return "泄漏电缆";
case 5: return "网络或总线多子防区模块";
default: return "未知类型:" + type;
}
}
}
public SectorState(int id, byte data)
{
this.id = id;
this.state = data & 0x0F;
this.type = data >> 4;
}
}

172
JiLinApp/Pages/FenceServerManage/Core/Entity/UdpAlarmHostDevice.cs

@ -1,172 +0,0 @@
using System.Collections.Generic;
namespace JiLinApp.Pages.FenceServerManage;
public class UdpAlarmHostDevice
{
public int deviceID { get; set; }//设备唯一ID
public string IP { get; set; }//设备IP
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;
}
}

30
JiLinApp/Pages/FenceServerManage/Core/Entity/UdpAlarmHostMessage.cs

@ -1,30 +0,0 @@
using Newtonsoft.Json.Linq;
namespace JiLinApp.Pages.FenceServerManage;
public class UdpAlarmHostMessage
{
public int Id { get; set; }
public string AlarmTime { get; set; }//报警时间
public string CID { get; set; }//CID代码
/*设备信息*/
public int DeviceID { get; set; }//设备唯一ID
public int ChannelNum { get; set; }//防区号
public int SubChannelNum { get; set; }//子防区号
public string Ip { get; set; }//设备IP
public int GroupID { get; set; }//分组号,报警主机可划入不同组
public int UserID { get; set; }//用户ID,指主机名称,有多台主机可以通过此名称区分
public int LinkOut { get; set; }//联动输出
public string ExtendArgs { get; set; }//扩展参数
/*CID信息*/
public string AlarmLevel { get; set; }//报警级别
public string AlarmContent { get; set; }//报警内容
public string AlarmRemarks { get; set; }//报警备注
public string AlarmType { get; set; }//报警类型
/*联动信息*/
public bool IsLinked { get; set; }//是否有联动信息
public JArray Linklist { get; set; }
}

12
JiLinApp/Pages/FenceServerManage/Core/Entity/UdpManagerConfig.cs

@ -1,12 +0,0 @@
namespace JiLinApp.Pages.FenceServerManage;
public class UdpManagerConfig
{
public string ServerIp { get; set; }
public int ServerPort { get; set; }
public int DevicePort { get; set; }
public int DeviceHeartKeep { get; set; }
}

71
JiLinApp/Pages/FenceServerManage/Core/Udp.cs

@ -1,71 +0,0 @@
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
namespace JiLinApp.Pages.FenceServerManage;
public class Udp
{
private BackgroundWorker back = null;
/// <summary>
/// 用于UDP发送的网络服务类
/// </summary>
private UdpClient udpcSend = null;
/// <summary>
/// 用于UDP接收的网络服务类
/// </summary>
private UdpClient udpcRecv;
public delegate void UDPReceive(string IP, byte[] str);//
public event UDPReceive myUDPReceive;//
public Udp(string ip, int port)
{
IPEndPoint localIpep = new IPEndPoint(
IPAddress.Parse(ip), port); // 本机IP和监听端口号
udpcRecv = new UdpClient(localIpep);
udpcSend = new UdpClient();
back = new BackgroundWorker();
back.WorkerSupportsCancellation = true;
back.DoWork += back_DoWork;
back.RunWorkerAsync();
}
~Udp()
{
if (back != null)
back.CancelAsync();
if (udpcRecv != null)
udpcRecv.Close();
if (udpcSend != null)
udpcSend.Close();
}
public bool SendMessage(byte[] sendbytes, string IP, int port)
{
IPEndPoint remoteIpep = new IPEndPoint(
IPAddress.Parse(IP), port); // 发送到的IP地址和端口号
int result = udpcSend.Send(sendbytes, sendbytes.Length, remoteIpep);
return result >= sendbytes.Length;
}
private void back_DoWork(object sender, DoWorkEventArgs e)
{
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);
while (!back.CancellationPending)
{
try
{
byte[] bytRecv = udpcRecv.Receive(ref remoteIpep);
myUDPReceive(remoteIpep.Address.ToString(), bytRecv);
}
catch
{
}
}
}
}

885
JiLinApp/Pages/FenceServerManage/Core/UdpManager.cs

@ -1,885 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Timers;
using System.Windows;
namespace JiLinApp.Pages.FenceServerManage;
public class UdpManager
{
#region fields
private Udp myUdp = null;
private int udp_sendPort = -1;
private int udp_ReceivePort = -1;
private int keep_alive = -1;
private Timer PtzCheckTimer = new();
private List<UdpAlarmHostDevice> deviceList = new();
#endregion fields
public UdpManager()
{
PtzCheckTimer.Interval = 1000;
PtzCheckTimer.Elapsed += PTZCheckTimer_Elapsed;
}
//计时判断设备是否在线,若超过规定时间没有新消息发来,则设备离线
private void PTZCheckTimer_Elapsed(object sender, ElapsedEventArgs e)
{
foreach (UdpAlarmHostDevice p1 in deviceList)
{
if (p1.keep_live >= 0)
{
p1.keep_live--;
}
if (p1.keep_live < 0)
{
p1.deviceOnlineState = 0;
if (OnUdpAlarmDeviceState != null)
{
OnUdpAlarmDeviceState(p1.deviceID, "设备离线");
}
}
}
}
public List<UdpAlarmHostDevice> getDeviceAll()
{
return deviceList;
}
public UdpAlarmHostDevice getDevice(int deviceID)
{
foreach (UdpAlarmHostDevice p1 in deviceList)
{
if (p1.deviceID == deviceID) return p1;
}
return null;
}
public List<SectorState> getDeviceChannelAll(int deviceID)
{
foreach (UdpAlarmHostDevice p1 in deviceList)
{
if (p1.deviceID == deviceID) return p1.sectorList;
}
return null;
}
public SectorState getDeviceChannel(int deviceID, int channel)
{
UdpAlarmHostDevice state = getDevice(deviceID);
if (state == null || state.sectorList == null) return null;
foreach (SectorState p1 in state.sectorList)
{
if (p1.id == channel) return p1;
}
return null;
}
#region BaseMethod
public bool StartServer(UdpManagerConfig config)
{
string s_IP = config.ServerIp;
int s_Port = config.ServerPort;
int d_Port = config.DevicePort;
int d_Keep = config.DeviceHeartKeep;
return AlarmHostLogin(s_IP, s_Port, d_Port, d_Keep);
}
public bool StopServer()
{
return AlarmHostLoginOut();
}
private bool AlarmHostLogin(string IP, int Port, int device_port, int keep_alive)
{
if (myUdp != null) AlarmHostLoginOut();
this.udp_sendPort = device_port;
this.udp_ReceivePort = Port;
this.keep_alive = keep_alive;
try
{
//启动UDP协议
myUdp = new Udp(IP, udp_ReceivePort);
myUdp.myUDPReceive += myUDPReceive;
}
catch (Exception ex)
{
myUdp = null;
MessageBox.Show(ex.ToString());
return false;
}
if (keep_alive > 0)
{
PtzCheckTimer.Enabled = true;
}
return true;
}
private bool AlarmHostLoginOut()
{
PtzCheckTimer.Enabled = false;
if (myUdp != null)
{
myUdp.myUDPReceive -= myUDPReceive;
myUdp = null;
}
return true;
}
#endregion BaseMethod
public delegate void UDPAlarmDeviceStateEvent(int deviceId, string state);
public event UDPAlarmDeviceStateEvent OnUdpAlarmDeviceState;
public delegate void UDPAlarmSectionStateEvent(int deviceId, int channel, string state);
public event UDPAlarmSectionStateEvent OnUdpAlarmSectionState;
public delegate void UDPAlarmEvent(UdpAlarmHostMessage msg);
public event UDPAlarmEvent OnUdpAlarmEvent;
public delegate void UDPAlarmCancelEvent(int deviceId, int channel);
public event UDPAlarmCancelEvent OnUdpAlarmCancel;
private void myUDPReceive(string Ip, byte[] str)
{
//解码
byte[] msg = AlarmEncode.decodeMessage(str);
//解析
switch (msg[4])
{
case 0x01: //心跳数据
analysisHeartMessage(Ip, msg);
break;
case 0x02://报警信息
AnalysisAlarmMessage(Ip, msg);
break;
case 0x03://防区信息
analysisAllSectorMessage(Ip, msg);
break;
case 0x04://张力防区信息
analysisSectorMessage(Ip, msg);
break;
case 0x05://报警主机最大防区信息
analysisMaxSectorMessage(Ip, msg);
break;
case 0x08://返回报警主机设置参数回服务器,无需解析
break;
default:
break;
}
Console.WriteLine("消息类型:" + msg[4]);
sendOK(Ip);
}
private void sendOK(string IP)
{
if (myUdp == null) return;
//byte[] bytes = new byte[] { 0x08, 0x12, 0xF0, 0xFA, 0x8F, 0x7F, 0x2E, 0x0D };
byte[] bytes = new byte[] { 0x08, 0x12, 0xF0, 0xFA, 0x8F, 0x06, 0x6B, 0x0D };
myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), IP, udp_sendPort);
}
private void analysisHeartMessage(string IP, byte[] msg)
{
int deviceID = ByteToInt(msg, 5);
UdpAlarmHostDevice device = getDevice(deviceID);
if (device == null)
{
device = new UdpAlarmHostDevice();
device.deviceID = deviceID;
device.userID = ByteToInt(msg, 13);
device.IP = IP;
device.deviceOnlineState = 1;
device.keep_live = keep_alive;
deviceList.Add(device);
}
device.deviceID = deviceID;
device.IP = IP;
device.groupID = ByteToInt(msg, 9);
device.userID = ByteToInt(msg, 13);
if (device.deviceState != msg[17])
{
if (OnUdpAlarmDeviceState != null)
{
switch (msg[17])
{
case 0x00://撤防状态
OnUdpAlarmDeviceState(device.deviceID, "撤防状态");
break;
case 0x01://外出布防
OnUdpAlarmDeviceState(device.deviceID, "外出布防(普通布防最常用)");
break;
case 0x02://即时布防(所有防区没有延时)
OnUdpAlarmDeviceState(device.deviceID, "即时布防(所有防区没有延时)");
break;
case 0x04://在家布防(留守布防有些防区可能是在旁路状态)
OnUdpAlarmDeviceState(device.deviceID, "在家布防(留守布防有些防区可能是在旁路状态)");
break;
case 0x08://即时留守布防(有些防区可能旁路,但是没有旁路防区没有延时)
OnUdpAlarmDeviceState(device.deviceID, "即时留守布防(有些防区可能旁路,但是没有旁路防区没有延时)");
break;
case 0x09://部分防区布防部分防区撤防
OnUdpAlarmDeviceState(device.deviceID, "部分防区布防部分防区撤防");
break;
}
}
}
device.deviceState = msg[17];
device.deviceWorkState = msg[18];
//设备状态1
device.cellState = getBit(msg[19], 0);
device.electricityState = getBit(msg[19], 1);
device.fuseState = getBit(msg[19], 2);
device.sectorState = getBit(msg[19], 3);
device.cellTestState = getBit(msg[19], 4);
device.deviceElectricityState = getBit(msg[19], 5);
device.soundState = getBit(msg[19], 6);
device.testState = getBit(msg[19], 7);
//设备状态2
device.criticalAlarmState = getBit(msg[20], 0);
device.fireAlarmState = getBit(msg[20], 1);
device.stealAlarmState = getBit(msg[20], 2);
device.deviceFireAlarmState = getBit(msg[20], 3);
device.deviceAlarmState = getBit(msg[20], 4);
device.deviceBywayState = getBit(msg[20], 5);
device.busOfflineState = getBit(msg[20], 6);
device.netOfflineState = getBit(msg[20], 7);
//设备状态3,4暂不使用
device.devideType = msg[23];
device.signalIntensity = msg[24];
device.channelNum = msg[25];
if (device.channelNum > 0)
{
device.channelState = new List<int>();
device.channelAlarmState = new List<int>();
for (int i = 0; i < device.channelNum; i++)
{
device.channelState.Add(getBit(msg[26], i));
device.channelAlarmState.Add(getBit(msg[27], i));
}
}
//在线状态
device.keep_live = keep_alive;
if (device.deviceOnlineState == 0)
{
if (OnUdpAlarmDeviceState != null)
{
OnUdpAlarmDeviceState(device.deviceID, "设备上线");
}
}
device.deviceOnlineState = 1;
}
private int getBit(byte bytes, int index)
{
switch (index)
{
case 0:
return bytes & 0x01;
case 1:
return (bytes & 0x02) >> 1;
case 2:
return (bytes & 0x04) >> 2;
case 3:
return (bytes & 0x08) >> 3;
case 4:
return (bytes & 0x10) >> 4;
case 5:
return (bytes & 0x20) >> 5;
case 6:
return (bytes & 0x40) >> 6;
case 7:
return (bytes & 0x80) >> 7;
default:
return 0;
}
}
private int ByteToInt(byte[] msg, int start)
{
byte[] bytes = new byte[] { msg[start + 3], msg[start + 2], msg[start + 1], msg[start] };
return BitConverter.ToInt32(bytes, 0);
}
private byte[] IntToByte(int num)
{
byte[] bytes = BitConverter.GetBytes(num);
return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
}
public void testAlarm(string devideId, string channel)
{
byte[] bytes = BitConverter.GetBytes(int.Parse(devideId));
byte[] bytes2 = BitConverter.GetBytes(int.Parse(channel));
byte[] msg = new byte[36]{
0x24,0x12,0xF0,0xFA,
0x02,bytes[3],bytes[2],bytes[1],
bytes[0],0x00,0x00,0x00,
0x00,bytes[3],bytes[2],bytes[1],
bytes[0],0x22,0x12,0x23,
0x10,0x10,0x10,0x01,
0x01,0x03,0x01,0x00,
0x02,bytes2[0],bytes2[1],0x00,
0x00,0x04,0x03,0x01
};
AnalysisAlarmMessage("127.0.0.1", msg);
}
private void AnalysisAlarmMessage(string IP, byte[] msg)
{
string CID = getCID(msg[23]) + getCID(msg[24]) + getCID(msg[25]) + getCID(msg[26]);
int deviceID = ByteToInt(msg, 5);
int channelNum = msg[29] + msg[30] * 256;
string alarmTime = "20" + getBCD(msg[17]) + "-" + getBCD(msg[18]) + "-" + getBCD(msg[19])
+ " " + getBCD(msg[20]) + ":" + getBCD(msg[21]) + ":" + getBCD(msg[22]);
if (CID.StartsWith("3"))
{
DataTable arrlist2 = new();
//DataTable arrlist2 = DBCenter.center.SearchByCondition("table_SectorAlarmMessage", "CID2='" + CID + "'");
if (arrlist2 == null || arrlist2.Rows.Count == 0)
{
//不是想要的消除警报信息
Console.WriteLine("不是想要的消除警报信息,设备号:" + deviceID + ",CID:" + CID);
return;
}
else
{
if (OnUdpAlarmCancel != null)
{
OnUdpAlarmCancel(deviceID, channelNum);
}
return;
}
}
//查询CID
DataTable arrlist = new();
//DataTable arrlist = DBCenter.center.SearchByCondition("table_SectorAlarmMessage", "CID='" + CID + "'");
if (arrlist == null || arrlist.Rows.Count == 0)
{
//查询不到的CID码的不需要处理
Console.WriteLine("不是想要的警报信息,设备号:" + deviceID + ",CID:" + CID);
return;
}
UdpAlarmHostMessage alarm = new()
{
DeviceID = deviceID,
Ip = IP,
GroupID = ByteToInt(msg, 9),
UserID = ByteToInt(msg, 13),
AlarmTime = alarmTime,
//CID暂定
CID = CID,
LinkOut = msg[27] + msg[28] * 256,
ChannelNum = channelNum,
SubChannelNum = msg[31] + msg[32] * 256,
ExtendArgs = msg[33].ToString("X2") + " " + msg[34].ToString("X2") + " " + msg[35].ToString("X2"),
AlarmLevel = arrlist.Rows[0]["level"].ToString(),
AlarmContent = arrlist.Rows[0]["content"].ToString(),
AlarmRemarks = arrlist.Rows[0]["remarks"].ToString(),
AlarmType = arrlist.Rows[0]["type"].ToString(),
Linklist = new()
};
//string error = "";
//alarm.linklist = DBCenter.center.SearchByConditionJArray("table_UDPLink", "deviceID=" + alarm.deviceID + "/channel='" + alarm.channelNum + "'", ref error);
if (alarm.Linklist == null || alarm.Linklist.Count == 0)
{
alarm.IsLinked = false;
}
else
{
alarm.IsLinked = true;
}
ProcessAlarm(alarm);
}
//处理报警事件
private void ProcessAlarm(UdpAlarmHostMessage msg)
{
OnUdpAlarmEvent(msg);
////报警信息放入数据库
//JObject obj = new()
//{
// { "alarmTime", msg.AlarmTime },
// { "CID", msg.CID },
// { "deviceID", msg.DeviceID },
// { "channelNum", msg.ChannelNum },
// { "subChannelNum", msg.SubChannelNum },
// { "IP", msg.Ip },
// { "groupID", msg.GroupID },
// { "userID", msg.UserID },
// { "linkOut", msg.LinkOut },
// { "extendArgs", msg.ExtendArgs },
// { "alarm_level", msg.AlarmLevel },
// { "alarm_content", msg.AlarmContent },
// { "alarm_remarks", msg.AlarmRemarks },
// { "alarm_type", msg.AlarmType },
// { "IsLinked", msg.IsLinked },
// { "linklist", msg.Linklist }
//};
//string error = "";
//DBCenter.center.InsertResult("table_UDPAlarmMessage", obj, ref error);
////打开预览窗口
//if (msg.IsLinked)
//{
// if (OnUdpAlarmEvent != null)
// {
// OnUdpAlarmEvent(msg);
// }
// //联动预置位
// for (int i = 0; i < msg.Linklist.Count; i++)
// {
// if (msg.Linklist[i]["needPreset"].ToString() == "true")
// {
// //int camID = int.Parse(msg.linklist[i]["camID"].ToString());
// //string camType = msg.linklist[i]["camType"].ToString();
// //CamType device_type = CamType.Table;
// //if (camType == "摄像机") device_type = CamType.Camera;
// //int presetId = int.Parse(msg.linklist[i]["presetID"].ToString());
// //RequestToService.center.NET_SDK_PTZPreset_Other(camID, device_type, (int)WMPTZPresetCommand.WMPTZPreset_GOTO, presetId, ref error);
// }
// }
//}
}
private string getCID(byte bytes)
{
switch (bytes)
{
case 0x00:
return "0";
case 0x01:
return "1";
case 0x02:
return "2";
case 0x03:
return "3";
case 0x04:
return "4";
case 0x05:
return "5";
case 0x06:
return "6";
case 0x07:
return "7";
case 0x08:
return "8";
case 0x09:
return "9";
case 0x0A:
return "A";
case 0x0B:
return "B";
case 0x0C:
return "C";
case 0x0D:
return "D";
case 0x0E:
return "E";
case 0x0F:
return "F";
default:
return "0";
}
}
private string getBCD(byte bytes)
{
int num = (bytes >> 4) * 10 + (bytes & 0x0F);
return num.ToString();
}
private byte getBCDByte(int num)
{
if (num >= 100) num = num % 100;
int hex = num / 10;
int lex = num % 10;
return (byte)(hex * 16 + lex);
}
private byte[] getBCDTime(DateTime time)
{
return new byte[] { getBCDByte(time.Year),getBCDByte((int)time.DayOfWeek),getBCDByte(time.Month),getBCDByte(time.Day),
getBCDByte(time.Hour),getBCDByte(time.Minute),getBCDByte(time.Second) };
}
private string getBCD2(byte bytes)
{
int num1 = bytes / 16;
int num2 = bytes % 16;
return (num1 * 10 + num2).ToString();
}
private void analysisAllSectorMessage(string IP, byte[] msg)
{
int deviceID = ByteToInt(msg, 5);
UdpAlarmHostDevice device = getDevice(deviceID);
if (device == null)
{
device = new UdpAlarmHostDevice();
device.deviceID = deviceID;
device.IP = IP;
device.deviceOnlineState = 1;
device.keep_live = keep_alive;
deviceList.Add(device);
}
device.IP = IP;
device.groupID = ByteToInt(msg, 9);
device.userID = ByteToInt(msg, 13);
if (device.sectorList == null)
{
device.sectorList = new List<SectorState>();
}
int count = msg[19];
for (int i = 0; i < count; i++)
{
int index = i + msg[20];//防区序号
int pos = 21 + i;//防区信息所在byte数组未知
SectorState state = new SectorState(index, msg[pos]);
updateSector(state, device.sectorList, device.deviceID);
}
}
private void updateSector(SectorState state, List<SectorState> list, int deviceId)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].id == state.id)
{
//设备离线
if (list[i].state != state.state)
{
reportSectorState(deviceId, state.id, state.state);
}
list[i] = state; //防区存在,更新
return;
}
}
list.Add(state);//防区不存在,添加
reportSectorState(deviceId, state.id, state.state);
}
private void reportSectorState(int deviceId, int channel, int state)
{
if (OnUdpAlarmSectionState != null)
{
switch (state)
{
case 0:
OnUdpAlarmSectionState(deviceId, channel, "防区未使用");
break;
case 1://撤防
OnUdpAlarmSectionState(deviceId, channel, "防区撤防");
break;
case 2://布防
OnUdpAlarmSectionState(deviceId, channel, "防区布防");
break;
case 3://旁路
OnUdpAlarmSectionState(deviceId, channel, "防区旁路");
break;
case 4://报警
OnUdpAlarmSectionState(deviceId, channel, "防区报警");
break;
case 5://无线防区欠压
OnUdpAlarmSectionState(deviceId, channel, "无线防区欠压");
break;
case 6://防区掉线
OnUdpAlarmSectionState(deviceId, channel, "防区掉线(与主线总线脱离)");
break;
case 7://未准备就绪
OnUdpAlarmSectionState(deviceId, channel, "未准备就绪");
break;
}
}
}
private void analysisSectorMessage(string IP, byte[] msg)
{
//东北没有张力防区,暂不解析
}
private void analysisMaxSectorMessage(string IP, byte[] msg)
{
int deviceID = ByteToInt(msg, 5);
UdpAlarmHostDevice device = getDevice(deviceID);
if (device == null)
{
device = new UdpAlarmHostDevice();
device.deviceID = deviceID;
device.IP = IP;
device.deviceOnlineState = 1;
device.keep_live = keep_alive;
deviceList.Add(device);
}
device.IP = IP;
device.groupID = ByteToInt(msg, 9);
device.userID = ByteToInt(msg, 13);
device.maxSectorNum = msg[17] * 256 + msg[18];
}
private bool checkDevice(UdpAlarmHostDevice device, ref string error)
{
if (device == null)
{
error = "没有此报警主机的记录";
return false;
}
if (device.deviceOnlineState == 0)
{
error = "此报警主机离线";
return false;
}
if (myUdp == null)
{
error = "UDP故障";
return false;
}
return true;
}
//外出布防或者布防
public bool setDeviceDefence(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x60 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//立即布防
public bool setDeviceDefenceImmediately(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x62 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//在家布防留守布防
public bool setDeviceDefenceHome(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x63 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//即时留守布防
public bool setDeviceDefenceHomeImmediately(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x64 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//撤防
public bool withdrawDeviceDefence(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x61 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//清除报警记忆(复位)
public bool clearDeviceDefence(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0x80, new byte[] { 0x65 });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//校对系统时间
public bool setDeviceTime(int deviceID, DateTime time, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] content = getBCDTime(time);
byte[] bytes = AlarmEncode.getSendMessage(0x8D, content);
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//设备重启
public bool rebootDevice(int deviceID, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0xA0, null);
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//单防区布防
public bool setDeviceChannelDefence(int deviceID, int channel, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0xC0, new byte[] { (byte)(channel / 256), (byte)(channel % 256) });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//单防区撤防
public bool withdrawDeviceChannelDefence(int deviceID, int channel, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0xC1, new byte[] { (byte)(channel / 256), (byte)(channel % 256) });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//单防区旁路
public bool setDeviceChannelByway(int deviceID, int channel, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0xC2, new byte[] { (byte)(channel / 256), (byte)(channel % 256) });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
//单防区旁路恢复
public bool withdrawDeviceChannelByway(int deviceID, int channel, ref string error)
{
UdpAlarmHostDevice device = getDevice(deviceID);
if (checkDevice(device, ref error))
{
byte[] bytes = AlarmEncode.getSendMessage(0xC3, new byte[] { (byte)(channel / 256), (byte)(channel % 256) });
return myUdp.SendMessage(AlarmEncode.encodeMessage(bytes), device.IP, udp_sendPort);
}
else
{
return false;
}
}
}

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

@ -1,4 +1,5 @@
using System;
using JiLinApp.Docking.FenceAlarm;
using System;
using System.Windows;
using System.Windows.Controls;
@ -30,8 +31,8 @@ public partial class Main : UserControl
MainViewModel vm = DataContext as MainViewModel;
vm.SetView(this);
Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState;
Manager.OnUdpAlarmSectionState += vm.OnUdpAlarmSectionState;
//Manager.OnUdpAlarmDeviceState += vm.OnUdpAlarmDeviceState;
//Manager.OnUdpAlarmSectionState += vm.OnUdpAlarmSectionState;
Manager.OnUdpAlarmEvent += vm.OnUdpAlarmEvent;
}
}
@ -76,18 +77,17 @@ public partial class Main : UserControl
}
private void StopBtn_Click(object sender, RoutedEventArgs e)
{
try
{
Manager.StopServer();
ChangeState(false);
}
#endregion ElementEvent
#region InvokeEvent
public void Test()
catch (Exception)
{
throw;
}
ChangeState(false);
}
#endregion InvokeEvent
#endregion ElementEvent
}

6
JiLinApp/Pages/FenceServerManage/MainViewModel.cs

@ -1,4 +1,5 @@
using JiLinApp.Mvvm;
using JiLinApp.Docking.FenceAlarm;
using JiLinApp.Mvvm;
using JiLinApp.Pages.Main;
using Prism.Events;
using Prism.Regions;
@ -7,7 +8,7 @@ namespace JiLinApp.Pages.FenceServerManage;
public class MainViewModel : ViewModelBase
{
#region fields
#region Fields
private Main View { get; set; }
@ -20,7 +21,6 @@ public class MainViewModel : ViewModelBase
public override void SetView(object view)
{
View = (Main)view;
View.Test();
}
#region ConnEvent

4
JiLinApp/Pages/Main/Core/MessageEvent.cs

@ -1,5 +1,5 @@
using JiLinApp.Pages.FenceServerManage;
using JiLinApp.Pages.ShakeServerManage;
using JiLinApp.Docking.FenceAlarm;
using JiLinApp.Docking.VibrateAlarm;
using Prism.Events;
namespace JiLinApp.Pages.Main;

4
JiLinApp/Pages/Main/MainWindow.xaml

@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fenceManage="clr-namespace:JiLinApp.Pages.FenceServerManage"
xmlns:ptzManage="clr-namespace:JiLinApp.Pages.PtzManage"
xmlns:shakeManage="clr-namespace:JiLinApp.Pages.ShakeServerManage"
xmlns:vibrateManage="clr-namespace:JiLinApp.Pages.VibrateServerManage"
Title="{Binding Title}" Width="1000" Height="700">
<materialDesign:Card materialDesign:ColorZoneAssist.Mode="PrimaryMid">
<TabControl Style="{StaticResource MaterialDesignNavigationRailTabControl}" TabStripPlacement="Top">
@ -24,7 +24,7 @@
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="震动报警服务" />
</StackPanel>
</TabItem.Header>
<shakeManage:Main materialDesign:ColorZoneAssist.Mode="PrimaryLight" Margin="10"></shakeManage:Main>
<vibrateManage:Main materialDesign:ColorZoneAssist.Mode="PrimaryLight" Margin="10"></vibrateManage:Main>
</TabItem>
<TabItem Width="auto" Margin="5 0 5 0">
<TabItem.Header>

242
JiLinApp/Pages/PtzManage/Core/PelcoD.cs

@ -1,242 +0,0 @@
using System;
namespace JiLinApp.Pages.PtzManage;
public class PelcoD
{
private string watchdir = ""; //监控方向
private static readonly byte STX = 0xFF; //同步字节
#region 监控方向和定时监控实体
public string WatchDir
{
get { return watchdir; }
set { watchdir = value; }
}
#endregion 监控方向和定时监控实体
#region 基本指令定义
#region 指令码1
private const byte FocusNear = 0x01; //增加聚焦
private const byte IrisOpen = 0x02; //减小光圈
private const byte IrisClose = 0x04; //增加光圈
private const byte CameraOnOff = 0x08; //摄像机打开和关闭
private const byte AutoManualScan = 0x10; //自动和手动扫描
private const byte Sense = 0x80; //Sence码
#endregion 指令码1
#region 指令码2
private const byte PanRight = 0x02; //右
private const byte PanLeft = 0x04; //左
private const byte TiltUp = 0x08; //上
private const byte TiltDown = 0x10; //下
private const byte ZoomTele = 0x20; //增加对焦
private const byte ZoomWide = 0x40; //减小对焦
private const byte FocusFar = 0x80; //减小聚焦
#endregion 指令码2
#region 镜头左右平移的速度
public static byte PanSpeedMin = 0x00; //停止
public static byte PanSpeedMax = 0x3F; //最高速
#endregion 镜头左右平移的速度
#region 镜头上下移动的速度
public static byte TiltSpeedMin = 0x00; //停止
public static byte TiltSpeedMax = 0x3F; //最高速
#endregion 镜头上下移动的速度
#endregion 基本指令定义
private const byte PanRightUp = 0xa; //右上
private const byte PanLeftUp = 0x0c; //左上
private const byte PanRightDown = 0x12; //右下
private const byte PanLeftDown = 0x14; //左下
#region 云台控制枚举
public enum Switch
{
On = 0x01,
Off = 0x02
} //雨刷控制
public enum Focus
{
Near = FocusNear,
Far = FocusFar
} //聚焦控制
public enum Zoom
{
Wide = ZoomWide,
Tele = ZoomTele
} //对焦控制
public enum Tilt
{
Up = TiltUp,
Down = TiltDown
} //上下控制
public enum Pan
{
Left = PanLeft,
Right = PanRight,
LeftUp = PanLeftUp,
LeftDown = PanLeftDown,
RightUp = PanRightUp,
RightDown = PanRightDown
} //左右控制
public enum Scan
{
Auto,
Manual
} //自动和手动控制
public enum Iris
{
Open = IrisOpen,
Close = IrisClose
} //光圈控制
public enum PresetAction
{
Set = 0x03,
Clear = 0x05,
Goto = 0x07
}
#endregion 云台控制枚举
#region 云台控制方法
//雨刷控制
public static byte[] CameraSwitch(uint deviceAddress, Switch action)
{
byte m_action = CameraOnOff;
if (action == Switch.On)
m_action = CameraOnOff + Sense;
return Message.GetMessage(deviceAddress, m_action, 0x00, 0x00, 0x00);
}
//光圈控制
public static byte[] CameraIrisSwitch(uint deviceAddress, Iris action)
{
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
}
//聚焦控制
public static byte[] CameraFocus(uint deviceAddress, Focus action)
{
if (action == Focus.Near)
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
else
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, 0x00);
}
//对焦控制
public static byte[] CameraZoom(uint deviceAddress, Zoom action)
{
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, 0x00);
}
/// <summary>
/// 上下控制
/// </summary>
/// <param name="deviceAddress"></param>
/// <param name="action"></param>
/// <param name="speed"></param>
/// <returns></returns>
public static byte[] CameraTilt(uint deviceAddress, Tilt action, uint speed)
{
if (speed < TiltSpeedMin)
speed = TiltSpeedMin;
if (speed > TiltSpeedMax)
speed = TiltSpeedMax;
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, (byte)speed);
}
/// <summary>
/// 左右控制
/// </summary>
/// <param name="deviceAddress"></param>
/// <param name="action"></param>
/// <param name="speed"></param>
/// <returns></returns>
public static byte[] CameraPan(uint deviceAddress, Pan action, uint speed)
{
if (speed < PanSpeedMin)
speed = PanSpeedMin;
if (speed > PanSpeedMax)
speed = PanSpeedMax;
return Message.GetMessage(deviceAddress, 0x00, (byte)action, (byte)speed, 0x00);
}
//停止云台的移动
public static byte[] CameraStop(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x00, 0x00, 0x00);
}
//自动和手动控制
public static byte[] CameraScan(uint deviceAddress, Scan scan)
{
byte m_byte = AutoManualScan;
if (scan == Scan.Auto)
m_byte = AutoManualScan + Sense;
return Message.GetMessage(deviceAddress, m_byte, 0x00, 0x00, 0x00);
}
public static byte[] Preset(uint deviceAddress, PresetAction action, byte presetId)
{
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, presetId);
}
#endregion 云台控制方法
public struct Message
{
public static byte Address;
public static byte CheckSum;
public static byte Command1,
Command2,
Data1,
Data2;
public static byte[] GetMessage(
uint address,
byte command1,
byte command2,
byte data1,
byte data2
)
{
if (address < 1 & address > 256)
throw new Exception("Pelco D协议只支持256设备");
Address = byte.Parse(address.ToString());
Command1 = command1;
Command2 = command2;
Data1 = data1;
Data2 = data2;
CheckSum = (byte)(Address + Command1 + Command2 + Data1 + Data2);
return new byte[] { STX, Address, Command1, Command2, Data1, Data2, CheckSum };
}
}
}

364
JiLinApp/Pages/PtzManage/Core/PelcoP.cs

@ -1,364 +0,0 @@
using System;
namespace JiLinApp.Pages.PtzManage;
/// <summary>
/// dot.NET Implementation of Pelco P Protocol
/// </summary>
public class PelcoP
{
private const byte STX = 0xA0;
private const byte ETX = 0xAF;
#region Pan and Tilt Commands
#region Data1
private const byte FocusFar = 0x01;
private const byte FocusNear = 0x02;
private const byte IrisOpen = 0x04;
private const byte IrisClose = 0x08;
private const byte CameraOnOff = 0x10;
private const byte AutoscanOn = 0x20;
private const byte CameraOn = 0x40;
#endregion Data1
#region Data2
private const byte PanRight = 0x02;
private const byte PanLeft = 0x04;
private const byte TiltUp = 0x08;
private const byte TiltDown = 0x10;
private const byte ZoomTele = 0x20;
private const byte ZoomWide = 0x40;
#endregion Data2
#region Data3
public static byte PanSpeedMin = 0x00;
public static byte PanSpeedMax = 0x3F;
#endregion Data3
#region Data4
public static byte TiltSpeedMin = 0x00;
public static byte TiltSpeedMax = 0x3F;
#endregion Data4
#endregion Pan and Tilt Commands
#region Enums
public enum PatternAction
{
Start,
Stop,
Run
}
public enum Action
{
Start,
Stop
}
public enum LensSpeed
{
Low = 0x00,
Medium = 0x01,
High = 0x02,
Turbo = 0x03
}
public enum Pan
{
Left = PanLeft,
Right = PanRight
}
public enum Tilt
{
Up = TiltUp,
Down = TiltDown
}
public enum Iris
{
Open = IrisOpen,
Close = IrisClose
}
public enum Zoom
{
Wide = ZoomWide,
Tele = ZoomTele
}
public enum Switch
{
On,
Off
}
public enum Focus
{
Near = FocusNear,
Far = FocusFar
}
public enum PresetAction
{
Set = 0x03,
Clear = 0x05,
Goto = 0x07
}
#endregion Enums
#region Extended Command Set
public static byte[] Preset(uint deviceAddress, PresetAction action, byte presetId)
{
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, presetId);
}
public static byte[] Flip(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x07, 0x00, 0x21);
}
public static byte[] ZeroPanPosition(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x07, 0x00, 0x22);
}
public static byte[] AutoScan(uint deviceAddress, Action action)
{
byte m_action;
if (action == Action.Start)
m_action = 0x09;
else
m_action = 0x0B;
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
}
public static byte[] RemoteReset(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x0F, 0x00, 0x00);
}
public static byte[] Zone(uint deviceAddress, byte zone, Action action)
{
if (zone < 0x01 & zone > 0x08)
throw new Exception("Zone value should be between 0x01 and 0x08 include");
byte m_action;
if (action == Action.Start)
m_action = 0x11;
else
m_action = 0x13;
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, zone);
}
public static byte[] WriteToScreen(uint deviceAddress, string text)
{
if (text.Length > 40)
text = text.Remove(40, text.Length - 40);
System.Text.Encoding encoding = System.Text.Encoding.ASCII;
byte[] m_bytes = new byte[encoding.GetByteCount(text) * 8];
int i = 0;
byte m_scrPosition;
byte m_ASCIIchr;
foreach (char ch in text)
{
m_scrPosition = Convert.ToByte(i / 8);
m_ASCIIchr = Convert.ToByte(ch);
Array.Copy(
Message.GetMessage(deviceAddress, 0x00, 0x15, m_scrPosition, m_ASCIIchr),
0,
m_bytes,
i,
8
);
i = i + 8;
}
return m_bytes;
}
public static byte[] ClearScreen(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x17, 0x00, 0x00);
}
public static byte[] AlarmAcknowledge(uint deviceAddress, uint alarmID)
{
if (alarmID < 1 & alarmID > 8)
throw new Exception("Only 8 alarms allowed for Pelco P implementation");
return Message.GetMessage(deviceAddress, 0x00, 0x19, 0x00, Convert.ToByte(alarmID));
}
public static byte[] ZoneScan(uint deviceAddress, Action action)
{
byte m_action;
if (action == Action.Start)
m_action = 0x1B;
else
m_action = 0x1D;
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
}
public static byte[] Pattern(uint deviceAddress, PatternAction action)
{
byte m_action;
switch (action)
{
case PatternAction.Start:
m_action = 0x1F;
break;
case PatternAction.Stop:
m_action = 0x21;
break;
case PatternAction.Run:
m_action = 0x23;
break;
default:
m_action = 0x23;
break;
}
return Message.GetMessage(deviceAddress, 0x00, m_action, 0x00, 0x00);
}
public static byte[] SetZoomLensSpeed(uint deviceAddress, LensSpeed speed)
{
return Message.GetMessage(deviceAddress, 0x00, 0x25, 0x00, (byte)speed);
}
public static byte[] SetFocusLensSpeed(uint deviceAddress, LensSpeed speed)
{
return Message.GetMessage(deviceAddress, 0x00, 0x27, 0x00, (byte)speed);
}
#endregion Extended Command Set
#region Base Command Set
public static byte[] CameraSwitch(uint deviceAddress, Switch action)
{
byte m_action = CameraOnOff;
if (action == Switch.On)
m_action += CameraOnOff; //Maybe wrong !!!
return Message.GetMessage(deviceAddress, m_action, 0x00, 0x00, 0x00);
}
public static byte[] CameraIrisSwitch(uint deviceAddress, Iris action)
{
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
}
public static byte[] CameraFocus(uint deviceAddress, Focus action)
{
return Message.GetMessage(deviceAddress, (byte)action, 0x00, 0x00, 0x00);
}
public static byte[] CameraZoom(uint deviceAddress, Zoom action)
{
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, 0x00);
}
public static byte[] CameraTilt(uint deviceAddress, Tilt action, uint speed)
{
if (speed < TiltSpeedMin)
speed = TiltSpeedMin;
if (speed > TiltSpeedMax)
speed = TiltSpeedMax;
return Message.GetMessage(deviceAddress, 0x00, (byte)action, 0x00, (byte)speed);
}
public static byte[] CameraPan(uint deviceAddress, Pan action, uint speed)
{
if (speed < PanSpeedMin)
speed = PanSpeedMin;
if (speed > PanSpeedMax)
speed = PanSpeedMax;
return Message.GetMessage(deviceAddress, 0x00, (byte)action, (byte)speed, 0x00);
}
public static byte[] CameraPanTilt(
uint deviceAddress,
Pan panAction,
uint panSpeed,
Tilt tiltAction,
uint tiltSpeed
)
{
byte[] m_bytes = new byte[8];
byte[] m_tiltMessage = CameraTilt(deviceAddress, tiltAction, tiltSpeed);
byte[] m_panMessage = CameraPan(deviceAddress, panAction, panSpeed);
//m_tiltMessage.CopyTo(m_bytes,0);
//m_panMessage.CopyTo(m_bytes,9);
/*m_bytes[0] = m_tiltMessage[0];
m_bytes[1] = m_tiltMessage[1];
m_bytes[2] = m_tiltMessage[2];
m_bytes[3] = (byte)(m_tiltMessage[3]+m_panMessage[3]);
m_bytes[4] = (byte)(+m_panMessage[4]);
m_bytes[5] = (byte)(+m_panMessage[5]);
m_bytes[6] = m_tiltMessage[6];
m_bytes[7] = m_tiltMessage[7];*/
m_bytes = Message.GetMessage(
deviceAddress,
0x00,
(byte)(m_tiltMessage[3] + m_panMessage[3]),
m_panMessage[4],
m_tiltMessage[5]
);
return m_bytes;
}
public static byte[] CameraStop(uint deviceAddress)
{
return Message.GetMessage(deviceAddress, 0x00, 0x00, 0x00, 0x00);
}
#endregion Base Command Set
public struct Message
{
public static byte Address;
public static byte CheckSum;
public static byte Data1,
Data2,
Data3,
Data4;
public static byte[] GetMessage(
uint address,
byte data1,
byte data2,
byte data3,
byte data4
)
{
if (address < 0 & address > 32)
throw new Exception("Protocol Pelco P support 32 devices only");
Address = byte.Parse((address - 1).ToString());
Data1 = data1;
Data2 = data2;
Data3 = data3;
Data4 = data4;
CheckSum = (byte)(STX ^ Address ^ Data1 ^ Data2 ^ Data3 ^ Data4 ^ ETX);
return new byte[] { STX, Address, Data1, Data2, Data3, Data4, ETX, CheckSum };
}
}
}

191
JiLinApp/Pages/PtzManage/Core/PtzCmd.cs

@ -1,191 +0,0 @@
using EC.Util.CameraSDK;
using System;
namespace JiLinApp.Pages.PtzManage;
public class PtzCmd
{
public static PtzControlType GetControlType(string ctrlStr)
{
return ctrlStr switch
{
"PelcoD" => PtzControlType.PelcoD,
"PelcoP" => PtzControlType.PelcoP,
"HikSdk" => PtzControlType.HikSdk,
_ => PtzControlType.None
};
}
public static PtzCmdType GetCmdType(string cmdStr)
{
return cmdStr switch
{
"Top" => PtzCmdType.Top,
"Down" => PtzCmdType.Down,
"Left" => PtzCmdType.Left,
"Right" => PtzCmdType.Right,
"TopLeft" => PtzCmdType.TopLeft,
"TopRight" => PtzCmdType.TopRight,
"DownLeft" => PtzCmdType.DownLeft,
"DownRight" => PtzCmdType.DownRight,
"Stop" => PtzCmdType.Stop,
"AutoStart" => PtzCmdType.AutoStart,
"AutoStop" => PtzCmdType.AutoStop,
"PresetSet" => PtzCmdType.PresetSet,
"PresetClear" => PtzCmdType.PresetClear,
"PresetGoto" => PtzCmdType.PresetGoto,
_ => PtzCmdType.None
};
}
public static byte[] GetCmd(PtzControlType ctrlType, PtzCmdType cmdType, byte[] args = null)
{
args ??= new byte[] { 1, 1, 1 };
byte[] cmd = ctrlType switch
{
PtzControlType.PelcoD => GetPelcoDCmd(cmdType, args),
PtzControlType.PelcoP => GetPelcoPCmd(cmdType, args),
_ => Array.Empty<byte>(),
};
return cmd;
}
public static byte[] GetPelcoDCmd(PtzCmdType cmdType, byte[] args)
{
uint addr = args[0];
uint panSpeed = 0x2f;
uint tiltSpeed = (uint)(PelcoD.TiltSpeedMax + PelcoD.TiltSpeedMin) / 2;
byte[] cmd = cmdType switch
{
PtzCmdType.Top => PelcoD.CameraTilt(addr, PelcoD.Tilt.Up, tiltSpeed),
PtzCmdType.Down => PelcoD.CameraTilt(addr, PelcoD.Tilt.Down, tiltSpeed),
PtzCmdType.Left => PelcoD.CameraPan(addr, PelcoD.Pan.Left, panSpeed),
PtzCmdType.Right => PelcoD.CameraPan(addr, PelcoD.Pan.Right, panSpeed),
PtzCmdType.TopLeft => PelcoD.CameraPan(addr, PelcoD.Pan.LeftUp, panSpeed),
PtzCmdType.TopRight => PelcoD.CameraPan(addr, PelcoD.Pan.RightUp, panSpeed),
PtzCmdType.DownLeft => PelcoD.CameraPan(addr, PelcoD.Pan.LeftDown, panSpeed),
PtzCmdType.DownRight => 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.PresetGoto => PelcoD.Preset(addr, PelcoD.PresetAction.Goto, args[1]),
PtzCmdType.None => Array.Empty<byte>(),
_ => Array.Empty<byte>(),
};
return cmd;
}
public static byte[] GetPelcoPCmd(PtzCmdType cmdType, byte[] args)
{
uint addr = args[0];
uint panSpeed = (uint)(PelcoP.PanSpeedMax + PelcoP.PanSpeedMin) / 2;
uint tiltSpeed = (uint)(PelcoP.TiltSpeedMax + PelcoP.TiltSpeedMin) / 2;
byte[] cmd = cmdType switch
{
PtzCmdType.Top => PelcoP.CameraTilt(addr, PelcoP.Tilt.Up, tiltSpeed),
PtzCmdType.Down => PelcoP.CameraTilt(addr, PelcoP.Tilt.Down, tiltSpeed),
PtzCmdType.Left => PelcoP.CameraPan(addr, PelcoP.Pan.Left, panSpeed),
PtzCmdType.Right => PelcoP.CameraPan(addr, PelcoP.Pan.Right, panSpeed),
PtzCmdType.TopLeft => PelcoP.CameraPanTilt(addr, PelcoP.Pan.Left, panSpeed, PelcoP.Tilt.Up, tiltSpeed),
PtzCmdType.TopRight => PelcoP.CameraPanTilt(addr, PelcoP.Pan.Right, panSpeed, PelcoP.Tilt.Up, tiltSpeed),
PtzCmdType.DownLeft => PelcoP.CameraPanTilt(addr, PelcoP.Pan.Left, panSpeed, PelcoP.Tilt.Down, tiltSpeed),
PtzCmdType.DownRight => 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.PresetGoto => PelcoP.Preset(addr, PelcoP.PresetAction.Goto, args[1]),
PtzCmdType.None => Array.Empty<byte>(),
_ => Array.Empty<byte>(),
};
return cmd;
}
public static void HikPtzMove(ref HiKSDK sdk, PtzCmdType cmdType, uint[] args)
{
if (sdk == null || args == null) return;
uint[] arr = new uint[args.Length + 1];
args.CopyTo(arr, 1);
switch (cmdType)
{
case PtzCmdType.Top:
arr[0] = HiKOriSDK.TILT_UP;
sdk.PtzMove(arr);
break;
case PtzCmdType.Down:
arr[0] = HiKOriSDK.TILT_DOWN;
sdk.PtzMove(arr);
break;
case PtzCmdType.Left:
arr[0] = HiKOriSDK.PAN_LEFT;
sdk.PtzMove(arr);
break;
case PtzCmdType.Right:
arr[0] = HiKOriSDK.PAN_RIGHT;
sdk.PtzMove(arr);
break;
case PtzCmdType.TopLeft:
arr[0] = HiKOriSDK.UP_LEFT;
sdk.PtzMove(arr);
break;
case PtzCmdType.TopRight:
arr[0] = HiKOriSDK.UP_RIGHT;
sdk.PtzMove(arr);
break;
case PtzCmdType.DownLeft:
arr[0] = HiKOriSDK.DOWN_LEFT;
sdk.PtzMove(arr);
break;
case PtzCmdType.DownRight:
arr[0] = HiKOriSDK.DOWN_RIGHT;
sdk.PtzMove(arr);
break;
case PtzCmdType.AutoStart:
arr[0] = HiKOriSDK.PAN_AUTO;
sdk.PtzMove(arr);
break;
case PtzCmdType.PresetGoto:
arr[0] = HiKOriSDK.GOTO_PRESET;
sdk.PtzPreset(arr);
break;
default:
break;
}
}
}
public enum PtzControlType
{
PelcoD,
PelcoP,
HikSdk,
None
}
public enum PtzCmdType
{
Top,
Down,
Left,
Right,
TopLeft,
TopRight,
DownLeft,
DownRight,
Stop,
AutoStart,
AutoStop,
PresetSet,
PresetClear,
PresetGoto,
None
}

1
JiLinApp/Pages/PtzManage/Main.xaml

@ -97,6 +97,7 @@
<ComboBox Name="ControlType" materialDesign:HintAssist.Hint="控制类型" Width="200" SelectionChanged="ControlType_SelectionChanged" Style="{StaticResource MaterialDesignOutlinedComboBox}">
<ComboBoxItem Content="PelcoD" />
<ComboBoxItem Content="PelcoP" />
<ComboBoxItem Content="DCamera" />
<ComboBoxItem Content="HikSdk" />
</ComboBox>
<ComboBox Name="CameraId" materialDesign:HintAssist.Hint="相机Id" Width="200" Margin="0 10 0 0" SelectedIndex="0" Style="{StaticResource MaterialDesignOutlinedComboBox}">

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

@ -1,7 +1,7 @@
using EC.Util.CameraSDK;
using EC.Util.Port;
using ImTools;
using JiLinApp.Core;
using JiLinApp.Docking.Ptz;
using NewLife.Reflection;
using System;
using System.Collections.Concurrent;
@ -23,13 +23,13 @@ namespace JiLinApp.Pages.PtzManage;
/// </summary>
public partial class Main : UserControl
{
#region fields
#region Fields
private YcSerialPort Port { get; set; }
private ConcurrentDictionary<string, HiKSDK> HikMap { get; } = new();
#endregion fields
#endregion Fields
public Main()
{
@ -41,6 +41,12 @@ public partial class Main : UserControl
private void Init()
{
if (DataContext != null)
{
MainViewModel vm = DataContext as MainViewModel;
vm.SetView(this);
}
// 初始化串口
string[] ports = SerialPort.GetPortNames();
ports = ports.OrderBy(s => int.Parse(Regex.Match(s, @"\d+").Value)).ToArray();
@ -50,7 +56,7 @@ public partial class Main : UserControl
}
// 初始化下拉框 Id
for (int i = 1; i <= 10; i++)
for (int i = 1; i <= 5; i++)
{
CameraId.Items.Add(new ComboBoxItem { Content = i });
PresetId.Items.Add(new ComboBoxItem { Content = i });
@ -66,8 +72,7 @@ public partial class Main : UserControl
}
// 解析海康相机
TaskUtil.Run(() => Dispatcher.Invoke(LoadHikCamera));
//Task.Factory.StartNew(() => Dispatcher.Invoke(LoadHikCamera), TaskCreationOptions.LongRunning);
TaskUtil.RunCatch(() => Dispatcher.Invoke(LoadHikCamera));
// 刷新控件状态
ControlType.SelectedIndex = 0;
@ -117,7 +122,7 @@ public partial class Main : UserControl
{
Port = null;
MessageBox.Show(ex.ToString());
return;
throw;
}
}
ChangeState(true);
@ -144,8 +149,14 @@ public partial class Main : UserControl
case PtzControlType.PelcoP:
if (!IsConnect()) break;
byte cameraId = byte.Parse(CameraId.Text);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new byte[] { cameraId });
Port.SendHex(cmd);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId });
if (cmd != null && cmd.Length > 0) Port.SendHex(cmd);
break;
case PtzControlType.DCamera:
if (!IsConnect()) break;
cmd = PtzCmd.GetCmd(ctrlType, cmdType);
if (cmd != null && cmd.Length > 0) Port.SendHex(cmd);
break;
case PtzControlType.HikSdk:
@ -171,8 +182,8 @@ public partial class Main : UserControl
if (!IsConnect()) break;
cmdType = PtzCmd.GetCmdType("Stop");
byte cameraId = byte.Parse(CameraId.Text);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new byte[] { cameraId });
Port.SendHex(cmd);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId });
if (cmd != null && cmd.Length > 0) Port.SendHex(cmd);
break;
case PtzControlType.HikSdk:
@ -200,8 +211,8 @@ public partial class Main : UserControl
case PtzControlType.PelcoP:
if (!IsConnect()) break;
byte cameraId = byte.Parse(CameraId.Text);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new byte[] { cameraId, presetId });
Port.SendHex(cmd);
byte[] cmd = PtzCmd.GetCmd(ctrlType, cmdType, new object[] { cameraId, presetId });
if (cmd != null && cmd.Length > 0) Port.SendHex(cmd);
break;
case PtzControlType.HikSdk:
@ -248,6 +259,9 @@ public partial class Main : UserControl
public void GotoPreset()
{
GotoBtn_Click(null, null);
int index = PresetId.SelectedIndex;
index = (index + 1) % PresetId.Items.Count;
PresetId.SelectedIndex = index;
}
#endregion InvokeEvent

53
JiLinApp/Pages/PtzManage/MainViewModel.cs

@ -1,12 +1,9 @@
using JiLinApp.Core;
using JiLinApp.Docking;
using JiLinApp.Biz.Transmit;
using JiLinApp.Core;
using JiLinApp.Docking.FenceAlarm;
using JiLinApp.Docking.VibrateAlarm;
using JiLinApp.Mvvm;
using JiLinApp.Pages.FenceServerManage;
using JiLinApp.Pages.Main;
using JiLinApp.Pages.ShakeServerManage;
using NetMQ;
using NetMQ.Sockets;
using NewLife.Serialization;
using Prism.Events;
using Prism.Regions;
@ -14,21 +11,18 @@ namespace JiLinApp.Pages.PtzManage;
public class MainViewModel : ViewModelBase
{
#region fields
#region Fields
private Main View { get; set; }
private readonly AppConfig AppConfig;
private AppConfig AppConfig { get; set; }
private readonly PublisherSocket AlarmPubSocket;
#endregion fields
#endregion Fields
public MainViewModel(IRegionManager region, IEventAggregator ea) : base(region, ea)
{
// Bind global fields
AppConfig = Global.AppConfig;
AlarmPubSocket = Global.AlarmPubSocket;
// Bind invoke event
ea.GetEvent<ShakeTcpAlarmSendEvent>().Subscribe(ShakeTcpAlarmReact);
@ -40,39 +34,28 @@ public class MainViewModel : ViewModelBase
View = (Main)view;
}
#region Send
private void SendAlarmToZmq(string msg)
{
AlarmPubSocket.SendMoreFrame(AppConfig.Zmq.AlarmPubTopic).SendFrame(msg);
}
private void SendAlarmToZmq(object obj)
{
AlarmPubSocket.SendMoreFrame(AppConfig.Zmq.AlarmPubTopic).SendFrame(obj.ToJson());
}
#endregion Send
#region InvokeEvent
internal void ShakeTcpAlarmReact(TcpAlarmHostMessage msg)
{
TaskUtil.Run(() =>
{
SendAlarmToZmq(msg.ToAlarmMessage());
SendAlarm(msg.ToAlarmMessage());
View.GotoPreset();
});
}
internal void FenceUdpAlarmReact(UdpAlarmHostMessage msg)
{
TaskUtil.Run(() =>
{
SendAlarmToZmq(msg.ToAlarmMessage());
SendAlarm(msg.ToAlarmMessage());
View.GotoPreset();
});
}
#endregion InvokeEvent
#region Send
private void SendAlarm(AlarmMessage alarm)
{
//AlarmPubSocket.SendMoreFrame(AppConfig.Zmq.AlarmPubTopic).SendFrame(obj.ToJson());
}
#endregion Send
}

525
JiLinApp/Pages/ShakeServerManage/Core/AsyncTcpServer.cs

@ -1,525 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
namespace JiLinApp.Pages.ShakeServerManage;
public class AsyncTcpServer : IDisposable
{
#region Fields
private TcpListener _listener;
private ConcurrentDictionary<string, TcpClientState> _clients;
private bool _disposed = false;
#endregion Fields
#region Ctors
private byte[] inOptionValues;
/// <summary>
/// 异步TCP服务器
/// </summary>
/// <param name="listenPort">监听的端口</param>
public AsyncTcpServer(int listenPort)
: this(IPAddress.Any, listenPort)
{
uint dummy = 0;
inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
}
/// <summary>
/// 异步TCP服务器
/// </summary>
/// <param name="localEP">监听的终结点</param>
public AsyncTcpServer(IPEndPoint localEP)
: this(localEP.Address, localEP.Port)
{
uint dummy = 0;
inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
}
/// <summary>
/// 异步TCP服务器
/// </summary>
/// <param name="localIPAddress">监听的IP地址</param>
/// <param name="listenPort">监听的端口</param>
public AsyncTcpServer(IPAddress localIPAddress, int listenPort)
{
uint dummy = 0;
inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
Address = localIPAddress;
Port = listenPort;
Encoding = Encoding.Default;
_clients = new ConcurrentDictionary<string, TcpClientState>();
_listener = new TcpListener(Address, Port);
_listener.AllowNatTraversal(true);
}
#endregion Ctors
#region Properties
/// <summary>
/// 服务器是否正在运行
/// </summary>
public bool IsRunning { get; private set; }
/// <summary>
/// 监听的IP地址
/// </summary>
public IPAddress Address { get; private set; }
/// <summary>
/// 监听的端口
/// </summary>
public int Port { get; private set; }
/// <summary>
/// 通信使用的编码
/// </summary>
public Encoding Encoding { get; set; }
#endregion Properties
#region Server
/// <summary>
/// 启动服务器
/// </summary>
/// <returns>异步TCP服务器</returns>
public AsyncTcpServer Start()
{
return Start(30);
}
/// <summary>
/// 启动服务器
/// </summary>
/// <param name="backlog">服务器所允许的挂起连接序列的最大长度</param>
/// <returns>异步TCP服务器</returns>
public AsyncTcpServer Start(int backlog)
{
if (IsRunning) return this;
IsRunning = true;
_listener.Start(backlog);
ContinueAcceptTcpClient(_listener);
return this;
}
/// <summary>
/// 停止服务器
/// </summary>
/// <returns>异步TCP服务器</returns>
public AsyncTcpServer Stop()
{
if (!IsRunning) return this;
try
{
_listener.Stop();
foreach (var client in _clients.Values)
{
client.TcpClient.Client.Disconnect(false);
}
_clients.Clear();
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
catch (SocketException ex)
{
Console.WriteLine("socket错误:" + ex.Message);
}
IsRunning = false;
return this;
}
private void ContinueAcceptTcpClient(TcpListener tcpListener)
{
try
{
tcpListener.BeginAcceptTcpClient(new AsyncCallback(HandleTcpClientAccepted), tcpListener);
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
catch (SocketException ex)
{
Console.WriteLine("socket错误:" + ex.Message);
}
}
#endregion Server
#region Receive
private void HandleTcpClientAccepted(IAsyncResult ar)
{
if (!IsRunning) return;
TcpListener tcpListener;
TcpClient tcpClient;
try
{
tcpListener = (TcpListener)ar.AsyncState;
tcpClient = tcpListener.EndAcceptTcpClient(ar);
tcpClient.Client.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
return;
}
if (!tcpClient.Connected) return;
byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
TcpClientState internalClient = new TcpClientState(tcpClient, buffer);
// add client connection to cache
string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString();
_clients.AddOrUpdate(tcpClientKey, internalClient, (n, o) => { return internalClient; });
RaiseClientConnected(tcpClient);
// begin to read data
NetworkStream networkStream = internalClient.NetworkStream;
ContinueReadBuffer(internalClient, networkStream);
// keep listening to accept next connection
ContinueAcceptTcpClient(tcpListener);
}
private void HandleDatagramReceived(IAsyncResult ar)
{
if (!IsRunning) return;
try
{
TcpClientState internalClient = (TcpClientState)ar.AsyncState;
if (!internalClient.TcpClient.Connected) return;
NetworkStream networkStream = internalClient.NetworkStream;
int numberOfReadBytes = 0;
try
{
// if the remote host has shutdown its connection,
// read will immediately return with zero bytes.
numberOfReadBytes = networkStream.EndRead(ar);
}
catch (Exception ex)
{
Console.WriteLine("错误:" + ex.Message);
numberOfReadBytes = 0;
}
if (numberOfReadBytes == 0)
{
// connection has been closed
TcpClientState internalClientToBeThrowAway;
string tcpClientKey = internalClient.TcpClient.Client.RemoteEndPoint.ToString();
_clients.TryRemove(tcpClientKey, out internalClientToBeThrowAway);
RaiseClientDisconnected(internalClient.TcpClient);
return;
}
// received byte and trigger event notification
byte[] receivedBytes = new byte[numberOfReadBytes];
Buffer.BlockCopy(internalClient.Buffer, 0, receivedBytes, 0, numberOfReadBytes);
RaiseDatagramReceived(internalClient, receivedBytes);
// continue listening for tcp datagram packets
ContinueReadBuffer(internalClient, networkStream);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("错误:" + ex.Message);
}
}
private void ContinueReadBuffer(TcpClientState internalClient, NetworkStream networkStream)
{
try
{
networkStream.BeginRead(internalClient.Buffer, 0, internalClient.Buffer.Length, HandleDatagramReceived, internalClient);
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
}
#endregion Receive
#region Events
/// <summary>
/// 接收到数据报文事件
/// </summary>
public event EventHandler<TcpDatagramReceivedEventArgs<byte[]>> DatagramReceived;
private void RaiseDatagramReceived(TcpClientState sender, byte[] datagram)
{
if (DatagramReceived != null)
{
DatagramReceived(this, new TcpDatagramReceivedEventArgs<byte[]>(sender, datagram));
}
}
/// <summary>
/// 与客户端的连接已建立事件
/// </summary>
public event EventHandler<TcpClientConnectedEventArgs> ClientConnected;
/// <summary>
/// 与客户端的连接已断开事件
/// </summary>
public event EventHandler<TcpClientDisconnectedEventArgs> ClientDisconnected;
private void RaiseClientConnected(TcpClient tcpClient)
{
if (ClientConnected != null)
{
ClientConnected(this, new TcpClientConnectedEventArgs(tcpClient));
}
}
private void RaiseClientDisconnected(TcpClient tcpClient)
{
if (ClientDisconnected != null)
{
ClientDisconnected(this, new TcpClientDisconnectedEventArgs(tcpClient));
}
}
#endregion Events
#region Send
private void GuardRunning()
{
if (!IsRunning)
throw new InvalidProgramException("This TCP server has not been started yet.");
}
/// <summary>
/// 发送报文至指定的客户端
/// </summary>
/// <param name="tcpClient">客户端</param>
/// <param name="datagram">报文</param>
public void Send(TcpClient tcpClient, byte[] datagram)
{
GuardRunning();
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
if (datagram == null)
throw new ArgumentNullException("datagram");
try
{
NetworkStream stream = tcpClient.GetStream();
if (stream.CanWrite)
{
stream.BeginWrite(datagram, 0, datagram.Length, HandleDatagramWritten, tcpClient);
}
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
}
/// <summary>
/// 发送报文至指定的客户端
/// </summary>
/// <param name="tcpClient">客户端</param>
/// <param name="datagram">报文</param>
public void Send(TcpClient tcpClient, string datagram)
{
Send(tcpClient, Encoding.GetBytes(datagram));
}
/// <summary>
/// 发送报文至所有客户端
/// </summary>
/// <param name="datagram">报文</param>
public void SendToAll(byte[] datagram)
{
GuardRunning();
foreach (var client in _clients.Values)
{
Send(client.TcpClient, datagram);
}
}
public ICollection<TcpClientState> GetAllClient()
{
return _clients.Values;
}
/// <summary>
/// 发送报文至所有客户端
/// </summary>
/// <param name="datagram">报文</param>
public void SendToAll(string datagram)
{
GuardRunning();
SendToAll(Encoding.GetBytes(datagram));
}
private void HandleDatagramWritten(IAsyncResult ar)
{
try
{
((TcpClient)ar.AsyncState).GetStream().EndWrite(ar);
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("错误:" + ex.Message);
}
catch (IOException ex)
{
Console.WriteLine("错误:" + ex.Message);
}
}
/// <summary>
/// 发送报文至指定的客户端
/// </summary>
/// <param name="tcpClient">客户端</param>
/// <param name="datagram">报文</param>
public void SyncSend(TcpClient tcpClient, byte[] datagram)
{
GuardRunning();
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
if (datagram == null)
throw new ArgumentNullException("datagram");
try
{
NetworkStream stream = tcpClient.GetStream();
if (stream.CanWrite)
{
stream.Write(datagram, 0, datagram.Length);
}
}
catch (ObjectDisposedException ex)
{
Console.WriteLine("对象注销错误:" + ex.Message);
}
}
/// <summary>
/// 发送报文至指定的客户端
/// </summary>
/// <param name="tcpClient">客户端</param>
/// <param name="datagram">报文</param>
public void SyncSend(TcpClient tcpClient, string datagram)
{
SyncSend(tcpClient, Encoding.GetBytes(datagram));
}
/// <summary>
/// 发送报文至所有客户端
/// </summary>
/// <param name="datagram">报文</param>
public void SyncSendToAll(byte[] datagram)
{
GuardRunning();
foreach (var client in _clients.Values)
{
SyncSend(client.TcpClient, datagram);
}
}
/// <summary>
/// 发送报文至所有客户端
/// </summary>
/// <param name="datagram">报文</param>
public void SyncSendToAll(string datagram)
{
GuardRunning();
SyncSendToAll(Encoding.GetBytes(datagram));
}
#endregion Send
#region IDisposable Members
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources;
/// <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
try
{
Stop();
if (_listener != null)
{
_listener = null;
}
}
catch (SocketException ex)
{
Console.WriteLine("socket错误:" + ex.Message);
}
}
_disposed = true;
}
}
#endregion IDisposable Members
}

51
JiLinApp/Pages/ShakeServerManage/Core/CRC8.cs

@ -1,51 +0,0 @@
using System;
namespace JiLinApp.Pages.ShakeServerManage;
public class CRC8
{
/// <summary>
/// CRC8位校验表
/// </summary>
private static byte[] CRC8Table = new byte[] {
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30, 95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139,
87,9,235,181,54,104,138,212,149,203, 41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53 };
public static byte CRC(byte[] buffer)
{
return CRC(buffer, 0, buffer.Length);
}
public static byte CRC(byte[] buffer, int off, int len)
{
byte crc = 0;
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (off < 0 || len < 0 || off + len > buffer.Length)
{
throw new ArgumentOutOfRangeException();
}
for (int i = off; i < len; i++)
{
crc = CRC8Table[crc ^ buffer[i]];
}
return crc;
}
}

74
JiLinApp/Pages/ShakeServerManage/Core/Entity/ClientMessage.cs

@ -1,74 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
namespace JiLinApp.Pages.ShakeServerManage;
public class ClientMessage
{
public TcpClient client { get; set; }
public TcpAlarmHostTable host { get; set; }
public string IP
{
get
{
if (host != null) return host.ip;
if (client != null) return client.Client.RemoteEndPoint.ToString().Split(':')[0];
return "";
}
}
public string Port
{
get
{
if (host != null) return host.port;
if (client != null) return client.Client.RemoteEndPoint.ToString().Split(':')[1];
return "-1";
}
}
public List<byte> list { get; set; }
public Hashtable sectioTable { get; set; }
public ClientMessage()
{
list = new List<byte>();
host = null;
sectioTable = new Hashtable();
}
public List<byte[]> getMessageList()
{
List<byte[]> msglist = new List<byte[]>();
while (list.Count >= 19)
{
if (list[0] == 0xAA && list[1] == 0xAA)
{
int num = list[17];
if (list.Count < 19 + num)
{
break;
}
else
{
byte[] bytes = new byte[num + 19];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = list[i];
}
msglist.Add(bytes);
list.RemoveRange(0, num + 19);
}
}
else
{
list.RemoveAt(0);
}
}
return msglist;
}
}

90
JiLinApp/Pages/ShakeServerManage/Core/Entity/DataMessage.cs

@ -1,90 +0,0 @@
using System;
using System.Text;
namespace JiLinApp.Pages.ShakeServerManage;
public class DataMessage
{
private byte headA = 0xAA;
private byte headB = 0xAA; //(1)帧头
public int deviceID { get; set; } //(2)设备ID
public string sendIP { get; set; } //(3)原地址
public int sendPort { get; set; }//(3)原地址
public string receiveIP { get; set; }//(4)目标地址
public int receivePort { get; set; }//(4)目标地址
public byte frameNum { get; set; }//(5)帧编号
public byte functionNum { get; set; }//(6)功能码
public byte dataLen { get; set; }//(7)传输数据长度
public byte[] data { get; set; }//(8)传输数据
public byte CRC { get; set; }//(9)CRC8
public void decode(byte[] bytes)
{
deviceID = bytes[2];
sendIP = bytes[3].ToString() + "." + bytes[4].ToString() + "." + bytes[5].ToString() + "." + bytes[6].ToString();
sendPort = bytes[8] * 256 + bytes[7];
receiveIP = bytes[9].ToString() + "." + bytes[10].ToString() + "." + bytes[11].ToString() + "." + bytes[12].ToString();
receivePort = bytes[13] * 256 + bytes[14];
frameNum = bytes[15];
functionNum = bytes[16];
dataLen = bytes[17];
data = new byte[dataLen];
for (int i = 0; i < dataLen; i++)
{
data[i] = bytes[18 + i];
}
CRC = bytes[18 + dataLen];
}
public byte[] encode()
{
byte[] bytes = new byte[19 + dataLen];
bytes[0] = bytes[1] = 0xAA;
bytes[2] = (byte)deviceID;
string[] strs = sendIP.Split('.');
bytes[3] = byte.Parse(strs[0]);
bytes[4] = byte.Parse(strs[1]);
bytes[5] = byte.Parse(strs[2]);
bytes[6] = byte.Parse(strs[3]);
bytes[7] = (byte)(sendPort % 256);
bytes[8] = (byte)(sendPort / 256);
string[] strs2 = receiveIP.Split('.');
bytes[9] = byte.Parse(strs2[0]);
bytes[10] = byte.Parse(strs2[1]);
bytes[11] = byte.Parse(strs2[2]);
bytes[12] = byte.Parse(strs2[3]);
bytes[13] = (byte)(receivePort % 256);
bytes[14] = (byte)(receivePort / 256);
bytes[15] = frameNum;
bytes[16] = functionNum;
bytes[17] = dataLen;
for (int i = 0; i < dataLen; i++)
{
bytes[18 + i] = data[i];
}
bytes[bytes.Length - 1] = CRC8.CRC(bytes, 0, bytes.Length - 1);
Console.WriteLine("发送指令:" + ToHexString(bytes));
return bytes;
}
private string ToHexString(byte[] bytes)
{
string hexString = string.Empty;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString("X2") + " ");
}
hexString = strB.ToString();
}
return hexString;
}
}

14
JiLinApp/Pages/ShakeServerManage/Core/Entity/DataRequest.cs

@ -1,14 +0,0 @@
namespace JiLinApp.Pages.ShakeServerManage;
public class DataRequest
{
public DataMessage request { get; set; }
public DataMessage responce { get; set; }
public DataRequest()
{
responce = null;
request = null;
}
}

57
JiLinApp/Pages/ShakeServerManage/Core/Entity/SectionState.cs

@ -1,57 +0,0 @@
namespace JiLinApp.Pages.ShakeServerManage;
public class SectionState
{
public int deviceID { get; set; }
public string channel { get; set; }
public int online { get; set; }
public string onLine_str
{
get
{
if (online == 0)
{
return "在线";
}
else
{
return "离线";
}
}
}
public int alarm { get; set; }
public string alarm_str
{
get
{
if (alarm == 0)
{
return "消警";
}
else
{
return "报警";
}
}
}
public SectionState(int id, int chan, int state)
{
deviceID = id;
channel = chan.ToString();
online = state % 2;
alarm = state / 2 % 2;
}
public SectionState(int id, int chan, int on, int a)
{
deviceID = id;
channel = chan.ToString();
online = on;
alarm = a;
}
}

20
JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpAlarmHostMessage.cs

@ -1,20 +0,0 @@
using Newtonsoft.Json.Linq;
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpAlarmHostMessage
{
public int Id { get; set; }
public string AlarmId { get; set; }//CID代码
public string AlarmTime { get; set; }//报警时间
/*设备信息*/
public int DeviceID { get; set; }//设备唯一ID
public string ChannelNum { get; set; }//防区号
public string Mode { get; set; }
public string Sensitivity { get; set; }
/*联动信息*/
public bool IsLinked { get; set; }//是否有联动信息
public JArray Linklist { get; set; }
}

22
JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpAlarmHostTable.cs

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpAlarmHostTable
{
public int id { get; set; }
public string name { get; set; }
public string lat { get; set; }
public string lng { get; set; }
public string ip { get; set; }
public string port { get; set; }
}

10
JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpManagerConfig.cs

@ -1,10 +0,0 @@
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpManagerConfig
{
public string ServerIp { get; set; }
public int ServerPort { get; set; }
public int DeviceHeartKeep { get; set; }
}

23
JiLinApp/Pages/ShakeServerManage/Core/Entity/TcpSectionTable.cs

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpSectionTable
{
public int id { get; set; }
public int deviceID { get; set; }
public string name { get; set; }
public string lat { get; set; }
public string lng { get; set; }
public string channel { get; set; }
public string mode { get; set; }
public string sensitivity { get; set; }
}

31
JiLinApp/Pages/ShakeServerManage/Core/TcpClientConnectedEventArgs.cs

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.ShakeServerManage;
/// <summary>
/// 与客户端的连接已建立事件参数
/// </summary>
public class TcpClientConnectedEventArgs : EventArgs
{
/// <summary>
/// 与客户端的连接已建立事件参数
/// </summary>
/// <param name="tcpClient">客户端</param>
public TcpClientConnectedEventArgs(TcpClient tcpClient)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
TcpClient = tcpClient;
}
/// <summary>
/// 客户端
/// </summary>
public TcpClient TcpClient { get; private set; }
}

31
JiLinApp/Pages/ShakeServerManage/Core/TcpClientDisconnectedEventArgs.cs

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.ShakeServerManage;
/// <summary>
/// 与客户端的连接已断开事件参数
/// </summary>
public class TcpClientDisconnectedEventArgs : EventArgs
{
/// <summary>
/// 与客户端的连接已断开事件参数
/// </summary>
/// <param name="tcpClient">客户端</param>
public TcpClientDisconnectedEventArgs(TcpClient tcpClient)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
TcpClient = tcpClient;
}
/// <summary>
/// 客户端
/// </summary>
public TcpClient TcpClient { get; private set; }
}

48
JiLinApp/Pages/ShakeServerManage/Core/TcpClientState.cs

@ -1,48 +0,0 @@
using System;
using System.Net.Sockets;
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpClientState
{
/// <summary>
/// Constructor for a new Client
/// </summary>
/// <param name="tcpClient">The TCP client</param>
/// <param name="buffer">The byte array buffer</param>
public TcpClientState(TcpClient tcpClient, byte[] buffer)
{
if (tcpClient == null) throw new ArgumentNullException("tcpClient");
if (buffer == null) throw new ArgumentNullException("buffer");
TcpClient = tcpClient;
Buffer = buffer;
temp = string.Empty;
}
/// <summary>
/// Gets the TCP Client
/// </summary>
public TcpClient TcpClient { get; private set; }
/// <summary>
/// Gets the Buffer.
/// </summary>
public byte[] Buffer { get; private set; }
/// <summary>
/// TCP接收到但未处理的数据
/// </summary>
public string temp { get; set; }
/// <summary>
/// Gets the network stream
/// </summary>
public NetworkStream NetworkStream
{
get
{
return TcpClient.GetStream();
}
}
}

34
JiLinApp/Pages/ShakeServerManage/Core/TcpDatagramReceivedEventArgs.cs

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiLinApp.Pages.ShakeServerManage;
/// <summary>
/// 接收到数据报文事件参数
/// </summary>
/// <typeparam name="T">报文类型</typeparam>
public class TcpDatagramReceivedEventArgs<T> : EventArgs
{
/// <summary>
/// 接收到数据报文事件参数
/// </summary>
/// <param name="tcpClient">客户端</param>
/// <param name="datagram">报文</param>
public TcpDatagramReceivedEventArgs(TcpClientState tcpClient, T datagram)
{
TcpClient = tcpClient;
Datagram = datagram;
}
/// <summary>
/// 客户端
/// </summary>
public TcpClientState TcpClient { get; private set; }
/// <summary>
/// 报文
/// </summary>
public T Datagram { get; private set; }
}

753
JiLinApp/Pages/ShakeServerManage/Core/TcpManager.cs

@ -1,753 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Timers;
namespace JiLinApp.Pages.ShakeServerManage;
public class TcpManager
{
#region fields
private JsonSerializerSettings jSetting { get; } = new();
private AsyncTcpServer server { get; set; } = null;
private Timer stateSpanTimer { get; } = new();
private Timer heartTimer { get; } = new();
private List<ClientMessage> list { get; } = new();
#endregion fields
public TcpManager()
{
jSetting.NullValueHandling = NullValueHandling.Ignore;
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
}
#region BaseMethod
public void StartServer(TcpManagerConfig config)
{
if (IsRunning()) return;
IPAddress address = IPAddress.Any;
_ = IPAddress.TryParse(config.ServerIp, out address);
server = new AsyncTcpServer(address, config.ServerPort);
server.ClientConnected += server_ClientConnected;
server.ClientDisconnected += server_ClientDisconnected;
server.DatagramReceived += server_DatagramReceived;
server.Start();
heartTimer.Close();
heartTimer.Interval = 1000 * config.DeviceHeartKeep;
heartTimer.Elapsed += HeartTimer_Elapsed;
heartTimer.Enabled = true;
heartTimer.Start();
}
public void StopServer()
{
heartTimer.Enabled = false;
if (IsRunning())
{
server.Stop();
server = null;
}
}
public bool IsRunning()
{
return server != null && server.IsRunning;
}
public bool StartScan(ref string error)
{
if (server == null)
{
error = "服务未创建";
return false;
}
if (!server.IsRunning)
{
error = "服务未运行";
return false;
}
stateSpanTimer.Enabled = true;
return true;
}
public void StopScan()
{
stateSpanTimer.Enabled = false;
}
#endregion BaseMethod
private void StateSpanTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
string error = "";
for (int i = 0; i < list.Count; i++)
{
sendState(list[i], ref error);
}
}
private void HeartTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
string error = "";
for (int i = 0; i < list.Count; i++)
{
sendHeart(list[i], ref error);
}
}
private ClientMessage GetClientMessage(TcpClient client)
{
string clientIP = client.Client.RemoteEndPoint.ToString().Split(':')[0];
for (int i = 0; i < list.Count; i++)
{
if (list[i].IP == clientIP)
{
return list[i];
}
}
return null;
}
private ClientMessage GetClientMessageIP(string clientIP)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].IP == clientIP)
{
return list[i];
}
}
return null;
}
private ClientMessage GetClientMessageDeviceID(int deviceId)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i].host != null && list[i].host.id == deviceId)
{
return list[i];
}
}
return null;
}
public delegate void TCPSectionAlarmOnEvent(TcpAlarmHostMessage msg);
public event TCPSectionAlarmOnEvent OnTcpSectionAlarmOn;
public delegate void TCPSectionStateChangeEvent(SectionState state);
public event TCPSectionStateChangeEvent OnTcpSectionStateChange;
public delegate void TCPDeviceMessageEvent(TcpAlarmHostTable host, string msg);
public event TCPDeviceMessageEvent OnTcpDeviceMessage;
public delegate void TCPSectionMessageEvent(TcpAlarmHostTable host, TcpSectionTable section, string msg);
public event TCPSectionMessageEvent OnTcpSectionMessage;
private void server_DatagramReceived(object sender, TcpDatagramReceivedEventArgs<byte[]> e)
{
string clientIP = e.TcpClient.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0];
ClientMessage client = GetClientMessage(e.TcpClient.TcpClient);
if (client != null)
{
AnalysisClientMessage(client, e.Datagram);
}
}
public void TestAlarm(string devideId, string channel)
{
ClientMessage message = new ClientMessage();
message.client = new TcpClient("127.0.0.1", 5090);
list.Add(message);
byte[] bytes1 = BitConverter.GetBytes(int.Parse(devideId));
byte[] bytes2 = BitConverter.GetBytes(int.Parse(channel));
byte[] bytes = new byte[24]{
0xAA,0xAA,bytes1[0],bytes1[1],
127,0,0,1,
0x00,0x00,127,0,
0,1,0x00,0x00,
1,0x14,0x04,bytes2[0],
bytes2[1],0x02,0x00,0x00
};
AnalysisClientMessage(message, bytes);
}
private string ToHexString(byte[] bytes)
{
string hexString = string.Empty;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString("X2") + " ");
}
hexString = strB.ToString();
}
return hexString;
}
private void AnalysisClientMessage(ClientMessage client, byte[] bytes)
{
client.list.AddRange(bytes);
List<byte[]> msglist = client.getMessageList();
if (msglist != null && msglist.Count > 0)
{
for (int i = 0; i < msglist.Count; i++)
{
Console.WriteLine(client.IP + " 收到数据:" + ToHexString(msglist[i]));
DataMessage mm = new DataMessage();
mm.decode(msglist[i]);
switch (mm.functionNum)
{
case 0x00:
Console.WriteLine(client.IP + " 登录");
if (client.host == null || client.host.id != mm.deviceID)
{
//string error = "";
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "id=" + mm.deviceID, ref error);
JArray arr = new();
if (arr != null && arr.Count > 0)
{
client.host = JsonConvert.DeserializeObject<TcpAlarmHostTable>(arr[0].ToString(), jSetting);
client.host.ip = mm.sendIP;
client.host.port = mm.sendPort.ToString();
}
}
if (OnTcpDeviceMessage != null)
{
if (client.host != null)
{
OnTcpDeviceMessage(client.host, "报警主机登录");
}
else
{
OnTcpDeviceMessage(new TcpAlarmHostTable() { id = mm.deviceID, ip = mm.sendIP, port = mm.sendPort.ToString(), name = "未知设备" }, "报警主机登录");
}
}
break;
case 0x01:
Console.WriteLine(client.IP + " 心跳");
break;
case 0x12:
Console.WriteLine(client.IP + "传感器地址设置响应");
SetDataRequest(mm, 0x02);
break;
case 0x13:
Console.WriteLine(client.IP + "传感器模式设置响应");
SetDataRequest(mm, 0x03);
break;
case 0x14:
Console.WriteLine(client.IP + "传感器状态响应");
int channel = mm.data[0] + mm.data[1] * 256;
int state = mm.data[2] + mm.data[3] * 256;
int online = state % 2;
int alarm = state / 2 % 2;
TcpAlarmHostTable host = new() { id = mm.deviceID, ip = mm.sendIP, port = mm.sendPort.ToString(), name = "未知设备" };
ProcessOnlineEvent(client, host, mm, channel, online);
ProcessAlarmEvent(client, host, mm, channel, alarm);
UpdateOnLineAlarm(client, host, channel, online, alarm);
SetDataRequest(mm, 0x04);
break;
case 0x15:
Console.WriteLine(client.IP + "传感器复位响应");
SetDataRequest(mm, 0x05);
break;
}
}
}
}
private void ProcessOnlineEvent(ClientMessage client, TcpAlarmHostTable host, DataMessage mm, int channel, int online)
{
if (client.sectioTable.ContainsKey(channel))
{
SectionState oldState = client.sectioTable[channel] as SectionState;
if (oldState.online == online) return;
}
TcpAlarmHostTable host1 = client.host == null ? host : client.host;
string error = "";
TcpSectionTable section = new TcpSectionTable() { deviceID = host.id, name = "未知传感器", channel = channel.ToString() };
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + mm.deviceID + "/channel='" + channel + "'", ref error);
JArray arr = new();
if (arr != null && arr.Count > 0) section = JsonConvert.DeserializeObject<TcpSectionTable>(arr[0].ToString(), jSetting);
if (OnTcpSectionMessage != null)
{
OnTcpSectionMessage(host1, section, online == 0 ? "传感器上线" : "传感器离线");
}
}
private void ProcessAlarmEvent(ClientMessage client, TcpAlarmHostTable host, DataMessage mm, int channel, int alarm)
{
if (client.sectioTable.ContainsKey(channel))
{
SectionState oldState = client.sectioTable[channel] as SectionState;
if (oldState.alarm == alarm) return;
}
TcpAlarmHostTable host1 = client.host == null ? host : client.host;
TcpSectionTable section = new() { deviceID = host.id, name = "未知传感器", channel = channel.ToString() };
JArray arr = new();
//string error = "";
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + mm.deviceID + "/channel='" + channel + "'", ref error);
if (arr != null && arr.Count > 0) section = JsonConvert.DeserializeObject<TcpSectionTable>(arr[0].ToString(), jSetting);
if (OnTcpSectionMessage != null)
{
OnTcpSectionMessage(host1, section, alarm == 0 ? "传感器消除警" : "传感器报警");
}
if (alarm == 1)
{
ProcessAlarm(host1.id, channel, alarm);
}
}
private void UpdateOnLineAlarm(ClientMessage client, TcpAlarmHostTable host, int channel, int online, int alarm)
{
if (client.sectioTable.ContainsKey(channel))
{
SectionState oldState = client.sectioTable[channel] as SectionState;
oldState.online = online;
oldState.alarm = alarm;
if (OnTcpSectionStateChange != null)
{
OnTcpSectionStateChange(oldState);
}
}
else
{
TcpAlarmHostTable host1 = client.host == null ? host : client.host;
SectionState state = new SectionState(host1.id, channel, online, alarm);
client.sectioTable[channel] = state;
if (OnTcpSectionStateChange != null)
{
OnTcpSectionStateChange(state);
}
}
}
private void ProcessAlarm(int deviceId, int channel, int alarmId)
{
TcpAlarmHostMessage alarm = new()
{
AlarmId = Convert.ToString(alarmId),
AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
DeviceID = deviceId,
ChannelNum = channel.ToString()
};
JArray arr = new();
//string error = "";
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + deviceId + "/channel='" + channel + "'", ref error);
if (arr != null && arr.Count > 0)
{
alarm.Mode = arr[0]["mode"].ToString();
alarm.Sensitivity = arr[0]["sensitivity"].ToString();
}
alarm.Linklist = new();
//alarm.Linklist = DBCenter.center.SearchByConditionJArray("table_TCPLink", "deviceID=" + alarm.deviceID + "/channel='" + channel + "'", ref error);
if (alarm.Linklist == null || alarm.Linklist.Count == 0)
{
alarm.IsLinked = false;
}
else
{
alarm.IsLinked = true;
}
ProcessAlarmDB(alarm);
}
//处理报警事件
private void ProcessAlarmDB(TcpAlarmHostMessage msg)
{
OnTcpSectionAlarmOn(msg);
////报警信息放入数据库
//JObject obj = new JObject
//{
// { "alarmTime", msg.AlarmTime },
// { "deviceID", msg.DeviceID },
// { "channelNum", msg.ChannelNum },
// { "mode", msg.Mode },
// { "sensitivity", msg.Sensitivity },
// { "IsLinked", msg.IsLinked },
// { "linklist", msg.Linklist }
//};
//string error = "";
//DBCenter.center.InsertResult("table_TCPAlarmMessage", obj, ref error);
////打开预览窗口
//if (msg.IsLinked)
//{
// if (OnTCPSectionAlarmOn != null)
// {
// OnTCPSectionAlarmOn(msg);
// }
// //联动预置位
// for (int i = 0; i < msg.linklist.Count; i++)
// {
// if (msg.linklist[i]["needPreset"].ToString() == "true")
// {
// int camID = int.Parse(msg.linklist[i]["camID"].ToString());
// string camType = msg.linklist[i]["camType"].ToString();
// CamType device_type = CamType.Table;
// if (camType == "摄像机") device_type = CamType.Camera;
// int presetId = int.Parse(msg.linklist[i]["presetID"].ToString());
// RequestToService.center.NET_SDK_PTZPreset_Other(camID, device_type, (int)WMPTZPresetCommand.WMPTZPreset_GOTO, presetId, ref error);
// }
// }
//}
}
public void SetDataRequest(DataMessage msg, byte functionNum)
{
lock (this)
{
for (int i = 0; i < reqlist.Count; i++)
{
if (reqlist[i].request.functionNum == functionNum && reqlist[i].request.frameNum == msg.frameNum)
{
reqlist[i].responce = msg;
}
}
}
}
public bool SendMessage(string IP, byte[] bytes, ref string error)
{
if (server == null)
{
error = "服务未创建";
return false;
}
if (!server.IsRunning)
{
error = "服务未运行";
return false;
}
ClientMessage client = GetClientMessageIP(IP);
if (client != null)
{
server.Send(client.client, bytes);
return true;
}
else
{
error = "主机未连接";
return false;
}
}
private List<DataRequest> reqlist = new List<DataRequest>();
private byte frameNumber = 0;
public bool sendRequest(ref DataRequest request, ref string error)
{
if (request.request == null)
{
error = "请求信息未填写";
return false;
}
//int waitTime = int.Parse(DBCenter.center.GetConfig("WW_TCP_DeviceTimeOut")) * 10;
int waitTime = 100;
request.request.frameNum = frameNumber;
frameNumber++;
bool send = SendMessage(request.request.receiveIP, request.request.encode(), ref error);
if (!send) return false;
reqlist.Add(request);
for (int i = 0; i < waitTime; i++)
{
if (request.responce != null)
{
reqlist.Remove(request);
return true;
}
System.Threading.Thread.Sleep(100);
}
return false;
}
public bool sendNoRequest(DataMessage msg, ref string error)
{
msg.frameNum = frameNumber;
frameNumber++;
return SendMessage(msg.receiveIP, msg.encode(), ref error);
}
public bool sendHeart(ClientMessage client, ref string error)
{
if (client.host == null)
{
error = "报警主机信息缺失";
return false;
}
DataMessage msg = getSendMessageHead(client.host.id, client, 0x01, 1);
msg.data = new byte[] { 0xFF };
return sendNoRequest(msg, ref error);
}
public bool SetSectionAddress(int deviceId, string channel_str, int address, ref string error)
{
ClientMessage client = GetClientMessageDeviceID(deviceId);
if (client == null)
{
error = "此主机号不在线";
return false;
}
DataMessage msg = getSendMessageHead(deviceId, client, 0x02, 4);
int channel = int.Parse(channel_str);
msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256), (byte)(address % 256), (byte)(address / 256) };
DataRequest request = new DataRequest();
request.request = msg;
bool result = sendRequest(ref request, ref error);
if (result)
{
JObject conlist = new JObject();
conlist.Add("deviceID", deviceId);
conlist.Add("channel", channel_str);
JObject valuelist = new JObject();
valuelist.Add("channel", address.ToString());
//DBCenter.center.UpdateResult("table_TCPSection", valuelist, conlist, ref error);
}
return result;
}
public bool SetSectionMode(int deviceId, string channel_str, byte mode, byte sensitivity, ref string error)
{
ClientMessage client = GetClientMessageDeviceID(deviceId);
if (client == null)
{
error = "此主机号不在线";
return false;
}
DataMessage msg = getSendMessageHead(deviceId, client, 0x03, 3);
int channel = int.Parse(channel_str);
msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256), (byte)(mode + sensitivity * 8) };
DataRequest request = new DataRequest();
request.request = msg;
bool result = sendRequest(ref request, ref error);
if (result)
{
JObject conlist = new JObject();
conlist.Add("deviceID", deviceId);
conlist.Add("channel", channel_str);
JObject valuelist = new JObject();
valuelist.Add("mode", mode.ToString());
valuelist.Add("sensitivity", sensitivity.ToString());
//DBCenter.center.UpdateResult("table_TCPSection", valuelist, conlist, ref error);
}
return result;
}
public bool SetSectionReset(int deviceId, string channel_str, ref string error)
{
ClientMessage client = GetClientMessageDeviceID(deviceId);
if (client == null)
{
error = "此主机号不在线";
return false;
}
DataMessage msg = getSendMessageHead(deviceId, client, 0x05, 2);
int channel = int.Parse(channel_str);
msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) };
DataRequest request = new DataRequest();
request.request = msg;
return sendRequest(ref request, ref error);
}
public SectionState SetSectionCheck(int deviceId, string channel_str, ref string error)
{
ClientMessage client = GetClientMessageDeviceID(deviceId);
if (client == null)
{
error = "此主机号不在线";
return null;
}
DataMessage msg = getSendMessageHead(deviceId, client, 0x04, 2);
int channel = int.Parse(channel_str);
msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) };
DataRequest request = new DataRequest();
request.request = msg;
bool result = sendRequest(ref request, ref error);
if (result)
{
int channel2 = request.responce.data[0] + request.responce.data[1] * 256;
int state2 = request.responce.data[2] + request.responce.data[3] * 256;
return new SectionState(deviceId, channel2, state2);
}
else
{
return null;
}
}
public List<SectionState> SetDeviceCheck(int deviceId, ref string error)
{
List<SectionState> list = new List<SectionState>();
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID=" + deviceId, ref error);
JArray arr = new();
if (arr != null && arr.Count > 0)
{
for (int i = 0; i < arr.Count; i++)
{
string channel = arr[i]["channel"].ToString();
SectionState state = SetSectionCheck(deviceId, channel, ref error);
if (state == null)
{
state = new SectionState(deviceId, int.Parse(channel), -1, -1);
}
list.Add(state);
}
}
else
{
error = "数据库中没有防区信息";
}
return list;
}
public List<SectionState> SetAllCheck(ref string error)
{
List<SectionState> list = new List<SectionState>();
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "", ref error);
JArray arr = new();
if (arr != null && arr.Count > 0)
{
for (int i = 0; i < arr.Count; i++)
{
int deviceId = int.Parse(arr[i]["id"].ToString());
list.AddRange(SetDeviceCheck(deviceId, ref error));
}
}
return list;
}
private DataMessage getSendMessageHead(int deviceId, ClientMessage client, byte fun_num, byte datalen)
{
//DataMessage msg = new DataMessage();
//msg.deviceID = deviceId;
//msg.sendIP = DBCenter.center.GetConfig("WW_TCP_ServeIP");
//msg.sendPort = int.Parse(DBCenter.center.GetConfig("WW_TCP_ServePort"));
//msg.receiveIP = client.IP;
//msg.receivePort = int.Parse(client.Port);
//msg.functionNum = fun_num;
//msg.dataLen = datalen;
//return msg;
return null;
}
public void sendState(ClientMessage client, ref string error)
{
//if (client.host == null)
//{
// error = "报警主机信息缺失";
// return;
//}
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPSection", "deviceID='" + client.host.id + "'", ref error);
//if (arr != null && arr.Count > 0)
//{
// for (int i = 0; i < arr.Count; i++)
// {
// DataMessage msg = getSendMessageHead(client.host.id, client, 0x04, 2);
// int channel = int.Parse(arr[i]["channel"].ToString());
// msg.data = new byte[] { (byte)(channel % 256), (byte)(channel / 256) };
// sendNoRequest(msg, ref error);
// }
//}
}
private void server_ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e)
{
string clientIP = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0];
Console.WriteLine(clientIP + "下线");
ClientMessage client = GetClientMessage(e.TcpClient);
if (client != null)
{
list.Remove(client);
if (OnTcpDeviceMessage != null)
{
if (client.host != null)
{
OnTcpDeviceMessage(client.host, "报警主机掉线");
}
else
{
OnTcpDeviceMessage(new TcpAlarmHostTable() { id = -1, ip = clientIP, port = client.Port, name = "未知设备" }, "报警主机掉线");
}
}
}
}
private void server_ClientConnected(object sender, TcpClientConnectedEventArgs e)
{
string error = "";
string clientIP = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[0];
string port = e.TcpClient.Client.RemoteEndPoint.ToString().Split(':')[1];
Console.WriteLine(clientIP + "上线");
ClientMessage client = GetClientMessage(e.TcpClient);
if (client == null)
{
ClientMessage msg = new ClientMessage();
msg.client = e.TcpClient;
//JArray arr = DBCenter.center.SearchByConditionJArray("table_TCPAlarmHost", "IP='" + clientIP + "'", ref error);
JArray arr = new();
if (arr != null && arr.Count > 0)
{
msg.host = JsonConvert.DeserializeObject<TcpAlarmHostTable>(arr[0].ToString(), jSetting);
}
list.Add(msg);
if (OnTcpDeviceMessage != null)
{
if (msg.host != null)
{
OnTcpDeviceMessage(msg.host, "报警主机上线");
}
else
{
OnTcpDeviceMessage(new TcpAlarmHostTable() { id = -1, ip = clientIP, port = client.Port, name = "未知设备" }, "报警主机上线");
}
}
}
}
public List<SectionState> getOnlineState(int deviceId)
{
ClientMessage msg = GetClientMessageDeviceID(deviceId);
if (msg != null)
{
return msg.sectioTable.Values as List<SectionState>;
}
else
{
return new List<SectionState>();
}
}
}

2
JiLinApp/Pages/ShakeServerManage/Main.xaml → JiLinApp/Pages/VibrateServerManage/Main.xaml

@ -1,4 +1,4 @@
<UserControl x:Class="JiLinApp.Pages.ShakeServerManage.Main"
<UserControl x:Class="JiLinApp.Pages.VibrateServerManage.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"

18
JiLinApp/Pages/ShakeServerManage/Main.xaml.cs → JiLinApp/Pages/VibrateServerManage/Main.xaml.cs

@ -1,8 +1,9 @@
using System;
using JiLinApp.Docking.VibrateAlarm;
using System;
using System.Windows;
using System.Windows.Controls;
namespace JiLinApp.Pages.ShakeServerManage;
namespace JiLinApp.Pages.VibrateServerManage;
/// <summary>
/// Main.xaml 的交互逻辑
@ -30,8 +31,8 @@ public partial class Main : UserControl
MainViewModel vm = DataContext as MainViewModel;
vm.SetView(this);
Manager.OnTcpDeviceMessage += vm.OnTcpDeviceMessage;
Manager.OnTcpSectionMessage += vm.OnTcpSectionMessage;
//Manager.OnTcpDeviceMessage += vm.OnTcpDeviceMessage;
//Manager.OnTcpSectionMessage += vm.OnTcpSectionMessage;
Manager.OnTcpSectionAlarmOn += vm.OnTcpSectionAlarmOn;
}
}
@ -71,7 +72,7 @@ public partial class Main : UserControl
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return;
throw;
}
}
ChangeState(true);
@ -80,9 +81,16 @@ public partial class Main : UserControl
private void StopBtn_Click(object sender, RoutedEventArgs e)
{
if (Manager.IsRunning())
{
try
{
Manager.StopServer();
}
catch (Exception)
{
throw;
}
}
ChangeState(false);
}

7
JiLinApp/Pages/ShakeServerManage/MainViewModel.cs → JiLinApp/Pages/VibrateServerManage/MainViewModel.cs

@ -1,13 +1,14 @@
using JiLinApp.Mvvm;
using JiLinApp.Docking.VibrateAlarm;
using JiLinApp.Mvvm;
using JiLinApp.Pages.Main;
using Prism.Events;
using Prism.Regions;
namespace JiLinApp.Pages.ShakeServerManage;
namespace JiLinApp.Pages.VibrateServerManage;
public class MainViewModel : ViewModelBase
{
#region fields
#region Fields
private Main View { get; set; }

17
JiLinApp/Properties/AssemblyInfo.cs

@ -0,0 +1,17 @@
using System.Runtime.InteropServices;
// 在此类的 SDK 样式项目中,现在,在此文件中早前定义的几个程序集属性将在生成期间自动添加,并使用在项目属性中定义的值进行填充。有关包含的属性以及如何定制此过程的详细信息,请参阅
// https://aka.ms/assembly-info-properties
// 将 ComVisible 设置为 false 会使此程序集中的类型对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,请将该类型的 ComVisible
// 属性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID。
[assembly: Guid("5cabd53f-59c8-426a-b4c6-233bf6dceaed")]
// 指定log4net 的配置文件
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "./config/log4net.config", Watch = true)]

26
JiLinApp/config.json

@ -1,26 +0,0 @@
{
"zmq": {
"alarmPubAddr": "tcp://127.0.0.1:5000",
"alarmPubTopic": "alarmRecv"
},
"CameraList": [
{
"Ip": "192.168.1.65",
"Port": "8000",
"UserName": "admin",
"Password": "hk123456"
},
{
"Ip": "192.168.1.65",
"Port": "8000",
"UserName": "admin",
"Password": "hk123456"
},
{
"Ip": "192.168.1.65",
"Port": "8000",
"UserName": "admin",
"Password": "hk123456"
}
]
}

25
JiLinApp/config/config.json

@ -0,0 +1,25 @@
{
"base": {
"console": false
},
"cameraList": [
{
"ip": "192.168.1.65",
"port": "8000",
"username": "admin",
"password": "hk123456"
},
{
"ip": "192.168.1.65",
"port": "8000",
"username": "admin",
"password": "hk123456"
},
{
"ip": "192.168.1.65",
"port": "8000",
"username": "admin",
"password": "hk123456"
}
]
}

26
JiLinApp/config/log4net.config

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<log4net>
<root>
<level value="Info" />
<!--文件形式记录日志-->
<appender-ref ref="RollingLogFileAppender" />
</root>
<!--定义输出到文件中-->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="logs/" />
<param name="Encoding" value="UTF-8" />
<param name="RollingStyle" value="Date" />
<param name="DatePattern" value="yyyy-MM-dd'.txt'" />
<param name="LockingModel" type="log4net.Appender.FileAppender+MinimalLock" />
<param name="AppendToFile" value="true" />
<param name="StaticLogFileName" value="false" />
<param name="MaxSizeRollBackups" value="30" />
<param name="maximumFileSize" value="5MB" />
<layout type="log4net.Layout.PatternLayout">
<!--输出格式-->
<conversionPattern value="【日志级别】%-5level 【记录时间】%date 【线程编号】[%thread]【执行时间】[%r]毫秒 【当前的类】%logger 属性[%property{NDC}]%n【日志描述】%message%n%n" />
</layout>
</appender>
</log4net>
</configuration>
Loading…
Cancel
Save