You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

838 lines
25 KiB

2 years ago
using System.Data;
using System.Timers;
using Timer = System.Timers.Timer;
namespace JiLinApp.Docking.FenceAlarm;
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_ReceivePort = Port;
this.udp_sendPort = device_port;
this.keep_alive = keep_alive;
try
{
//启动UDP协议
myUdp = new Udp(IP, udp_ReceivePort);
myUdp.myUDPReceive += myUDPReceive;
}
catch (Exception ex)
{
myUdp = null;
return false;
}
if (keep_alive > 0)
{
PtzCheckTimer.Enabled = true;
}
return true;
}
private bool AlarmHostLoginOut()
{
PtzCheckTimer.Enabled = false;
if (myUdp != null)
{
myUdp.myUDPReceive -= myUDPReceive;
myUdp.Stop();
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]);
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"),
};
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;
}
}
}