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.
793 lines
25 KiB
793 lines
25 KiB
2 years ago
|
using JiLinApp.Docking.VibrateAlarm;
|
||
|
using System.Collections.Concurrent;
|
||
|
using System.Net;
|
||
|
using System.Timers;
|
||
|
using Timer = System.Timers.Timer;
|
||
|
|
||
|
namespace JiLinApp.Docking.FenceAlarm;
|
||
|
|
||
|
public class UdpManager
|
||
|
{
|
||
|
#region Fields
|
||
|
|
||
|
private UdpServer Server { get; set; }
|
||
|
|
||
|
private UdpManagerConfig Config { get; set; }
|
||
|
|
||
|
private Timer PtzCheckTimer { get; } = new();
|
||
|
|
||
|
private ConcurrentDictionary<int, UdpAlarmHost> DeviceDict { get; } = new();
|
||
|
|
||
|
#region Event
|
||
|
|
||
|
public delegate void FenceUdpDeviceStateEvent(UdpAlarmHost device);
|
||
|
|
||
|
public delegate void FenceUdpSectorStateEvent(SectorState sector);
|
||
|
|
||
|
public delegate void FenceUdpAlarmEvent(UdpAlarmHostMessage msg);
|
||
|
|
||
|
public event FenceUdpDeviceStateEvent? OnFenceUdpDeviceState;
|
||
|
|
||
|
public event FenceUdpSectorStateEvent? OnFenceUdpSectorState;
|
||
|
|
||
|
public event FenceUdpAlarmEvent? OnFenceUdpAlarm;
|
||
|
|
||
|
#endregion Event
|
||
|
|
||
|
#endregion Fields
|
||
|
|
||
|
public UdpManager()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
#region Server
|
||
|
|
||
|
public void Start(UdpManagerConfig config)
|
||
|
{
|
||
|
if (IsRunning()) return;
|
||
|
Server = new(config.ServerPort);
|
||
|
Server.DatagramReceived += Server_DatagramReceived;
|
||
|
Server.Start();
|
||
|
|
||
|
PtzCheckTimer.Interval = 3000;//3s
|
||
|
PtzCheckTimer.Elapsed += PTZCheckTimer_Elapsed;
|
||
|
PtzCheckTimer.Enabled = true;
|
||
|
|
||
|
Config = config;
|
||
|
}
|
||
|
|
||
|
public void Stop()
|
||
|
{
|
||
|
if (!IsRunning()) return;
|
||
|
try
|
||
|
{
|
||
|
Server.Stop();
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
Server.DatagramReceived -= Server_DatagramReceived;
|
||
|
Server = null;
|
||
|
DeviceDict.Clear();
|
||
|
PtzCheckTimer.Stop();
|
||
|
PtzCheckTimer.Elapsed -= PTZCheckTimer_Elapsed;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool IsRunning()
|
||
|
{
|
||
|
return Server != null && Server.IsRunning();
|
||
|
}
|
||
|
|
||
|
#endregion Server
|
||
|
|
||
|
#region Events
|
||
|
|
||
|
/// <summary>
|
||
|
/// 计时判断设备是否在线,若超过规定时间没有新消息发来,则设备离线
|
||
|
/// </summary>
|
||
|
/// <param name="sender"></param>
|
||
|
/// <param name="e"></param>
|
||
|
private void PTZCheckTimer_Elapsed(object? sender, ElapsedEventArgs e)
|
||
|
{
|
||
|
foreach (var key in DeviceDict.Keys)
|
||
|
{
|
||
|
UdpAlarmHost device = DeviceDict[key];
|
||
|
if (device.KeepLive > 0) device.KeepLive--;
|
||
|
else ProcessDeviceStateEvent(ref device, 0, device.DefenceState);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Server_DatagramReceived(object? sender, UdpDatagramReceivedEventArgs<byte[]> e)
|
||
|
{
|
||
|
IPEndPoint ipep = e.Ipep;
|
||
|
//解码
|
||
|
//byte[] msg = e.Datagram;
|
||
|
byte[] msg = AlarmEncode.DecodeMessage(e.Datagram);
|
||
|
bool vaild = msg.Length >= 8 && msg[2] == AlarmEncode.Head[0] && msg[3] == AlarmEncode.Head[1];
|
||
|
Console.WriteLine("Recv from {0}:{1} => {2}, {3}, {4}", ipep.Address.ToString(), ipep.Port, DataMessage.ToHexString(e.Datagram), DataMessage.ToHexString(msg), vaild);
|
||
|
if (!vaild) return;
|
||
|
//解析
|
||
|
DeviceCmd deviceCmd = (DeviceCmd)msg[4];
|
||
|
switch (deviceCmd)
|
||
|
{
|
||
|
case DeviceCmd.HeartBeatCmd://心跳信息
|
||
|
AnalysisHeartMessage(ipep, msg);
|
||
|
break;
|
||
|
|
||
|
case DeviceCmd.AlarmCmd://报警信息
|
||
|
AnalysisAlarmMessage(ipep, msg);
|
||
|
break;
|
||
|
|
||
|
case DeviceCmd.AllSectorStateCmd://防区信息
|
||
|
AnalysisAllSectorMessage(ipep, msg);
|
||
|
break;
|
||
|
|
||
|
case DeviceCmd.RtSectorStateCmd://张力防区信息
|
||
|
AnalysisSectorMessage(ipep, msg);
|
||
|
break;
|
||
|
|
||
|
case DeviceCmd.MaxSectorTotalCmd://最大防区信息
|
||
|
AnalysisMaxSectorMessage(ipep, msg);
|
||
|
break;
|
||
|
|
||
|
case DeviceCmd.BackSettingsCmd://返回报警主机设置参数回服务器,无需解析
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
SendOk(ipep);
|
||
|
}
|
||
|
|
||
|
#endregion Events
|
||
|
|
||
|
#region Analysis
|
||
|
|
||
|
private void AnalysisHeartMessage(IPEndPoint ipep, byte[] msg)
|
||
|
{
|
||
|
string ip = ipep.Address.ToString();
|
||
|
int deviceId = ByteToInt(msg, 5);
|
||
|
if (!TryGetDevice(deviceId, out UdpAlarmHost device))
|
||
|
{
|
||
|
device = new()
|
||
|
{
|
||
|
DeviceId = deviceId,
|
||
|
Ip = ip,
|
||
|
Port = ipep.Port,
|
||
|
GroupId = ByteToInt(msg, 9),
|
||
|
UserId = ByteToInt(msg, 13),
|
||
|
OnlineState = 1,
|
||
|
KeepLive = Config.DeviceHeartKeep
|
||
|
};
|
||
|
AddDevice(deviceId, ref device);
|
||
|
}
|
||
|
byte defenceState = msg[17];
|
||
|
//在线状态
|
||
|
device.KeepLive = Config.DeviceHeartKeep;
|
||
|
ProcessDeviceStateEvent(ref device, 1, defenceState);
|
||
|
device.WorkState = 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.SectorTotal = msg[25];
|
||
|
}
|
||
|
|
||
|
private void AnalysisAlarmMessage(IPEndPoint ipep, byte[] msg)
|
||
|
{
|
||
|
string ip = ipep.Address.ToString();
|
||
|
int deviceId = ByteToInt(msg, 5);
|
||
|
if (!TryGetDevice(deviceId, out _))
|
||
|
{
|
||
|
UdpAlarmHost device = new()
|
||
|
{
|
||
|
DeviceId = deviceId,
|
||
|
Ip = ip,
|
||
|
Port = ipep.Port,
|
||
|
GroupId = ByteToInt(msg, 9),
|
||
|
UserId = ByteToInt(msg, 13),
|
||
|
OnlineState = 1,
|
||
|
KeepLive = Config.DeviceHeartKeep
|
||
|
};
|
||
|
AddDevice(deviceId, ref device);
|
||
|
}
|
||
|
string alarmTime = $"20{GetBCD(msg[17])}-{GetBCD(msg[18])}-{GetBCD(msg[19])} " +
|
||
|
$"{GetBCD(msg[20])}:{GetBCD(msg[21])}:{GetBCD(msg[22])}";
|
||
|
string CID = GetCID(msg[23]) + GetCID(msg[24]) + GetCID(msg[25]) + GetCID(msg[26]);
|
||
|
int sectorId = msg[29] + msg[30] * 256;
|
||
|
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,
|
||
|
SectorId = sectorId,
|
||
|
SubSectorId = msg[31] + msg[32] * 256,
|
||
|
ExtendArgs = msg[33].ToString("X2") + " " + msg[34].ToString("X2") + " " + msg[35].ToString("X2"),
|
||
|
};
|
||
|
ReportAlarm(alarm);
|
||
|
}
|
||
|
|
||
|
private void AnalysisAllSectorMessage(IPEndPoint ipep, byte[] msg)
|
||
|
{
|
||
|
string ip = ipep.Address.ToString();
|
||
|
int deviceId = ByteToInt(msg, 5);
|
||
|
if (!TryGetDevice(deviceId, out UdpAlarmHost device))
|
||
|
{
|
||
|
device = new()
|
||
|
{
|
||
|
DeviceId = deviceId,
|
||
|
Ip = ip,
|
||
|
Port = ipep.Port,
|
||
|
GroupId = ByteToInt(msg, 9),
|
||
|
UserId = ByteToInt(msg, 13),
|
||
|
OnlineState = 1,
|
||
|
KeepLive = Config.DeviceHeartKeep
|
||
|
};
|
||
|
AddDevice(deviceId, ref device);
|
||
|
}
|
||
|
device.SectorTotal = msg[17] * 256 + msg[18];
|
||
|
int sectorNum = msg[19], startIndex = msg[20];
|
||
|
for (int i = 0; i < sectorNum; i++)
|
||
|
{
|
||
|
int sectorId = i + startIndex;//防区序号
|
||
|
int pos = 21 + i;//防区信息所在byte数组未知
|
||
|
SectorState curSector = new(device.DeviceId, sectorId, msg[pos]);
|
||
|
if (device.SectorDict.TryGetValue(sectorId, out SectorState? sector))
|
||
|
{
|
||
|
ProcessSectorStateEvent(ref sector, curSector.State);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sector = curSector;
|
||
|
device.SectorDict[sector.Id] = sector;
|
||
|
//ProcessSectorStateEvent(ref sector);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void AnalysisSectorMessage(IPEndPoint ipep, byte[] msg)
|
||
|
{
|
||
|
//东北没有张力防区,暂不解析
|
||
|
string ip = ipep.Address.ToString();
|
||
|
int deviceId = ByteToInt(msg, 5);
|
||
|
if (!TryGetDevice(deviceId, out UdpAlarmHost device))
|
||
|
{
|
||
|
device = new()
|
||
|
{
|
||
|
DeviceId = deviceId,
|
||
|
Ip = ip,
|
||
|
Port = ipep.Port,
|
||
|
GroupId = ByteToInt(msg, 9),
|
||
|
UserId = ByteToInt(msg, 13),
|
||
|
OnlineState = 1,
|
||
|
KeepLive = Config.DeviceHeartKeep
|
||
|
};
|
||
|
AddDevice(deviceId, ref device);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void AnalysisMaxSectorMessage(IPEndPoint ipep, byte[] msg)
|
||
|
{
|
||
|
string ip = ipep.Address.ToString();
|
||
|
int deviceId = ByteToInt(msg, 5);
|
||
|
if (!TryGetDevice(deviceId, out UdpAlarmHost device))
|
||
|
{
|
||
|
device = new()
|
||
|
{
|
||
|
DeviceId = deviceId,
|
||
|
Ip = ip,
|
||
|
Port = ipep.Port,
|
||
|
GroupId = ByteToInt(msg, 9),
|
||
|
UserId = ByteToInt(msg, 13),
|
||
|
OnlineState = 1,
|
||
|
KeepLive = Config.DeviceHeartKeep
|
||
|
};
|
||
|
AddDevice(deviceId, ref device);
|
||
|
}
|
||
|
device.SectorTotal = msg[17] * 256 + msg[18];
|
||
|
}
|
||
|
|
||
|
private void ProcessDeviceStateEvent(ref UdpAlarmHost device, int onlineState, int defenceState)
|
||
|
{
|
||
|
bool reportFlag = false;
|
||
|
if (device.OnlineState != onlineState)
|
||
|
{
|
||
|
if (onlineState == 0 && device.KeepLive < 0)
|
||
|
{
|
||
|
reportFlag = true;
|
||
|
device.OnlineState = onlineState;
|
||
|
}
|
||
|
else if (onlineState == 1 && device.KeepLive >= 0)
|
||
|
{
|
||
|
reportFlag = true;
|
||
|
device.OnlineState = onlineState;
|
||
|
}
|
||
|
}
|
||
|
if (device.DefenceState != defenceState)
|
||
|
{
|
||
|
reportFlag = true;
|
||
|
device.DefenceState = defenceState;
|
||
|
}
|
||
|
if (reportFlag) ReportDeviceState(device);
|
||
|
}
|
||
|
|
||
|
private void ProcessSectorStateEvent(ref SectorState sector, int state)
|
||
|
{
|
||
|
if (sector.State != state)
|
||
|
{
|
||
|
sector.State = state;
|
||
|
ReportSectorState(sector);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void ReportDeviceState(UdpAlarmHost device)
|
||
|
{
|
||
|
OnFenceUdpDeviceState?.Invoke(device);
|
||
|
}
|
||
|
|
||
|
private void ReportSectorState(SectorState sector)
|
||
|
{
|
||
|
OnFenceUdpSectorState?.Invoke(sector);
|
||
|
}
|
||
|
|
||
|
private void ReportAlarm(UdpAlarmHostMessage msg)
|
||
|
{
|
||
|
OnFenceUdpAlarm?.Invoke(msg);
|
||
|
}
|
||
|
|
||
|
#endregion Analysis
|
||
|
|
||
|
#region Send
|
||
|
|
||
|
/// <summary>
|
||
|
/// 应答
|
||
|
/// </summary>
|
||
|
/// <param name="ipep"></param>
|
||
|
/// <returns></returns>
|
||
|
private bool SendOk(IPEndPoint ipep)
|
||
|
{
|
||
|
if (!IsRunning()) return false;
|
||
|
byte[] bytes = new byte[] { 0x08, 0x12, 0xF0, 0xFA, 0x8F, 0x06, 0x6B, 0x0D };
|
||
|
////byte[] bytes = AlarmEncode.GetSendMessage(0x8F, Array.Empty<byte>());
|
||
|
return Server.SendMessage(ipep.Address.ToString(), ipep.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
//Console.WriteLine();
|
||
|
//byte[] bytes = new byte[] {
|
||
|
// 0x24, 0x12, 0xF0, 0xFA,
|
||
|
// 0x02,
|
||
|
// 0x77, 0x35, 0x94, 0x01,
|
||
|
// 0x07, 0x5B, 0xCD, 0x15,
|
||
|
// 0x00, 0x01, 0xE2, 0x40,
|
||
|
// 0x23, 0x05, 0x18, 0x17, 0x12, 0x34,
|
||
|
// 0x01, 0x00, 0x00, 0x01,
|
||
|
// 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||
|
// 0x0F, 0x41, 0x0D };
|
||
|
//Console.WriteLine(DataMessage.ToHexString(AlarmEncode.EncodeMessage(bytes))); bytes = new byte[] {
|
||
|
// 0x24, 0x12, 0xF0, 0xFA,
|
||
|
// 0x02,
|
||
|
// 0x77, 0x35, 0x94, 0x01,
|
||
|
// 0x07, 0x5B, 0xCD, 0x15,
|
||
|
// 0x00, 0x01, 0xE2, 0x40,
|
||
|
// 0x23, 0x05, 0x18, 0x17, 0x12, 0x34,
|
||
|
// 0x01, 0x00, 0x00, 0x02,
|
||
|
// 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||
|
// 0x3C, 0x05, 0x0D };
|
||
|
//Console.WriteLine(DataMessage.ToHexString(AlarmEncode.EncodeMessage(bytes))); bytes = new byte[] {
|
||
|
// 0x24, 0x12, 0xF0, 0xFA,
|
||
|
// 0x02,
|
||
|
// 0x77, 0x35, 0x94, 0x01,
|
||
|
// 0x07, 0x5B, 0xCD, 0x15,
|
||
|
// 0x00, 0x01, 0xE2, 0x40,
|
||
|
// 0x23, 0x05, 0x18, 0x17, 0x12, 0x34,
|
||
|
// 0x01, 0x00, 0x00, 0x01,
|
||
|
// 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||
|
// 0x0E, 0x35, 0x0D };
|
||
|
//Console.WriteLine(DataMessage.ToHexString(AlarmEncode.EncodeMessage(bytes))); bytes = new byte[] {
|
||
|
// 0x24, 0x12, 0xF0, 0xFA,
|
||
|
// 0x02,
|
||
|
// 0x77, 0x35, 0x94, 0x01,
|
||
|
// 0x07, 0x5B, 0xCD, 0x15,
|
||
|
// 0x00, 0x01, 0xE2, 0x40,
|
||
|
// 0x23, 0x05, 0x18, 0x17, 0x12, 0x34,
|
||
|
// 0x01, 0x00, 0x00, 0x02,
|
||
|
// 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||
|
// 0x3C, 0xC9, 0x0D };
|
||
|
//Console.WriteLine(DataMessage.ToHexString(AlarmEncode.EncodeMessage(bytes)));
|
||
|
//Server.SendMessage(ipep.Address.ToString(), ipep.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
//return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 外出布防或者布防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetDeviceDefence(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x60 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 撤防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool WithdrawDeviceDefence(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x61 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 立即布防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetDeviceDefenceImmediately(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x62 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 在家布防留守布防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetDeviceDefenceHome(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x63 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 即时留守布防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetDeviceDefenceHomeImmediately(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x64 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 清除报警记忆(复位)
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool ClearDeviceDefence(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x80, new byte[] { 0x65 });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 校对系统时间
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="time"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetDeviceTime(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] content = GetBCDTime(DateTime.Now);
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x8D, content);
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 设备重启
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool RebootDevice(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0xA0, Array.Empty<byte>());
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 单防区布防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="sectorId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetSectorefence(int deviceId, int sectorId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0xC0, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 单防区撤防
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="sectorId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool WithdrawSectorDefence(int deviceId, int sectorId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0xC1, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 单防区旁路
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="sectorId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SetSectorByway(int deviceId, int sectorId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0xC2, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 单防区旁路恢复
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="sectorId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool WithdrawSectorByway(int deviceId, int sectorId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0xC3, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 查询防区状态
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <param name="sectorId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SearchSectorState(int deviceId, int sectorId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x85, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 查询所有防区状态
|
||
|
/// </summary>
|
||
|
/// <param name="deviceId"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool SearchAllSectorState(int deviceId)
|
||
|
{
|
||
|
UdpAlarmHost device = GetDevice(deviceId);
|
||
|
if (CheckDevice(device))
|
||
|
{
|
||
|
int sectorId = 0x00;
|
||
|
byte[] bytes = AlarmEncode.GetSendMessage(0x85, new byte[] { (byte)(sectorId / 256), (byte)(sectorId % 256) });
|
||
|
return Server.SendMessage(device.Ip, device.Port, AlarmEncode.EncodeMessage(bytes));
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#endregion Send
|
||
|
|
||
|
#region DeviceDict
|
||
|
|
||
|
public bool ContainsDevice(int deviceId)
|
||
|
{
|
||
|
return DeviceDict.ContainsKey(deviceId);
|
||
|
}
|
||
|
|
||
|
public UdpAlarmHost GetDevice(int deviceId)
|
||
|
{
|
||
|
return DeviceDict[deviceId];
|
||
|
}
|
||
|
|
||
|
public bool TryGetDevice(int deviceId, out UdpAlarmHost device)
|
||
|
{
|
||
|
return DeviceDict.TryGetValue(deviceId, out device);
|
||
|
}
|
||
|
|
||
|
private bool AddDevice(int deviceId, ref UdpAlarmHost device)
|
||
|
{
|
||
|
if (ContainsDevice(deviceId)) return false;
|
||
|
DeviceDict[deviceId] = device;
|
||
|
UdpAlarmHost innerDevice = DeviceDict[deviceId];
|
||
|
if (innerDevice.SectorsEmpty && innerDevice.SectorsLock.TryEnterWriteLock(1000))
|
||
|
{
|
||
|
Task.Run(() =>
|
||
|
{
|
||
|
innerDevice = DeviceDict[deviceId];
|
||
|
while (innerDevice.SectorsEmpty)
|
||
|
{
|
||
|
SearchAllSectorState(innerDevice.DeviceId);
|
||
|
Thread.Sleep(1000);
|
||
|
}
|
||
|
innerDevice.SectorsLock.ExitWriteLock();
|
||
|
});
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private void SetDevice(int deviceId, UdpAlarmHost device)
|
||
|
{
|
||
|
DeviceDict[deviceId] = device;
|
||
|
}
|
||
|
|
||
|
private bool RemoveDevice(int deviceId)
|
||
|
{
|
||
|
return DeviceDict.Remove(deviceId, out _);
|
||
|
}
|
||
|
|
||
|
public List<UdpAlarmHost> GetDeviceList()
|
||
|
{
|
||
|
return DeviceDict.Values.ToList();
|
||
|
}
|
||
|
|
||
|
private bool CheckDevice(UdpAlarmHost device)
|
||
|
{
|
||
|
if (!IsRunning()) return false;
|
||
|
if (device == null) return false;
|
||
|
if (device.OnlineState == 0) return false;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#endregion DeviceDict
|
||
|
|
||
|
#region Util
|
||
|
|
||
|
private int GetBit(byte bytes, int index)
|
||
|
{
|
||
|
return index switch
|
||
|
{
|
||
|
0 => bytes & 0x01,
|
||
|
1 => (bytes & 0x02) >> 1,
|
||
|
2 => (bytes & 0x04) >> 2,
|
||
|
3 => (bytes & 0x08) >> 3,
|
||
|
4 => (bytes & 0x10) >> 4,
|
||
|
5 => (bytes & 0x20) >> 5,
|
||
|
6 => (bytes & 0x40) >> 6,
|
||
|
7 => (bytes & 0x80) >> 7,
|
||
|
_ => 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] };
|
||
|
}
|
||
|
|
||
|
private string GetCID(byte bytes)
|
||
|
{
|
||
|
return bytes switch
|
||
|
{
|
||
|
0x00 => "0",
|
||
|
0x01 => "1",
|
||
|
0x02 => "2",
|
||
|
0x03 => "3",
|
||
|
0x04 => "4",
|
||
|
0x05 => "5",
|
||
|
0x06 => "6",
|
||
|
0x07 => "7",
|
||
|
0x08 => "8",
|
||
|
0x09 => "9",
|
||
|
0x0A => "A",
|
||
|
0x0B => "B",
|
||
|
0x0C => "C",
|
||
|
0x0D => "D",
|
||
|
0x0E => "E",
|
||
|
0x0F => "F",
|
||
|
_ => "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 %= 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) };
|
||
|
}
|
||
|
|
||
|
#endregion Util
|
||
|
}
|