2025-12-11 09:17:16 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using Common;
|
|
|
|
|
|
using Dao;
|
|
|
|
|
|
using RCUHost.Protocols;
|
|
|
|
|
|
using uPLibrary.Networking.M2Mqtt;
|
|
|
|
|
|
using uPLibrary.Networking.M2Mqtt.Messages;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using CommonEntity;
|
|
|
|
|
|
using RestSharp;
|
|
|
|
|
|
using System.Configuration;
|
|
|
|
|
|
using Dao.Implement;
|
|
|
|
|
|
using Domain;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Microsoft.IO;
|
|
|
|
|
|
|
|
|
|
|
|
namespace RCUHost.Implement
|
|
|
|
|
|
{
|
|
|
|
|
|
public class State
|
|
|
|
|
|
{
|
|
|
|
|
|
internal State(int bufferSize)
|
|
|
|
|
|
{
|
|
|
|
|
|
Buffer = new byte[bufferSize];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal byte[] Buffer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// HostServer
|
|
|
|
|
|
/// 服务器与RCU主机所有往来命令消息都会经过 HostServer 进行统一处理。
|
|
|
|
|
|
/// 对于 RCU 发往服务器的消息,首先进行校验,解析出消息头部,分发给其对应的 Receiver
|
|
|
|
|
|
/// 再由 Receiver 对数据部分进行解析处理。
|
|
|
|
|
|
/// 服务器发往 RCU 的消息,首先由 Receiver 对命令数据进行封包,再经由 HostServer 将
|
|
|
|
|
|
/// 数据发送出去。
|
|
|
|
|
|
/// HostServer 维护一个 Receiver 列表,如果需要 HostServer 处理 RCU 发给服务器的
|
|
|
|
|
|
/// 某种类型消息,就需要将其对应的 Receiver 附加到 Receiver 列表中,否则 HostServer 就
|
|
|
|
|
|
/// 会忽略该消息。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class HostServer : IHostServer, IDisposable
|
|
|
|
|
|
{
|
|
|
|
|
|
#region Private Properties
|
|
|
|
|
|
|
|
|
|
|
|
public ISysOauth2Repository SysOauth2Repository { get; set; }
|
|
|
|
|
|
public IHostModalRepository HostModalRepository { get; set; }
|
|
|
|
|
|
private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(HostServer));
|
|
|
|
|
|
private Object _lock = new Object();
|
|
|
|
|
|
private UdpClient udpClient;
|
|
|
|
|
|
//private Socket udpClient;
|
|
|
|
|
|
private ConcurrentDictionary<CommandType, IReceiver> receivers = new ConcurrentDictionary<CommandType, IReceiver>();
|
|
|
|
|
|
private ConcurrentBag<CommandData> commandQueue = new ConcurrentBag<CommandData>();//BlockingCollection
|
|
|
|
|
|
//private System.Threading.Timer timer = null;
|
|
|
|
|
|
//private Object _lock1 = new Object();
|
|
|
|
|
|
private static long _customer = 0;
|
|
|
|
|
|
private Object _lock2 = new Object();
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Public Properies
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// BeforeStart事件
|
|
|
|
|
|
/// HostServer 启动之前调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
//public event EventHandler BeforeStart;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// AfterStart事件
|
|
|
|
|
|
/// HostServer 启动后调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
//public event EventHandler AfterStart;
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 由Spring调用
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 由 Spring 在创建 HostServer 后调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 由 Spring 在销毁 HostServer 前调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Destroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
public void AddReceiver(IReceiver receiver)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
receivers[receiver.CommandType] = receiver;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void RemoveReceiver(IReceiver receiver)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver takeReceiver = null;
|
|
|
|
|
|
receivers.TryRemove(receiver.CommandType, out takeReceiver);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static string UDPAllDataKey = "All_UDPPackage_Data";
|
|
|
|
|
|
public void StreamConsume(string group = "UDPData", string consumer = "Crics1", string task_key = "task1")
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var redis = CSRedisCacheHelper.redis1;
|
|
|
|
|
|
var data = redis.XReadGroup(group, consumer, 500, 10, new ValueTuple<string, string>(UDPAllDataKey, ">"));
|
|
|
|
|
|
|
|
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//var pending = redis.XPending(UDPAllDataKey, group);
|
|
|
|
|
|
foreach (var item in data)
|
|
|
|
|
|
{
|
|
|
|
|
|
var idarray = item.Item2;
|
|
|
|
|
|
string nsa = string.Concat(task_key, "#", idarray.Count().ToString());
|
|
|
|
|
|
CSRedisCacheHelper.Publish("udp_package_consumer", nsa);
|
|
|
|
|
|
foreach (var SerializeNo in idarray)
|
|
|
|
|
|
{
|
|
|
|
|
|
var id1 = SerializeNo.Item1;
|
|
|
|
|
|
var str = SerializeNo.Item2[1];
|
|
|
|
|
|
var GGG = JsonConvert.DeserializeObject<GaiXie>(str);
|
|
|
|
|
|
redis.XAck(UDPAllDataKey, group, id1);
|
|
|
|
|
|
redis.XDel(UDPAllDataKey, id1);
|
|
|
|
|
|
ProcessData(GGG);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 启动 HostServer
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Start()
|
|
|
|
|
|
{
|
|
|
|
|
|
Close();
|
|
|
|
|
|
|
|
|
|
|
|
//CSRedisCacheHelper.StreamAdd(1,UDPAllDataKey, data);
|
|
|
|
|
|
//CSRedisCacheHelper.StreamConsume(1, UDPAllDataKey);
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
udpClient = new UdpClient(3339);
|
|
|
|
|
|
uint IOC_IN = 0x80000000;
|
|
|
|
|
|
uint IOC_VENDOR = 0x18000000;
|
|
|
|
|
|
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
|
|
|
|
|
|
udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
|
|
|
|
|
|
udpClient.BeginReceive(ReceiveCallback, new UdpState(udpClient));
|
|
|
|
|
|
logger.Error("Host Server启动成功,端口:3339");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CSRedisCacheHelper.redis1.Del(UDPAllDataKey);
|
|
|
|
|
|
CSRedisCacheHelper.redis1.XGroupCreate(UDPAllDataKey, "UDPData", "0", true);
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
StreamConsume("UDPData", "Crics1", "task1");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TaskCreationOptions.LongRunning);
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
StreamConsume("UDPData", "Crics2", "task2");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TaskCreationOptions.LongRunning);
|
|
|
|
|
|
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
StreamConsume("UDPData", "Crics3", "task3");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TaskCreationOptions.LongRunning);
|
|
|
|
|
|
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
StreamConsume("UDPData", "Crics4", "task4");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TaskCreationOptions.LongRunning);
|
|
|
|
|
|
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
StreamConsume("UDPData", "Crics5", "task5");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TaskCreationOptions.LongRunning);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error("Host Server启动失败,端口:3339");
|
|
|
|
|
|
Close();
|
2025-12-19 16:58:44 +08:00
|
|
|
|
//throw ex;//不能去掉,否则重启iis服务,通讯服务不会再次启动
|
2025-12-11 09:17:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关闭 HostServer
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Close()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (udpClient != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
udpClient.Close();
|
|
|
|
|
|
udpClient = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public static MqttClient client { get; set; }
|
|
|
|
|
|
public static void StartMQTTClient()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (client == null || client.IsConnected == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
client = new MqttClient("127.0.0.1");
|
|
|
|
|
|
|
|
|
|
|
|
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
|
|
|
|
|
|
client.ConnectionClosed += new MqttClient.ConnectionClosedEventHandler(client_ConnectionClosed);
|
|
|
|
|
|
string clientId = Guid.NewGuid().ToString("N");
|
|
|
|
|
|
client.Connect(clientId);
|
|
|
|
|
|
|
|
|
|
|
|
client.Subscribe(new string[] { "/blw/mqtt/test" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
|
|
|
|
|
|
|
|
|
|
|
|
Console.ReadKey();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
static void client_ConnectionClosed(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool bbb = client.IsConnected;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Encoding.UTF8.GetString(e.Message);
|
|
|
|
|
|
logger.Error("收到了测试数据:" + sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
public static void PublishMessage(byte[] message)
|
|
|
|
|
|
{
|
|
|
|
|
|
string topic = "/blw/2024/registerinfo";
|
|
|
|
|
|
if (client != null && client.IsConnected)
|
|
|
|
|
|
{
|
|
|
|
|
|
client.Publish(topic, message);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
StartMQTTClient();
|
|
|
|
|
|
client.Publish(topic, message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 数据发送
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令数据报发送到指定的远程主机上的指定端口。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data">byte类型数据,表示将要发送到远程主机的命令数据</param>
|
|
|
|
|
|
/// <param name="ip">远程主机IP地址</param>
|
|
|
|
|
|
/// <param name="port">远程主机端口</param>
|
|
|
|
|
|
public void Send(byte[] data, string ip, int port)
|
|
|
|
|
|
{
|
|
|
|
|
|
Send(data, new IPEndPoint(IPAddress.Parse(ip), port), false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令数据发送到位于指定远程终结点的主机。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data">byte类型数据,表示将要发送到远程主机的命令数据</param>
|
|
|
|
|
|
/// <param name="endPoint">IPEndPoint类型,表示要将命令数据发送到的主机和端口</param>
|
|
|
|
|
|
public void Send(byte[] data, IPEndPoint endPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
Send(data, endPoint, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令数据报发送到指定的远程主机上的指定端口。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data">byte类型数据,表示将要发送到远程主机的命令数据</param>
|
|
|
|
|
|
/// <param name="ip">远程主机IP地址</param>
|
|
|
|
|
|
/// <param name="port">远程主机端口</param>
|
|
|
|
|
|
public void SendAndPushCommandQueue(byte[] data, string ip, int port)
|
|
|
|
|
|
{
|
|
|
|
|
|
Send(data, new IPEndPoint(IPAddress.Parse(ip), port), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令数据发送到位于指定远程终结点的主机。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data">byte类型数据,表示将要发送到远程主机的命令数据</param>
|
|
|
|
|
|
/// <param name="endPoint">IPEndPoint类型,表示要将命令数据发送到的主机和端口</param>
|
|
|
|
|
|
public void SendAndPushCommandQueue(byte[] data, IPEndPoint endPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
Send(data, endPoint, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令数据发送到位于指定远程终结点的主机。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data">byte类型数据,表示将要发送到远程主机的命令数据</param>
|
|
|
|
|
|
/// <param name="endPoint">IPEndPoint类型,表示要将命令数据发送到的主机和端口</param>
|
|
|
|
|
|
/// <param name="needPushCommandQueue">是否需要将命令放入队列</param>
|
|
|
|
|
|
public void Send(byte[] data, IPEndPoint endPoint, bool needPushCommandQueue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (udpClient != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 去掉lock
|
|
|
|
|
|
ushort crc = Tools.CRC16(data, data.Length - 2);//最后两个字节,加CRC16校验
|
|
|
|
|
|
data[data.Length - 2] = Convert.ToByte(crc & 0xff);
|
|
|
|
|
|
data[data.Length - 1] = Convert.ToByte((crc >> 8) & 0xff);
|
|
|
|
|
|
|
|
|
|
|
|
//[AA 55 2C 00
|
|
|
|
|
|
//54 33 53 41
|
|
|
|
|
|
//0E
|
|
|
|
|
|
//FF AA
|
|
|
|
|
|
//3D 04 //hotelcode 04 3D 1085
|
|
|
|
|
|
//60
|
|
|
|
|
|
//CB
|
|
|
|
|
|
//00 00 00 00 00 00 00 03 04 00 08 00 01 00 34 01 08 00 02 00 01 06 01 00 02 00 00 52 A4 ]
|
|
|
|
|
|
var HotelCode = data.Skip(11).Take(2).ToArray();
|
|
|
|
|
|
var N1 = HotelCode[0];
|
|
|
|
|
|
var N2 = HotelCode[1];
|
|
|
|
|
|
if (N1 == 0xFF && N2 == 0xFF)
|
|
|
|
|
|
{
|
|
|
|
|
|
//return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var N3 = Convert.ToInt64(Convert.ToInt16(N1.ToString("000")) + Convert.ToInt16(N2.ToString("000")) * 256).ToString();
|
|
|
|
|
|
|
|
|
|
|
|
var TotalKey = "UDPPackage_TotalSendPackage";
|
|
|
|
|
|
UDPPackageCount LLL_T = null;
|
|
|
|
|
|
DataTongJi.TotalCount.TryGetValue(TotalKey, out LLL_T);
|
|
|
|
|
|
if (LLL_T != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
LLL_T.Count = LLL_T.Count + 1;
|
|
|
|
|
|
long UUU = 0;
|
|
|
|
|
|
LLL_T.FenLei.TryGetValue(N3, out UUU);
|
|
|
|
|
|
UUU = UUU + 1;
|
|
|
|
|
|
|
|
|
|
|
|
long UUU1 = 0;
|
|
|
|
|
|
LLL_T.FenLei.TryRemove(N3, out UUU1);
|
|
|
|
|
|
LLL_T.FenLei.TryAdd(N3, UUU);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UDPPackageCount u = new UDPPackageCount();
|
|
|
|
|
|
u.Count = 1;
|
|
|
|
|
|
u.FenLei = new ConcurrentDictionary<string, long>();
|
|
|
|
|
|
u.FenLei.TryAdd(N3, 1);
|
|
|
|
|
|
DataTongJi.TotalCount.TryAdd(TotalKey, u);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
udpClient.Send(data, data.Length, endPoint);
|
|
|
|
|
|
// 使用同一个 Socket 发送回复
|
|
|
|
|
|
//udpClient.SendTo(data, endPoint);
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自定义序号:用于推送通讯命令
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private long GetNextCustomer()
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (_lock2)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_customer < 16000000)
|
|
|
|
|
|
{
|
|
|
|
|
|
_customer++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_customer = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//if (_customer < 16000000)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// Interlocked.Increment(ref _customer);
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
//{
|
|
|
|
|
|
// Interlocked.Exchange(ref _customer, 0);
|
|
|
|
|
|
//}
|
|
|
|
|
|
return _customer;
|
|
|
|
|
|
}
|
|
|
|
|
|
public IHostRepository HostRepository { get; set; }
|
|
|
|
|
|
public ISysHotelRepository SysHotelRepository { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步接收回调函数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ar"></param>
|
|
|
|
|
|
private void ReceiveCallback(IAsyncResult ar)
|
|
|
|
|
|
{
|
|
|
|
|
|
UdpState state = ar.AsyncState as UdpState;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IPEndPoint remoteEP111 = new IPEndPoint(IPAddress.Any, 0);
|
|
|
|
|
|
byte[] receiveBuffer111 = state.UdpClient.EndReceive(ar, ref remoteEP111);
|
|
|
|
|
|
if (receiveBuffer111.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
#region 接收的数据包总数
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalReceiveCount);
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
ReceiverContext context = new ReceiverContext(receiveBuffer111, remoteEP111, GetNextCustomer());
|
|
|
|
|
|
|
|
|
|
|
|
int length = context.Data.Length;
|
|
|
|
|
|
if (length < 3 || length != BitConverter.ToInt16(context.Data, 2))
|
|
|
|
|
|
{
|
|
|
|
|
|
//错误数据
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalErrorPackageReceiveCount);
|
|
|
|
|
|
return;//非正确的数据包
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
context.SystemHeader = DecodeSystemHeader(context.Data);
|
|
|
|
|
|
if (context.SystemHeader.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!String.Equals(new String(context.SystemHeader.Value.SystemID), SystemHeader.SYSTEM_ID, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
|
{
|
|
|
|
|
|
//错误数据
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalErrorPackageReceiveCount);
|
|
|
|
|
|
return;//非系统数据包
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//透传是新增加的
|
|
|
|
|
|
var VVV = context.SystemHeader.Value;
|
|
|
|
|
|
string KKKHNH = CacheKey.TouChuanKey;
|
|
|
|
|
|
var HHHostNo = context.SystemHeader.Value.HostNumber.ToString();
|
|
|
|
|
|
var da1 = CSRedisCacheHelper.HMGet<string>(1, KKKHNH, HHHostNo);
|
|
|
|
|
|
if (!string.IsNullOrEmpty(da1[0]))
|
|
|
|
|
|
{
|
|
|
|
|
|
string nns = Tools.ByteToString(context.Data);
|
|
|
|
|
|
if (VVV.CmdType == 0x71)
|
|
|
|
|
|
{
|
|
|
|
|
|
BLWMQTT.MQTTPublishData("blw/touchuan/report/" + HHHostNo, nns);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 只处理正确的
|
|
|
|
|
|
if (VVV.CmdType != 0xD6 && VVV.CmdType != 0x0C)
|
|
|
|
|
|
{
|
|
|
|
|
|
var hostnumber1 = VVV.HostNumber;
|
|
|
|
|
|
string hotelCode = hostnumber1.ToHotelCode().ToString();//获取酒店编码
|
|
|
|
|
|
|
|
|
|
|
|
var hostnumber2 = hostnumber1.ToString();
|
|
|
|
|
|
//时间拦截 超过2秒就不再处理
|
|
|
|
|
|
string ShiJianLanJie = CacheKey.TimeIntercept + "_" + hostnumber2;
|
|
|
|
|
|
string ShiJianLanJieSync = CacheKey.SyncTimeIntercept + "_" + hostnumber2;
|
|
|
|
|
|
if (VVV.CmdType == 0x0E)
|
|
|
|
|
|
{
|
|
|
|
|
|
//MemoryCacheHelper.Set(ShiJianLanJie, 1, DateTimeOffset.Now.AddSeconds(DataTongJi.LostPackage_Interval));
|
|
|
|
|
|
|
|
|
|
|
|
//有错误的0x19数据,所有的 在0x19数据触发后的5秒内的后续数据就不再接收
|
|
|
|
|
|
string key123 = RoomStatusReceiver.PoolOverFlowKey + "_" + hostnumber2;
|
|
|
|
|
|
var OOObj = MemoryCacheHelper.Get(key123);
|
|
|
|
|
|
if (OOObj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//错误数据
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalErrorPackageReceiveCount);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///消息ID +1
|
|
|
|
|
|
Interlocked.Increment(ref StepTongJi.EveryMessageIDNo);
|
|
|
|
|
|
//因为0E不会被拦截所以可以在这里写
|
|
|
|
|
|
if (VVV.CmdType == 0x0E || VVV.CmdType == 0X01)
|
|
|
|
|
|
{
|
|
|
|
|
|
//StepTongJi.EveryMessageID = Guid.NewGuid().ToString("N");
|
|
|
|
|
|
//计数器+1
|
|
|
|
|
|
Interlocked.Increment(ref StepTongJi.LookDataCounter);
|
|
|
|
|
|
|
|
|
|
|
|
//开始监听
|
|
|
|
|
|
Interlocked.Increment(ref StepTongJi.Every_0E_01_MessageID);
|
|
|
|
|
|
if (StepTongJi.LookDataCounter == 500)
|
|
|
|
|
|
{
|
|
|
|
|
|
//监听的ID
|
|
|
|
|
|
//Interlocked.Exchange(ref StepTongJi.GlobalListenID, StepTongJi.EveryMessageID);
|
|
|
|
|
|
|
|
|
|
|
|
context.MessageID = Guid.NewGuid().ToString("N");
|
|
|
|
|
|
context.IsMonitor = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int maxWorker = 0;
|
|
|
|
|
|
int maxIo = 0;
|
|
|
|
|
|
int availWorker = 0;
|
|
|
|
|
|
int availIo = 0;
|
|
|
|
|
|
// 获取最大线程数
|
|
|
|
|
|
ThreadPool.GetMaxThreads(out maxWorker, out maxIo);
|
|
|
|
|
|
// 获取可用线程数
|
|
|
|
|
|
ThreadPool.GetAvailableThreads(out availWorker, out availIo);
|
|
|
|
|
|
// 计算忙碌线程数
|
|
|
|
|
|
int busyWorker = maxWorker - availWorker;
|
|
|
|
|
|
int busyIo = maxIo - availIo;
|
|
|
|
|
|
int minWorker = 0;
|
|
|
|
|
|
int minIo = 0;
|
|
|
|
|
|
// 获取最小线程数
|
|
|
|
|
|
ThreadPool.GetMinThreads(out minWorker, out minIo);
|
|
|
|
|
|
|
|
|
|
|
|
int tid = Thread.CurrentThread.ManagedThreadId;
|
|
|
|
|
|
string NNN1 = string.Format("工作线程{8}: 最小={0}, 最大={1}, 可用={2}, 使用中={3},IO线程: 最小={4}, 最大={5}, 可用={6}, 使用中={7}", minWorker, maxWorker, availWorker, busyWorker, minIo, maxIo, availIo, busyIo, tid);
|
|
|
|
|
|
|
|
|
|
|
|
StepTongJi.SendInfo(0.1, NNN1, context.MessageID, context.IsMonitor);
|
|
|
|
|
|
|
|
|
|
|
|
string NNN7 = string.Format("HostNUMBER:{0},端点:{1}", hostnumber2, context.RemoteEndPoint.ToString());
|
|
|
|
|
|
StepTongJi.SendInfo(0.2, NNN7, context.MessageID, context.IsMonitor);
|
|
|
|
|
|
|
|
|
|
|
|
StepInfo s = new StepInfo();
|
|
|
|
|
|
s.Step = 1;
|
|
|
|
|
|
s.MessageId = context.MessageID;
|
|
|
|
|
|
s.StepDescription = "进入UDPCallBack";
|
|
|
|
|
|
//string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
|
|
|
|
|
|
string ti = CPUData.GetNowPrecise().ToString("yyyy-MM-dd HH:mm:ss.ffffff");
|
|
|
|
|
|
s.TriggerTime = ti;
|
|
|
|
|
|
s.Content = context.Data;
|
|
|
|
|
|
s.EveryMessageId = StepTongJi.EveryMessageIDNo;
|
|
|
|
|
|
s.Monitor_0E_01 = StepTongJi.Every_0E_01_MessageID;
|
|
|
|
|
|
s.HotelCode = hotelCode;
|
|
|
|
|
|
s.HostNumber = hostnumber2;
|
|
|
|
|
|
|
|
|
|
|
|
string NNN = Newtonsoft.Json.JsonConvert.SerializeObject(s);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-roomstatus-monitor", NNN);
|
|
|
|
|
|
|
|
|
|
|
|
Interlocked.Exchange(ref StepTongJi.LookDataCounter, 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (VVV.CmdType == 0x08)
|
|
|
|
|
|
{
|
|
|
|
|
|
MemoryCacheHelper.Set(ShiJianLanJieSync, 1, DateTimeOffset.Now.AddSeconds(DataTongJi.LostPackage_Interval));
|
|
|
|
|
|
}
|
|
|
|
|
|
if (VVV.CmdType == 0x02)
|
|
|
|
|
|
{
|
|
|
|
|
|
MemoryCacheHelper.Set(ShiJianLanJie, 1, DateTimeOffset.Now.AddSeconds(50));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (VVV.CmdType == 0x01)
|
|
|
|
|
|
{
|
|
|
|
|
|
//升级之后,会上报注册指令,不能被跳过
|
|
|
|
|
|
string Key = "Upgrade_UpdateSQL_" + hostnumber1;
|
|
|
|
|
|
object OOO1 = MemoryCacheHelper.Get(Key);
|
|
|
|
|
|
if (OOO1 == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//string RegisterKey2 = "SearchHostFilter";
|
|
|
|
|
|
|
|
|
|
|
|
//上报注册指令太快会被拦截
|
|
|
|
|
|
//string KKK = "RegisterKey_" + hostnumber1;
|
|
|
|
|
|
//object OOO = MemoryCacheHelper.Get(KKK);
|
|
|
|
|
|
//if (OOO != null)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// RCUHost.RCUHostCommon.tools.LanJieData(RegisterKey2, hotelCode);
|
|
|
|
|
|
// return;
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string LanJieKey = "Intercept";
|
|
|
|
|
|
ConcurrentBag<string> RoomNumberList = null;
|
|
|
|
|
|
bool isexists = DataTongJi.BlockLowerMachineList.TryGetValue(hotelCode, out RoomNumberList);
|
|
|
|
|
|
//如果存在数据
|
|
|
|
|
|
if (isexists)
|
|
|
|
|
|
{
|
|
|
|
|
|
//如果 设备序号存在就过滤掉
|
|
|
|
|
|
if (RoomNumberList != null && RoomNumberList.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
//只过滤这些数据
|
|
|
|
|
|
if (RoomNumberList.ToList().Contains(hostnumber1.ToString()))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (VVV.CmdType == 0x0E)
|
|
|
|
|
|
{
|
|
|
|
|
|
string KeyFilter = "StatusFilter";
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(KeyFilter, hotelCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
LanJieData(LanJieKey, hotelCode);
|
|
|
|
|
|
StepTongJi.SendInfo(1.01, "进入黑名单,不再有后续处理", context.MessageID, context.IsMonitor);
|
|
|
|
|
|
}
|
|
|
|
|
|
//如果不存在就处理
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
GaiXie g = new GaiXie();
|
|
|
|
|
|
g.Data = receiveBuffer111;
|
|
|
|
|
|
g.IPEndPoint = remoteEP111.ToString();
|
|
|
|
|
|
var data = Newtonsoft.Json.JsonConvert.SerializeObject(g);
|
|
|
|
|
|
CSRedisCacheHelper.StreamAdd(1, "All_UDPPackage_Data", data);
|
|
|
|
|
|
//ProcessData(context, hotelCode);
|
|
|
|
|
|
//var ts1 = new Tuple<ReceiverContext, string>(context, hotelCode);
|
|
|
|
|
|
//Task.Factory.StartNew((actor_state) =>
|
|
|
|
|
|
// {
|
|
|
|
|
|
// var gg = actor_state as Tuple<ReceiverContext, string>;
|
|
|
|
|
|
// ProcessData(gg.Item1, gg.Item2);
|
|
|
|
|
|
// }, ts1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (VVV.CmdType == 0x0E)
|
|
|
|
|
|
{
|
|
|
|
|
|
string KeyFilter = "StatusFilter";
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(KeyFilter, hotelCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
//如果存在,且 设备列表为0
|
|
|
|
|
|
LanJieData(LanJieKey, hotelCode);
|
|
|
|
|
|
StepTongJi.SendInfo(1.01, "进入黑名单,不再有后续处理", context.MessageID, context.IsMonitor);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//ProcessData(context, hotelCode);
|
|
|
|
|
|
|
|
|
|
|
|
GaiXie g = new GaiXie();
|
|
|
|
|
|
g.Data = receiveBuffer111;
|
|
|
|
|
|
g.IPEndPoint = remoteEP111.ToString();
|
|
|
|
|
|
var data = Newtonsoft.Json.JsonConvert.SerializeObject(g);
|
|
|
|
|
|
CSRedisCacheHelper.StreamAdd(1, "All_UDPPackage_Data", data);
|
|
|
|
|
|
var ts1 = new Tuple<ReceiverContext, string>(context, hotelCode);
|
|
|
|
|
|
//Task.Factory.StartNew((actor_state) =>
|
|
|
|
|
|
// {
|
|
|
|
|
|
// var gg = actor_state as Tuple<ReceiverContext, string>;
|
|
|
|
|
|
// ProcessData(gg.Item1, gg.Item2);
|
|
|
|
|
|
// }, ts1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//错误数据
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalErrorPackageReceiveCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error("统计Error:" + ex.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Interlocked.Increment(ref YUANZI_TongJi.TotalErrorPackageReceiveCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error(string.Format("接收数据失败:{0}", ex.ToString()));
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (this.udpClient != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
state.UdpClient.BeginReceive(ReceiveCallback, new UdpState(this.udpClient));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void LanJieData(string Key11, string hotelCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
var Key = "UDPPackage_" + Key11.ToString();
|
|
|
|
|
|
|
|
|
|
|
|
UDPPackageCount LLL = null;
|
|
|
|
|
|
DataTongJi.TotalCount.TryGetValue(Key, out LLL);
|
|
|
|
|
|
if (LLL != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dic = LLL.FenLei;
|
|
|
|
|
|
LLL.Count = LLL.Count + 1;
|
|
|
|
|
|
long hotel_count = 0;
|
|
|
|
|
|
if (dic.TryGetValue(hotelCode, out hotel_count))
|
|
|
|
|
|
{
|
|
|
|
|
|
dic[hotelCode] = dic[hotelCode] + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
dic.TryAdd(hotelCode, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UDPPackageCount u = new UDPPackageCount();
|
|
|
|
|
|
u.Count = 1;
|
|
|
|
|
|
|
|
|
|
|
|
var list = new ConcurrentDictionary<string, long>();
|
|
|
|
|
|
list.TryAdd(hotelCode, 1);
|
|
|
|
|
|
|
|
|
|
|
|
u.FenLei = list;
|
|
|
|
|
|
|
|
|
|
|
|
DataTongJi.TotalCount.TryAdd(Key, u);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static Status NewStatusParse(Stream stream)
|
|
|
|
|
|
{
|
|
|
|
|
|
Status roomStatus = new Status();
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 重要:将流的位置重置到开始,以便读取
|
|
|
|
|
|
//stream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
|
using (BinaryReader reader = new BinaryReader(stream))
|
|
|
|
|
|
{
|
|
|
|
|
|
roomStatus.SysLock = reader.ReadBoolean(); //RCU是否锁定:0/否,1/是
|
|
|
|
|
|
roomStatus.CardType = reader.ReadByte(); //房卡类型:0/无人,1/有人,2/客人,3/经理,4/服务员
|
|
|
|
|
|
roomStatus.Door = reader.ReadBoolean(); //门磁开关:1/开,2/关
|
|
|
|
|
|
roomStatus.ElecQty = reader.ReadUInt16(); //门锁电量,单位:MV
|
|
|
|
|
|
roomStatus.HostTemp = reader.ReadByte(); //主机温度
|
|
|
|
|
|
//空调数量,默认0,新的回路方式,此处无用,兼容老版本
|
|
|
|
|
|
int airConditionNumber = reader.ReadByte();
|
|
|
|
|
|
for (int i = 0; i < airConditionNumber; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
byte airNo = reader.ReadByte();
|
|
|
|
|
|
if (!roomStatus.AirConditions.ContainsKey(airNo))
|
|
|
|
|
|
{
|
|
|
|
|
|
roomStatus.AirConditions[airNo] = new AirConditionStatus();
|
|
|
|
|
|
}
|
|
|
|
|
|
roomStatus.AirConditions[airNo].AirNo = airNo;
|
|
|
|
|
|
roomStatus.AirConditions[airNo].CurrentTemp = reader.ReadSByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].SettingTemp = reader.ReadSByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].OnOff = reader.ReadBoolean();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].Speed = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].Mode = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].Valve = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].CompensatoryTemp = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].KeepTemp = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].ColdHotMode = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].DeadTemp = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].HotDevition = reader.ReadByte();
|
|
|
|
|
|
roomStatus.AirConditions[airNo].ColdDevition = reader.ReadByte();
|
|
|
|
|
|
}
|
|
|
|
|
|
//设备状态数量,包含所有回路状态
|
|
|
|
|
|
int deviceNumber = reader.ReadByte();
|
|
|
|
|
|
|
|
|
|
|
|
long originalPosition = reader.BaseStream.Position;
|
|
|
|
|
|
// 读取前先记录当前位置
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
//0x19数据缓冲区异常问题处理
|
|
|
|
|
|
//0x19 取电数据不处理
|
|
|
|
|
|
//非0x19 取电数据处理,但是不触发 欢迎词
|
|
|
|
|
|
for (int i = 0; i < deviceNumber; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var QA = reader.ReadBytes(4);
|
|
|
|
|
|
var Status = reader.ReadUInt16();
|
|
|
|
|
|
|
|
|
|
|
|
string address = new DeviceAddress(QA).ToString();
|
|
|
|
|
|
if (!roomStatus.Devices.ContainsKey(address))
|
|
|
|
|
|
{
|
|
|
|
|
|
roomStatus.Devices[address] = new Device();
|
|
|
|
|
|
}
|
|
|
|
|
|
roomStatus.Devices[address].Address = address;//设备地址
|
|
|
|
|
|
roomStatus.Devices[address].StatusReceiver = Status;//设备状态改为2个字节,Modified By 20181213
|
|
|
|
|
|
originalPosition = reader.BaseStream.Position;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 发生异常时回退到原始位置
|
|
|
|
|
|
reader.BaseStream.Position = originalPosition;
|
|
|
|
|
|
//logger.Error("device_count error");
|
|
|
|
|
|
}
|
|
|
|
|
|
return roomStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly List<byte> TakeCardSeq = new List<byte>() { 0x04, 0x00, 0x01 };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Reply(ReceiverContext context, byte[] framenolist)
|
|
|
|
|
|
{
|
|
|
|
|
|
var headerLen = StructConverter.SizeOf(context.SystemHeader);
|
|
|
|
|
|
var headerData = new byte[headerLen + 2];
|
|
|
|
|
|
Array.Copy(context.Data, headerData, headerLen);
|
|
|
|
|
|
headerData[2] = 0x11;
|
|
|
|
|
|
headerData[3] = 0x00;
|
|
|
|
|
|
|
|
|
|
|
|
headerData[9] = framenolist[0];
|
|
|
|
|
|
headerData[10] = framenolist[1];
|
|
|
|
|
|
Send(headerData, context.RemoteEndPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void ReplyWithContent(ReceiverContext context, byte[] content, byte[] framenolist)
|
|
|
|
|
|
{
|
|
|
|
|
|
var headerLen = StructConverter.SizeOf(context.SystemHeader);
|
|
|
|
|
|
var headerData = new byte[headerLen + 2];
|
|
|
|
|
|
Array.Copy(context.Data, headerData, headerLen);
|
|
|
|
|
|
headerData[2] = 0x12;
|
|
|
|
|
|
headerData[3] = 0x00;
|
|
|
|
|
|
|
|
|
|
|
|
headerData[9] = framenolist[0];
|
|
|
|
|
|
headerData[10] = framenolist[1];
|
|
|
|
|
|
var HHH = headerData.ToList();
|
|
|
|
|
|
HHH.AddRange(content);
|
|
|
|
|
|
Send(HHH.ToArray<byte>(), context.RemoteEndPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
public static string SameStatus0E = "处理过0E";
|
|
|
|
|
|
public static string SameStatus01 = "处理过01";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 欢迎词触发
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="flag1"></param>
|
|
|
|
|
|
/// <param name="hotelcode1"></param>
|
|
|
|
|
|
/// <param name="HostNumberOnly1"></param>
|
|
|
|
|
|
private void VoiceRobotTrigger(int flag1, string hotelcode1, string HostNumberOnly1)
|
|
|
|
|
|
{
|
|
|
|
|
|
var TS = new Tuple<int, string, string>(flag1, hotelcode1, HostNumberOnly1);
|
|
|
|
|
|
Task.Factory.StartNew((state1) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var UUU = (Tuple<int, string, string>)state1;
|
|
|
|
|
|
int flag = UUU.Item1;
|
|
|
|
|
|
string hotelcode = UUU.Item2;
|
|
|
|
|
|
string HostNumberOnly = UUU.Item3;
|
|
|
|
|
|
Host host = null;
|
|
|
|
|
|
string Key = CacheKey.HostInfo_Key_HostNumber + "_" + HostNumberOnly;
|
|
|
|
|
|
object obj = MemoryCacheHelper.Get(Key);
|
|
|
|
|
|
if (obj != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
host = obj as Host;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Host host_O = HostRepository.GetByHostNumber(HostNumberOnly);
|
|
|
|
|
|
MemoryCacheHelper.SlideSet(Key, host_O);
|
|
|
|
|
|
host = host_O;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (host != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
string roomnumber = host.RoomNumber;
|
|
|
|
|
|
|
|
|
|
|
|
//小度
|
|
|
|
|
|
string XiaoDuCUID = host.XiaoDuCUID;
|
|
|
|
|
|
|
|
|
|
|
|
//天猫
|
|
|
|
|
|
string TianMaoCUID = host.TianMaoCUID;
|
|
|
|
|
|
|
|
|
|
|
|
//欢迎词
|
|
|
|
|
|
string WelcomeSpeech = host.SysHotel.WelcomeSpeech;
|
2025-12-23 10:08:11 +08:00
|
|
|
|
string WelcomeBGM = host.SysHotel.WelcomeBGM;
|
2025-12-11 09:17:16 +08:00
|
|
|
|
|
|
|
|
|
|
//欢送词
|
|
|
|
|
|
string GoodbyeSpeech = host.SysHotel.GoodbyeSpeech;
|
|
|
|
|
|
|
|
|
|
|
|
//断电重置
|
|
|
|
|
|
bool IsPowerOffResetXiaoDu = host.SysHotel.IsPowerOffResetXiaoDu;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//1、如果有绑定小度,小度处理
|
|
|
|
|
|
if (!string.IsNullOrEmpty(XiaoDuCUID))
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 小度
|
|
|
|
|
|
string accessToken1 = SysOauth2Repository.GetXiaoDuToken();
|
|
|
|
|
|
if (!string.IsNullOrEmpty(accessToken1))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (flag == 1 && !string.IsNullOrEmpty(WelcomeSpeech))//取电打开时,播放欢迎词
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var ttt = new Tuple<string, string, string, string, string>(accessToken1, XiaoDuCUID, WelcomeSpeech, hotelcode, roomnumber);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var tuple_a = state as Tuple<string, string, string, string, string>;
|
|
|
|
|
|
string accessToken = tuple_a.Item1;
|
|
|
|
|
|
|
|
|
|
|
|
var myarray = tuple_a.Item2.Split(',');
|
|
|
|
|
|
var a1 = tuple_a.Item3;
|
|
|
|
|
|
var a2 = tuple_a.Item4;
|
|
|
|
|
|
var a3 = tuple_a.Item5;
|
|
|
|
|
|
|
|
|
|
|
|
//foreach (string cuid in host.XiaoDuCUID.Split(','))//多个小度英文逗号隔开
|
|
|
|
|
|
foreach (string cuid in myarray)//多个小度英文逗号隔开
|
|
|
|
|
|
{
|
|
|
|
|
|
//XiaoDuOperation.UploadWebhook(accessToken, cuid, host.SysHotel.WelcomeSpeech, host.SysHotel.Code, host.RoomNumber);
|
|
|
|
|
|
XiaoDuOperation.UploadWebhook(accessToken, cuid, a1, a2, a3);
|
|
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = a2;
|
|
|
|
|
|
w1.RoomNumber = a3;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.XiaoDu;
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "小度";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "欢迎词";
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, ttt);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (flag == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsPowerOffResetXiaoDu)//断电重置小度
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var ttt = new Tuple<string, string, string, string, string>(accessToken1, XiaoDuCUID, WelcomeSpeech, hotelcode, roomnumber);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var tuple_a = state as Tuple<string, string, string, string, string>;
|
|
|
|
|
|
string accessToken = tuple_a.Item1;
|
|
|
|
|
|
var myarray = tuple_a.Item2.Split(',');
|
|
|
|
|
|
var a1 = tuple_a.Item3;
|
|
|
|
|
|
var a2 = tuple_a.Item4;
|
|
|
|
|
|
var a3 = tuple_a.Item5;
|
|
|
|
|
|
foreach (string cuid in myarray)//多个小度英文逗号隔开
|
|
|
|
|
|
{
|
|
|
|
|
|
//XiaoDuOperation.PostWebRequestToXiaoDu(accessToken, cuid, new XiaoDuParamJson() { method = "reset" }, host.SysHotel.Code, host.RoomNumber);//重置小度
|
|
|
|
|
|
XiaoDuOperation.PostWebRequestToXiaoDu(accessToken, cuid, new XiaoDuParamJson() { method = "reset" }, a2, a3);//重置小度
|
|
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = a2;
|
|
|
|
|
|
w1.RoomNumber = a3;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.XiaoDu;
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "小度";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "断电重置";
|
|
|
|
|
|
//w1.ActionData = new HttpActionData() { RequestData = w2 };
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, ttt);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!string.IsNullOrEmpty(GoodbyeSpeech))//断电,播放离房提示
|
|
|
|
|
|
{
|
|
|
|
|
|
var ttt = new Tuple<string, string, string, string, string>(accessToken1, XiaoDuCUID, WelcomeSpeech, hotelcode, roomnumber);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var tuple_a = state as Tuple<string, string, string, string, string>;
|
|
|
|
|
|
string accessToken = tuple_a.Item1;
|
|
|
|
|
|
var myarray = tuple_a.Item2.Split(',');
|
|
|
|
|
|
var a1 = tuple_a.Item3;
|
|
|
|
|
|
var a2 = tuple_a.Item4;
|
|
|
|
|
|
var a3 = tuple_a.Item5;
|
|
|
|
|
|
foreach (string cuid in myarray)//多个小度英文逗号隔开
|
|
|
|
|
|
{
|
|
|
|
|
|
XiaoDuOperation.UploadWebhook(accessToken, cuid, a1, a2, a3);
|
|
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = a2;
|
|
|
|
|
|
w1.RoomNumber = a3;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.XiaoDu;
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "小度";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "欢送词";
|
|
|
|
|
|
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
//w1.ActionData = new HttpActionData() { RequestData = w2 };
|
|
|
|
|
|
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, ttt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//2、如果有绑定天猫精灵,天猫精灵处理
|
|
|
|
|
|
if (!string.IsNullOrEmpty(TianMaoCUID))
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 天猫
|
|
|
|
|
|
if (flag == 1 && !string.IsNullOrEmpty(WelcomeSpeech))//取电打开时,播放欢迎词
|
|
|
|
|
|
{
|
2025-12-23 10:08:11 +08:00
|
|
|
|
var TTT = new Tuple<string, string, string, string, string>(TianMaoCUID, WelcomeSpeech, hotelcode, roomnumber, WelcomeBGM);
|
2025-12-11 09:17:16 +08:00
|
|
|
|
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
2025-12-23 10:08:11 +08:00
|
|
|
|
var hhh = state as Tuple<string, string, string, string, string>;
|
2025-12-11 09:17:16 +08:00
|
|
|
|
var a = hhh.Item1.Split(',');
|
|
|
|
|
|
|
|
|
|
|
|
var b = hhh.Item2;
|
|
|
|
|
|
var c = hhh.Item3;
|
|
|
|
|
|
var d = hhh.Item4;
|
2025-12-23 10:08:11 +08:00
|
|
|
|
var e = hhh.Item5;
|
2025-12-11 09:17:16 +08:00
|
|
|
|
|
|
|
|
|
|
foreach (string cuid in a)//多个英文逗号隔开
|
|
|
|
|
|
{
|
2025-12-23 14:33:40 +08:00
|
|
|
|
//if (!string.IsNullOrEmpty(e))
|
|
|
|
|
|
//{
|
|
|
|
|
|
// string ffg = "https://www.boonlive-rcu.com/welcomebgm/" + e;
|
|
|
|
|
|
// TianMaoOperation.PostWebRequestToTianMao("PushWelcome",
|
|
|
|
|
|
// Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], RoomNo = cuid.Split('&')[1], WelcomeText = b, MusicUrl = ffg }), c, d);//通知天猫精灵播放欢迎词
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
//{
|
|
|
|
|
|
// TianMaoOperation.PostWebRequestToTianMao("PushWelcome",
|
|
|
|
|
|
// Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], RoomNo = cuid.Split('&')[1], WelcomeText = b }), c, d);//通知天猫精灵播放欢迎词
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
TianMaoOperation.PostWebRequestToTianMao("PushWelcome",
|
|
|
|
|
|
Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], RoomNo = cuid.Split('&')[1], WelcomeText = b }), c, d);//通知天猫精灵播放欢迎词
|
2025-12-11 09:17:16 +08:00
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = c;
|
|
|
|
|
|
w1.RoomNumber = d;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.TianMao;
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "天猫";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "欢送词";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
//w1.ActionData = new HttpActionData() { RequestData = w2 };
|
|
|
|
|
|
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TTT);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (flag == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsPowerOffResetXiaoDu)//断电重置
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var TTT = new Tuple<string, string, string, string>(TianMaoCUID, WelcomeSpeech, hotelcode, roomnumber);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var hhh = state as Tuple<string, string, string, string>;
|
|
|
|
|
|
var a = hhh.Item1.Split(',');
|
|
|
|
|
|
|
|
|
|
|
|
var b = hhh.Item2;
|
|
|
|
|
|
var c = hhh.Item3;
|
|
|
|
|
|
var d = hhh.Item4;
|
|
|
|
|
|
foreach (string cuid in a)//多个英文逗号隔开
|
|
|
|
|
|
{
|
|
|
|
|
|
TianMaoOperation.PostWebRequestToTianMao("CheckoutWithAK",
|
|
|
|
|
|
Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], RoomNo = cuid.Split('&')[1] }), c, d);//重置天猫精灵
|
|
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = c;
|
|
|
|
|
|
w1.RoomNumber = d;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.TianMao;
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "天猫";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "断电重置";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
//w1.ActionData = new HttpActionData() { RequestData = w2 };
|
|
|
|
|
|
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TTT);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!string.IsNullOrEmpty(GoodbyeSpeech))//取电关闭时,播放离房提示
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
var TTT = new Tuple<string, string, string, string>(TianMaoCUID, WelcomeSpeech, hotelcode, roomnumber);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var hhh = state as Tuple<string, string, string, string>;
|
|
|
|
|
|
var a = hhh.Item1.Split(',');
|
|
|
|
|
|
|
|
|
|
|
|
var b = hhh.Item2;
|
|
|
|
|
|
var c = hhh.Item3;
|
|
|
|
|
|
var d = hhh.Item4;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (string cuid in a)//多个英文逗号隔开
|
|
|
|
|
|
{
|
|
|
|
|
|
TianMaoOperation.PostWebRequestToTianMao("PushWelcome",
|
|
|
|
|
|
Newtonsoft.Json.JsonConvert.SerializeObject(new
|
|
|
|
|
|
{
|
|
|
|
|
|
HotelId = cuid.Split('&')[0],
|
|
|
|
|
|
RoomNo = cuid.Split('&')[1],
|
|
|
|
|
|
WelcomeText = b
|
|
|
|
|
|
}), c, d);//通知天猫精灵播放离房提示
|
|
|
|
|
|
|
|
|
|
|
|
Interface3Log w1 = new Interface3Log();
|
|
|
|
|
|
w1.HotelCode = c;
|
|
|
|
|
|
w1.RoomNumber = d;
|
|
|
|
|
|
w1.TriggerTime = DateTime.Now;
|
|
|
|
|
|
w1.CommandType = ChangLiangValue.TianMao;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WelcomeAction w2 = new WelcomeAction();
|
|
|
|
|
|
w2.VoiceDeviceClass = "天猫";
|
|
|
|
|
|
w2.CUID = cuid;
|
|
|
|
|
|
w2.CommandType = "欢送词";
|
|
|
|
|
|
|
|
|
|
|
|
w1.ActionData = new HttpActionData() { RequestData = Newtonsoft.Json.JsonConvert.SerializeObject(w2) };
|
|
|
|
|
|
//w1.ActionData = new HttpActionData() { RequestData = w2 };
|
|
|
|
|
|
var q1 = Newtonsoft.Json.JsonConvert.SerializeObject(w1);
|
|
|
|
|
|
CSRedisCacheHelper.Publish(CacheKey.InvokeHttpInterface, q1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, TTT);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}, TS);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//private static readonly RecyclableMemoryStreamManager manager = new RecyclableMemoryStreamManager();
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 处理数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="context"></param>
|
|
|
|
|
|
//private void ProcessData(ReceiverContext context111, string hotelCode)
|
|
|
|
|
|
private void ProcessData(GaiXie gga)
|
|
|
|
|
|
{
|
|
|
|
|
|
//GaiXie gga = new GaiXie();
|
|
|
|
|
|
string[] III = gga.IPEndPoint.Split(':');
|
|
|
|
|
|
int PPP = int.Parse(III[1]);
|
|
|
|
|
|
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(III[0]), PPP);
|
|
|
|
|
|
ReceiverContext context111 = new ReceiverContext(gga.Data, ip, GetNextCustomer());
|
|
|
|
|
|
context111.SystemHeader = DecodeSystemHeader(context111.Data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte cmdType = context111.SystemHeader.Value.CmdType;
|
|
|
|
|
|
ushort MyFrameNO = context111.SystemHeader.Value.FrameNo;
|
|
|
|
|
|
|
|
|
|
|
|
byte[] framenolist = BitConverter.GetBytes(MyFrameNO);
|
|
|
|
|
|
string IP_PORTStr = context111.RemoteEndPoint.ToString();
|
|
|
|
|
|
string HostNNN = context111.SystemHeader.Value.HostNumber.ToString();
|
|
|
|
|
|
string CODE = context111.SystemHeader.Value.HostNumber.ToHotelCode().ToString();
|
|
|
|
|
|
string hotelCode = CODE;
|
|
|
|
|
|
string EndPoint = context111.RemoteEndPoint.ToString();
|
|
|
|
|
|
//if (cmdType != 0x01)
|
|
|
|
|
|
//在线状态 不排队 注册0x01
|
|
|
|
|
|
if (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 只要有数据包,就是心跳
|
|
|
|
|
|
|
|
|
|
|
|
string Key = context111.SystemHeader.Value.HostNumber.ToString();
|
|
|
|
|
|
string EEE = CSRedisCacheHelper.Get<string>(Key);
|
|
|
|
|
|
if (string.IsNullOrEmpty(EEE))
|
|
|
|
|
|
{
|
|
|
|
|
|
OnOffLineData o = new OnOffLineData();
|
|
|
|
|
|
o.HostNumber = Key;
|
|
|
|
|
|
o.HotelCode = hotelCode;
|
|
|
|
|
|
o.CurrentStatus = "on";
|
|
|
|
|
|
o.CurrentTime = DateTime.Now;
|
|
|
|
|
|
o.EndPoint = context111.RemoteEndPoint.ToString();
|
|
|
|
|
|
//新来的数据
|
|
|
|
|
|
var n = Newtonsoft.Json.JsonConvert.SerializeObject(o);
|
|
|
|
|
|
//CSRedisCacheHelper.Publish("redis-on_off_line", n);
|
|
|
|
|
|
}
|
|
|
|
|
|
string EndPointStr = context111.RemoteEndPoint.ToString();
|
|
|
|
|
|
CSRedisCacheHelper.Set(context111.SystemHeader.Value.HostNumber.ToString(), context111.RemoteEndPoint.Address.ToString() + ":" + context111.RemoteEndPoint.Port.ToString());//主机编码
|
|
|
|
|
|
|
|
|
|
|
|
string KKF = context111.SystemHeader.Value.HostNumber.ToString();
|
|
|
|
|
|
|
|
|
|
|
|
RCUOnLineExtra xe = new RCUOnLineExtra();
|
|
|
|
|
|
xe.CurrentDateTime = DateTime.Now;
|
|
|
|
|
|
xe.HotelCode = hotelCode;
|
|
|
|
|
|
if (!DataTongJi.ONLINERCU.ContainsKey(KKF))
|
|
|
|
|
|
{
|
|
|
|
|
|
DataTongJi.ONLINERCU.TryAdd(KKF, xe);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
RCUOnLineExtra outv;
|
|
|
|
|
|
DataTongJi.ONLINERCU.TryRemove(KKF, out outv);
|
|
|
|
|
|
DataTongJi.ONLINERCU.TryAdd(KKF, xe);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//RCUHost.RCUHostCommon.tools.LanJieData(KKK, hotelCode);
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 如果是0E 01就直接回复
|
|
|
|
|
|
//36 就是新版本的0E
|
|
|
|
|
|
//if (cmdType == 0x0E || cmdType == 0x01)
|
|
|
|
|
|
if (cmdType == 0x0E || cmdType == 0x01 || cmdType == 0x36)
|
|
|
|
|
|
{
|
|
|
|
|
|
StepTongJi.SendInfo(1.1, "0E 01指令回复开始", context111.MessageID, context111.IsMonitor);
|
|
|
|
|
|
Reply(context111, framenolist);
|
|
|
|
|
|
StepTongJi.SendInfo(1.2, "0E 01指令回复结束", context111.MessageID, context111.IsMonitor);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
byte[] OriginalByte = context111.Data;
|
|
|
|
|
|
|
|
|
|
|
|
int offset = StructConverter.SizeOf(context111.SystemHeader);
|
|
|
|
|
|
int length = context111.Data.Length - offset - 2;
|
|
|
|
|
|
|
|
|
|
|
|
string HostNUMBER = HostNNN;
|
|
|
|
|
|
if (length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 新版协议
|
|
|
|
|
|
if (cmdType == 0x32 || cmdType == 0x33 || cmdType == 0x34 || cmdType == 0x35 || cmdType == 0x36)
|
|
|
|
|
|
{
|
|
|
|
|
|
NewXieYi(context111, hotelCode, HostNNN, framenolist, cmdType, EndPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
#region 01指令
|
|
|
|
|
|
if (cmdType == 0x01)
|
|
|
|
|
|
{
|
|
|
|
|
|
//注册指令
|
|
|
|
|
|
//AA 55 68 00 54 33 53 41 01 FF FF 95 05 68 E4
|
|
|
|
|
|
//00 00 00 00 FF FF FE 00 AC 14 00 FE 0D 0D 34 D0 B8 11 68 E4 43 31 46 5F 41 5F 4C 34 5F 33 35 5F 32 34 30 38 32 39 00 00 26 00 00 DF 05 05 05 CB AB B4 B2 B1 A6 D2 D7 00 00 00 00 00 00 00 00 31 30 31 37 00 00 00 00 00 00 00 00 00 00 00 00 F6 12 00 00 96 B0 00 00
|
|
|
|
|
|
//3D 89
|
|
|
|
|
|
//升级之后,会上报注册指令,不能被跳过
|
|
|
|
|
|
string Key = "Upgrade_UpdateSQL_" + HostNUMBER;
|
|
|
|
|
|
object OOO1 = MemoryCacheHelper.Get(Key);
|
|
|
|
|
|
if (OOO1 == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int lll = OriginalByte.Length;
|
|
|
|
|
|
var A1 = OriginalByte.Skip(15).Take(lll - 15 - 2).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
string YiJingChuLiGuo = CacheKey.AllReadyDealWith01_Prefix + "_" + HostNUMBER;
|
|
|
|
|
|
object ooo = MemoryCacheHelper.Get(YiJingChuLiGuo);
|
|
|
|
|
|
if (ooo != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
byte[] bbb = ooo as byte[];
|
|
|
|
|
|
if (A1.SequenceEqual<byte>(bbb))
|
|
|
|
|
|
{
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(SameStatus01, hotelCode);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 0E
|
|
|
|
|
|
if (cmdType == 0x0E)
|
|
|
|
|
|
{
|
|
|
|
|
|
//using (var stream = manager.GetStream())
|
|
|
|
|
|
//{
|
|
|
|
|
|
//stream.Write(context111.Data, offset, length);
|
|
|
|
|
|
//}
|
|
|
|
|
|
using (MemoryStream stream = new MemoryStream(context111.Data, offset, length))
|
|
|
|
|
|
{
|
|
|
|
|
|
Status status = NewStatusParse(stream);
|
|
|
|
|
|
if (status != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var LG = status.Devices;
|
|
|
|
|
|
Device UXV = null;
|
|
|
|
|
|
//找出取电
|
|
|
|
|
|
LG.TryGetValue("004000001", out UXV);
|
|
|
|
|
|
if (UXV != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
byte bfg = Convert.ToByte(UXV.StatusReceiver);
|
|
|
|
|
|
|
|
|
|
|
|
string KKK1 = CacheKey.TakeCardOnLine + "_" + HostNUMBER;
|
|
|
|
|
|
CommonEntity.DataTongJi.MTakeCardData t = new DataTongJi.MTakeCardData();
|
|
|
|
|
|
t.HostNUMBER = HostNUMBER;
|
|
|
|
|
|
t.HotelCode = hotelCode;
|
|
|
|
|
|
t.Status = bfg;
|
|
|
|
|
|
t.LastUpdateTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
var data = CSRedisCacheHelper.Get_Partition<CommonEntity.DataTongJi.MTakeCardData>(KKK1, 5);
|
|
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//说明是拔卡
|
|
|
|
|
|
if ((data.Status == 0x01 && bfg == 0x02))
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Newtonsoft.Json.JsonConvert.SerializeObject(t);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-takecard_change", sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
//插卡
|
|
|
|
|
|
if ((data.Status == 0x02 && bfg == 0x01))
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Newtonsoft.Json.JsonConvert.SerializeObject(t);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-takecard_change", sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Newtonsoft.Json.JsonConvert.SerializeObject(t);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-takecard_change", sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CSRedisCacheHelper.Set_Partition(KKK1, t, 5);
|
|
|
|
|
|
|
|
|
|
|
|
if (DataTongJi.TakeCardOnLine.ContainsKey(HostNUMBER))
|
|
|
|
|
|
{
|
|
|
|
|
|
CommonEntity.DataTongJi.MTakeCardData ooo = null;
|
|
|
|
|
|
DataTongJi.TakeCardOnLine.TryRemove(HostNUMBER, out ooo);
|
|
|
|
|
|
DataTongJi.TakeCardOnLine.TryAdd(HostNUMBER, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DataTongJi.TakeCardOnLine.TryAdd(HostNUMBER, t);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (status.Devices.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in status.Devices)
|
|
|
|
|
|
{
|
|
|
|
|
|
string ItemKKK = item.Key;
|
|
|
|
|
|
Device VVV = item.Value;
|
|
|
|
|
|
if (item.Key.StartsWith("004000") && !item.Key.Equals("004000001"))
|
|
|
|
|
|
{
|
|
|
|
|
|
CommonEntity.DataTongJi.OtherServiceInfo oth = new DataTongJi.OtherServiceInfo();
|
|
|
|
|
|
oth.HotelCode = hotelCode;
|
|
|
|
|
|
oth.HostNumber = HostNUMBER;
|
|
|
|
|
|
oth.LastUpdateTime = DateTime.Now;
|
|
|
|
|
|
oth.StatusReceiver = item.Value.StatusReceiver;
|
|
|
|
|
|
oth.Address = item.Value.Address;
|
|
|
|
|
|
|
|
|
|
|
|
string NKKK1 = CacheKey.ServiceInfoOther + "_" + HostNUMBER + "_" + item.Key;
|
|
|
|
|
|
var data = CSRedisCacheHelper.Get_Partition<CommonEntity.DataTongJi.OtherServiceInfo>(NKKK1, 5);
|
|
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort UUU = data.StatusReceiver;
|
|
|
|
|
|
//说明是有变化
|
|
|
|
|
|
if (UUU != item.Value.StatusReceiver)
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Newtonsoft.Json.JsonConvert.SerializeObject(oth);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-serviceinfo_change", sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
string sss = Newtonsoft.Json.JsonConvert.SerializeObject(oth);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-serviceinfo_change", sss);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (status.Devices.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var LLL = status.Devices.OrderBy(A => A.Key);
|
|
|
|
|
|
var KKK1 = LLL.Select(A => A.Key).ToArray();
|
|
|
|
|
|
var KKK2 = LLL.Select(A => A.Value.StatusReceiver.ToString("00")).ToArray();
|
|
|
|
|
|
if (KKK1.Length > 0 && KKK2.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var VVV1 = string.Join("", KKK1);
|
|
|
|
|
|
var VVV2 = string.Join("", KKK2);
|
|
|
|
|
|
|
|
|
|
|
|
//StringBuilder sb = new StringBuilder();
|
|
|
|
|
|
//sb.Clear();
|
|
|
|
|
|
//sb.Append(VVV1);
|
|
|
|
|
|
//sb.Append(VVV2);
|
2025-12-23 10:08:11 +08:00
|
|
|
|
string sb = string.Concat(VVV1, VVV2);
|
2025-12-11 09:17:16 +08:00
|
|
|
|
string YiJingChuLiGuo = CacheKey.AllReadyDealWith0E_Prefix + "_" + HostNUMBER;
|
|
|
|
|
|
object data = MemoryCacheHelper.Get(YiJingChuLiGuo);
|
|
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
string shuju = data.ToString();
|
|
|
|
|
|
if (shuju.Equals(sb))
|
|
|
|
|
|
{
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(SameStatus0E, hotelCode);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error("取电数据上报出问题了:" + ex.Message);
|
|
|
|
|
|
logger.Error("取电数据上报出问题了:" + ex.StackTrace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 故意让UDP丢掉的数据包总数
|
|
|
|
|
|
//insertcard 保留
|
|
|
|
|
|
//if (cmdType != 0x0E||cmdType!=0x01)
|
|
|
|
|
|
if (cmdType != 0E || cmdType != 0x03)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (DataTongJi.DefineLostPackage != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Interlocked.Increment(ref DataTongJi.RecordLostPackage);
|
|
|
|
|
|
if (DataTongJi.RecordLostPackage == DataTongJi.DefineLostPackage)
|
|
|
|
|
|
{
|
|
|
|
|
|
Interlocked.Exchange(ref DataTongJi.RecordLostPackage, 0);
|
|
|
|
|
|
string Key = "AllocateUDPLostPackage";
|
|
|
|
|
|
|
|
|
|
|
|
UDPPackageCount a1 = null;
|
|
|
|
|
|
DataTongJi.TotalCount.TryGetValue(Key, out a1);
|
|
|
|
|
|
if (a1 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
a1.Count = a1.Count + 1;
|
|
|
|
|
|
long NNN = 0;
|
|
|
|
|
|
bool bbn = a1.FenLei.TryGetValue(hotelCode, out NNN);
|
|
|
|
|
|
if (bbn)
|
|
|
|
|
|
{
|
|
|
|
|
|
NNN = NNN + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
long take = 0;
|
|
|
|
|
|
a1.FenLei.TryRemove(hotelCode, out take);
|
|
|
|
|
|
a1.FenLei.TryAdd(hotelCode, NNN);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
UDPPackageCount u = new UDPPackageCount();
|
|
|
|
|
|
u.Count = 1;
|
|
|
|
|
|
u.FenLei = new ConcurrentDictionary<string, long>();
|
|
|
|
|
|
u.FenLei.TryAdd(hotelCode, 1);
|
|
|
|
|
|
DataTongJi.TotalCount.TryAdd(Key, u);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//RCUHost.RCUHostCommon.tools.LanJieData(KKK, hotelCode);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string KKK = "StatusPass";
|
|
|
|
|
|
if (context111.SystemHeader.Value.CmdType == 0x0E)
|
|
|
|
|
|
{
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(KKK, hotelCode);
|
|
|
|
|
|
}
|
|
|
|
|
|
var Key10 = (CommandType)context111.SystemHeader.Value.CmdType;
|
|
|
|
|
|
var Key11 = Key10.ToString();
|
|
|
|
|
|
LanJieData(Key11, hotelCode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//添加统计
|
|
|
|
|
|
StepTongJi.SendInfo(2, "UDPCallBack执行完,即将分配Task", context111.MessageID, context111.IsMonitor);
|
|
|
|
|
|
//如果是心跳,直接处理
|
|
|
|
|
|
if (cmdType == 0x02)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (context111.SystemHeader.Value.FrameNo > 0x7FFF)
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver receiver = receivers[((CommandType)context111.SystemHeader.Value.CmdType)];
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(receiver as HeartReceiver).Process(context111);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//帧序号≤32767,则表示主机收到回复确认,可取消命令重发
|
|
|
|
|
|
RemoveCommandDataFromCommandQueueByFrameNo(context111.SystemHeader.Value.FrameNo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Task.Factory.StartNew((State) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ReceiverContext context = State as ReceiverContext;
|
|
|
|
|
|
|
|
|
|
|
|
//添加统计信息
|
|
|
|
|
|
StepTongJi.SendInfo(3, "Task分配成功,即将开始执行", context.MessageID, context.IsMonitor);
|
|
|
|
|
|
|
|
|
|
|
|
if (cmdType == 0x36)
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver receiver = receivers[(CommandType)0x36];
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(receiver as GenericReceiverBase).Process(context);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//必须过滤帧号,否则时间同步一直互相发送信息
|
|
|
|
|
|
if (context.SystemHeader.Value.FrameNo > 0x7FFF
|
|
|
|
|
|
|| (CommandType)context.SystemHeader.Value.CmdType == CommandType.RCUInfo
|
|
|
|
|
|
|| (CommandType)context.SystemHeader.Value.CmdType == CommandType.UpdateProgressBar
|
|
|
|
|
|
|| (CommandType)context.SystemHeader.Value.CmdType == CommandType.TFTPLog)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (receivers.ContainsKey((CommandType)context.SystemHeader.Value.CmdType))
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver receiver = receivers[((CommandType)context.SystemHeader.Value.CmdType)];
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(receiver as GenericReceiverBase).Process(context);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//帧序号≤32767,则表示主机收到回复确认,可取消命令重发
|
|
|
|
|
|
RemoveCommandDataFromCommandQueueByFrameNo(context.SystemHeader.Value.FrameNo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
StepTongJi.SendInfo(6, "Task执行完,即将切换下一个Task", context.MessageID, context.IsMonitor);
|
|
|
|
|
|
|
|
|
|
|
|
var FFF = DataTongJi.CPU_Data;
|
|
|
|
|
|
if (FFF.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
double avg_d = FFF.Average();
|
|
|
|
|
|
StepTongJi.SendInfo(0, avg_d.ToString(), context.MessageID, context.IsMonitor);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, context111);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static object oo = new object();
|
|
|
|
|
|
private void NewXieYi(ReceiverContext context_1, string hotelCode_1, string HostNNN_1, byte[] framenolist_1, byte cmdType_1, string EndPoint_1)
|
|
|
|
|
|
{
|
|
|
|
|
|
var Tuple = new Tuple<ReceiverContext, string, string, byte[], byte, string>(context_1, hotelCode_1, HostNNN_1, framenolist_1, cmdType_1, EndPoint_1);
|
|
|
|
|
|
Task.Factory.StartNew((state) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var ts = state as Tuple<ReceiverContext, string, string, byte[], byte, string>;
|
|
|
|
|
|
ReceiverContext context111 = ts.Item1;
|
|
|
|
|
|
string hotelCode = ts.Item2;
|
|
|
|
|
|
string HostNNN = ts.Item3;
|
|
|
|
|
|
byte[] framenolist = ts.Item4;
|
|
|
|
|
|
byte cmdType = ts.Item5;
|
|
|
|
|
|
string EndPoint = ts.Item6;
|
|
|
|
|
|
if (cmdType == 0x33)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// RCU重启原因: AA 55 26 00 54 33 53 41 35 02 80 EB 03 6B 24
|
|
|
|
|
|
// 4C 61 75 6E 63 68 65 72 5F 43 31 46 5F 56 30 34 2E 37 20 20 //"Launcher_C1F_V04.7 "
|
|
|
|
|
|
// 01 重启原因 0x01:软件复位,0x02:上电复位,0x03:外部手动复位,0x04:下电复位,0x05:看门狗复位,其他值:未知复位
|
|
|
|
|
|
// D5 40
|
|
|
|
|
|
ReplyWithContent(context111, new byte[] { 0x00 }, framenolist);
|
|
|
|
|
|
byte[] OriginalByte = context111.Data;
|
|
|
|
|
|
int offset = StructConverter.SizeOf(context111.SystemHeader);
|
|
|
|
|
|
int length = context111.Data.Length - offset - 2;
|
|
|
|
|
|
var data = OriginalByte.Skip(offset).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
var LauncherVersion = data.Take(20);
|
|
|
|
|
|
var RestartReason = data.Skip(20).Take(1);
|
|
|
|
|
|
|
|
|
|
|
|
NewVersionHexData ns = new NewVersionHexData();
|
|
|
|
|
|
ns.CmdType = 0x33;
|
|
|
|
|
|
ns.HotelCode = hotelCode;
|
|
|
|
|
|
ns.HostNumber = HostNNN;
|
|
|
|
|
|
ns.RemoteEndPoint = EndPoint;
|
|
|
|
|
|
ns.CurrentTime = DateTime.Now;
|
|
|
|
|
|
ns.HexData = Tools.ByteToString(context111.Data);
|
|
|
|
|
|
string mns1 = Newtonsoft.Json.JsonConvert.SerializeObject(ns);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-rcu-restart", mns1);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (cmdType == 0x35)
|
|
|
|
|
|
{
|
|
|
|
|
|
ReplyWithContent(context111, new byte[] { 0x00 }, framenolist);
|
|
|
|
|
|
//P0:取电动作状态
|
|
|
|
|
|
// 0x00:无动作
|
|
|
|
|
|
// 0x01:取电动作
|
|
|
|
|
|
// 0x02:断电动作
|
|
|
|
|
|
//P1:插卡状态
|
|
|
|
|
|
// 0x00:无插卡动作
|
|
|
|
|
|
// 0x01:插卡动作
|
|
|
|
|
|
// 0x02:拔卡动作
|
|
|
|
|
|
//P2:身份信息
|
|
|
|
|
|
//P3:无卡逻辑状态(对应事件状态)
|
|
|
|
|
|
|
|
|
|
|
|
//取电变化上报: AA 55 15 00 54 33 53 41 35 20 80 EB 03 6B 24 01 00 00 00 D7 74
|
|
|
|
|
|
// AA 55 15 00 54 33 53 41 35 20 80 EB 03 6B 24
|
|
|
|
|
|
// 01 //取电动作
|
|
|
|
|
|
// 00 //插卡动作
|
|
|
|
|
|
// 00 //身份信息
|
|
|
|
|
|
// 00 //无卡逻辑事件
|
|
|
|
|
|
// D7 74
|
|
|
|
|
|
|
|
|
|
|
|
byte[] OriginalByte = context111.Data;
|
|
|
|
|
|
int offset = StructConverter.SizeOf(context111.SystemHeader);
|
|
|
|
|
|
int length = context111.Data.Length - offset - 2;
|
|
|
|
|
|
|
|
|
|
|
|
var data = OriginalByte.Skip(offset).ToArray();
|
|
|
|
|
|
var qudian = data[0];
|
|
|
|
|
|
var chaka = data[1];
|
|
|
|
|
|
var shenfen = data[2];
|
|
|
|
|
|
var noka_event = data[3];
|
|
|
|
|
|
|
|
|
|
|
|
if (qudian == 0x01)
|
|
|
|
|
|
{
|
|
|
|
|
|
VoiceRobotTrigger(1, hotelCode, HostNNN);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (qudian == 0x02)
|
|
|
|
|
|
{
|
|
|
|
|
|
VoiceRobotTrigger(0, hotelCode, HostNNN);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NewVersionHexData ns = new NewVersionHexData();
|
|
|
|
|
|
ns.CmdType = 0x35;
|
|
|
|
|
|
ns.HotelCode = hotelCode;
|
|
|
|
|
|
ns.HostNumber = HostNNN;
|
|
|
|
|
|
ns.RemoteEndPoint = EndPoint;
|
|
|
|
|
|
ns.CurrentTime = DateTime.Now;
|
|
|
|
|
|
ns.HexData = Tools.ByteToString(context111.Data);
|
|
|
|
|
|
string mns1 = Newtonsoft.Json.JsonConvert.SerializeObject(ns);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-rcu-card_action", mns1);
|
|
|
|
|
|
|
|
|
|
|
|
string HostID = CSRedisCacheHelper.HMGet<string>(5, CacheKey.HostId_HostNumber, HostNNN)[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(HostID))
|
|
|
|
|
|
{
|
|
|
|
|
|
string KKey = CacheKey.HostModalStatus_Prefix + "_" + HostID + "_" + "004000001";
|
|
|
|
|
|
var OldHostModal = CSRedisCacheHelper.Get_Partition<HostModal_Cache>(KKey);
|
|
|
|
|
|
if (OldHostModal != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (qudian == 0x01)
|
|
|
|
|
|
{
|
|
|
|
|
|
OldHostModal.Status = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (qudian == 0x02)
|
|
|
|
|
|
{
|
|
|
|
|
|
OldHostModal.Status = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
CSRedisCacheHelper.Set_Partition(KKey, OldHostModal);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// AA 55 35 00 54 33 53 41 34 10 80 EB 03 6B 24
|
|
|
|
|
|
// 01 //协议版本
|
|
|
|
|
|
// 01 //取电状态
|
|
|
|
|
|
// 00 //身份信息
|
|
|
|
|
|
// 00 //无卡逻辑
|
|
|
|
|
|
// 00 00 00 00 00 00 00 00 //服务信息全部回路状态 1~64 64Bit 0 :关 1:开
|
|
|
|
|
|
// 01 //PMS状态
|
|
|
|
|
|
// 01 //碳达人
|
|
|
|
|
|
// 01 //上报设备数
|
|
|
|
|
|
|
|
|
|
|
|
// 39 //设备类型 - 能耗设备
|
|
|
|
|
|
// 01 //设备地址
|
|
|
|
|
|
// 01 00 //设备回路
|
|
|
|
|
|
// 10 //设备数据长度
|
|
|
|
|
|
// 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 //设备数据
|
|
|
|
|
|
|
|
|
|
|
|
// 07 //设备类型 - 温控
|
|
|
|
|
|
// 01 //设备地址
|
|
|
|
|
|
// 01 00 //设备回路
|
|
|
|
|
|
// 02 //设备数据长度
|
|
|
|
|
|
// 00 00 //设备数据
|
|
|
|
|
|
|
|
|
|
|
|
// F4 AA //CRC16
|
|
|
|
|
|
|
|
|
|
|
|
//能耗设备 - 上报数据格式
|
|
|
|
|
|
//P15:设备类型
|
|
|
|
|
|
//P16:设备地址
|
|
|
|
|
|
//P17~P18:设备回路
|
|
|
|
|
|
//P19:设备数据长度
|
|
|
|
|
|
//P20~P21:通道电压,单位:10mV
|
|
|
|
|
|
//P22~P23:通道电流,单位:10mA
|
|
|
|
|
|
//P24~P25:通道有功功率,单位:mW
|
|
|
|
|
|
//P26~P29:通道能耗,单位:Wh(1度电 = 1KWh)
|
|
|
|
|
|
//P30~P33:通道总能耗,单位:Wh(1度电 = 1KWh)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cmdType == 0x36)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Reply(context111);
|
|
|
|
|
|
string hexdata = Tools.ByteToString(context111.Data);
|
|
|
|
|
|
|
|
|
|
|
|
NewVersionHexData ns = new NewVersionHexData();
|
|
|
|
|
|
ns.CmdType = 0x36;
|
|
|
|
|
|
ns.HotelCode = hotelCode;
|
|
|
|
|
|
ns.HostNumber = HostNNN;
|
|
|
|
|
|
ns.RemoteEndPoint = EndPoint;
|
|
|
|
|
|
ns.CurrentTime = DateTime.Now;
|
|
|
|
|
|
ns.HexData = Tools.ByteToString(context111.Data);
|
|
|
|
|
|
//CSRedisCacheHelper.Publish("redis-rcu-hexdata", Newtonsoft.Json.JsonConvert.SerializeObject(ns));
|
|
|
|
|
|
}
|
|
|
|
|
|
if (cmdType == 0x34)
|
|
|
|
|
|
{
|
|
|
|
|
|
ReplyWithContent(context111, new byte[] { 0x00 }, framenolist);
|
|
|
|
|
|
byte[] OriginalByte = context111.Data;
|
|
|
|
|
|
|
|
|
|
|
|
int offset = StructConverter.SizeOf(context111.SystemHeader);
|
|
|
|
|
|
int length = context111.Data.Length - offset - 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//给宝镜发送完整的数据
|
|
|
|
|
|
string hexdata = Tools.ByteToString(context111.Data);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-baojing-powerdata", hexdata);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
NewVersionHexData ns = new NewVersionHexData();
|
|
|
|
|
|
ns.CmdType = 0x34;
|
|
|
|
|
|
ns.HotelCode = hotelCode;
|
|
|
|
|
|
ns.HostNumber = HostNNN;
|
|
|
|
|
|
ns.RemoteEndPoint = EndPoint;
|
|
|
|
|
|
ns.CurrentTime = DateTime.Now;
|
|
|
|
|
|
ns.HexData = hexdata;
|
|
|
|
|
|
|
|
|
|
|
|
//CSRedisCacheHelper.Publish("redis-rcu-timer_data", Newtonsoft.Json.JsonConvert.SerializeObject(ns));
|
|
|
|
|
|
|
|
|
|
|
|
string HostID = CSRedisCacheHelper.HMGet<string>(5, CacheKey.HostId_HostNumber, HostNNN)[0];
|
|
|
|
|
|
string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<DingShiReportDate> DeviceList = new List<DingShiReportDate>();
|
|
|
|
|
|
var DS1 = CSRedisCacheHelper.Get_Partition<List<DingShiReportDate>>(CacheKey.DingShiReportData + "_" + HostID, 3);
|
|
|
|
|
|
if (DS1 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DeviceList = DS1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//logger.Error("定时上报的HostId:" + HostID);
|
|
|
|
|
|
//定时上报要查询 当前房间配置了哪些设备
|
|
|
|
|
|
//这里根据主机Id 号查询当前房间,有哪些设备
|
|
|
|
|
|
if (!string.IsNullOrEmpty(HostID))
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (oo)
|
|
|
|
|
|
{
|
|
|
|
|
|
var list2 = HostModalRepository.LoadByHostID(int.Parse(HostID));
|
|
|
|
|
|
var list = list2.Where(r => r.Modal.IsUploadBaoJing).OrderBy(r => r.Modal.ModalAddress);//只装置标志启动的
|
|
|
|
|
|
|
|
|
|
|
|
List<DingShiReportDate> dingls = new List<DingShiReportDate>();
|
|
|
|
|
|
foreach (HostModal item in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
DingShiReportDate ddd = new DingShiReportDate();
|
|
|
|
|
|
ddd.HostID = item.HostID;
|
|
|
|
|
|
ddd.Address = item.Modal.ModalAddress;
|
|
|
|
|
|
ddd.DeviceType = item.Modal.Type.ToString();
|
|
|
|
|
|
dingls.Add(ddd);
|
|
|
|
|
|
}
|
|
|
|
|
|
DeviceList = dingls;
|
|
|
|
|
|
CSRedisCacheHelper.Set_PartitionWithForever<List<DingShiReportDate>>(CacheKey.DingShiReportData + "_" + HostID, dingls, 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<DingShiReportDate> DeviceStatusList = new List<DingShiReportDate>();
|
|
|
|
|
|
foreach (DingShiReportDate item in DeviceList)
|
|
|
|
|
|
{
|
|
|
|
|
|
string KKey = CacheKey.HostModalStatus_Prefix + "_" + item.HostID + "_" + item.Address;
|
|
|
|
|
|
var hostModal = CSRedisCacheHelper.Get_Partition<HostModal_Cache>(KKey);
|
|
|
|
|
|
if (hostModal != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
DingShiReportDate ddd = new DingShiReportDate();
|
|
|
|
|
|
ddd.HostID = item.HostID;
|
|
|
|
|
|
ddd.Address = item.Address;
|
|
|
|
|
|
ddd.DeviceType = item.DeviceType;
|
|
|
|
|
|
ddd.Status = hostModal.Status;
|
|
|
|
|
|
ddd.Brightness = hostModal.Brightness;
|
|
|
|
|
|
|
|
|
|
|
|
var aaa = hostModal.AirConditionData;
|
|
|
|
|
|
ddd.CurrentTemp = aaa.CurrentTemp;
|
|
|
|
|
|
ddd.SettingTemp = aaa.SettingTemp;
|
|
|
|
|
|
ddd.FanSpeed = aaa.FanSpeed;
|
|
|
|
|
|
ddd.Mode = aaa.Mode;
|
|
|
|
|
|
ddd.Valve = aaa.Valve;
|
|
|
|
|
|
DeviceStatusList.Add(ddd);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using (MemoryStream stream = new MemoryStream(context111.Data, offset, length))
|
|
|
|
|
|
{
|
|
|
|
|
|
using (BinaryReader reader = new BinaryReader(stream))
|
|
|
|
|
|
{
|
|
|
|
|
|
//版本
|
|
|
|
|
|
var Version = reader.ReadByte();
|
|
|
|
|
|
|
|
|
|
|
|
//取电
|
|
|
|
|
|
var TakeCardStatus = reader.ReadByte();
|
|
|
|
|
|
|
|
|
|
|
|
//string QUDIANKey = CacheKey.NewVersionDeviceStatus + "_" + HostNNN;
|
|
|
|
|
|
//var hostModal = CSRedisCacheHelper.HMGet<NewVersionDeviceStatus>(1, QUDIANKey, "004000001");
|
|
|
|
|
|
|
|
|
|
|
|
//if (hostModal[0] != null)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// hostModal[0].Status = TakeCardStatus;
|
|
|
|
|
|
// CSRedisCacheHelper.HMSet(1, QUDIANKey, "004000001", hostModal);
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
//{
|
|
|
|
|
|
// NewVersionDeviceStatus n = new NewVersionDeviceStatus();
|
|
|
|
|
|
// n.Status = TakeCardStatus;
|
|
|
|
|
|
// n.HotelCode = CODE;
|
|
|
|
|
|
// n.HostNumber = HostNNN;
|
|
|
|
|
|
// n.ModalType = DeviceType.ServiceInfo;
|
|
|
|
|
|
// n.UpdateTime = DateTime.Now;
|
|
|
|
|
|
// CSRedisCacheHelper.HMSet(1, QUDIANKey, "004000001", n);
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
//身份
|
|
|
|
|
|
var IdentityInfo = reader.ReadByte();
|
|
|
|
|
|
var NOCardInfo = reader.ReadByte();
|
|
|
|
|
|
|
|
|
|
|
|
//服务信息全部回路状态 1~64 64Bit 0 :关 1:开
|
|
|
|
|
|
//把8个字节转换成64个二进制位
|
|
|
|
|
|
var N = reader.ReadBytes(8);
|
|
|
|
|
|
BitArray bitlist = new BitArray(N);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < bitlist.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (i == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
string SerNo = i.ToString("000");
|
|
|
|
|
|
|
|
|
|
|
|
//界面上显示,为了 兼容老版的 界面 显示逻辑,所以这样写
|
|
|
|
|
|
if (!string.IsNullOrEmpty(HostID))
|
|
|
|
|
|
{
|
|
|
|
|
|
string KKey = CacheKey.HostModalStatus_Prefix + "_" + HostID + "_" + "004000" + SerNo;
|
|
|
|
|
|
var OldHostModal = CSRedisCacheHelper.Get_Partition<HostModal_Cache>(KKey);
|
|
|
|
|
|
if (OldHostModal != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (bitlist[i])
|
|
|
|
|
|
{
|
|
|
|
|
|
OldHostModal.Status = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
OldHostModal.Status = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//var hostModal1 = CSRedisCacheHelper.HMGet<NewVersionDeviceStatus>(1, QUDIANKey, "004000" + SerNo);
|
|
|
|
|
|
//if (hostModal1[0] != null)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// if (bitlist[i])
|
|
|
|
|
|
// {
|
|
|
|
|
|
// hostModal1[0].Status = 1;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// hostModal1[0].Status = 2;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// CSRedisCacheHelper.HMSet(1, QUDIANKey, "004000" + SerNo, hostModal1[0]);
|
|
|
|
|
|
//}
|
|
|
|
|
|
//else
|
|
|
|
|
|
//{
|
|
|
|
|
|
// NewVersionDeviceStatus n = new NewVersionDeviceStatus();
|
|
|
|
|
|
// n.Status = 2;
|
|
|
|
|
|
// n.HotelCode = CODE;
|
|
|
|
|
|
// n.HostNumber = HostNNN;
|
|
|
|
|
|
// n.ModalType = DeviceType.ServiceInfo;
|
|
|
|
|
|
// n.UpdateTime = DateTime.Now;
|
|
|
|
|
|
// CSRedisCacheHelper.HMSet(1, QUDIANKey, "004000" + SerNo, n);
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//PMS房态
|
|
|
|
|
|
//定时上报,之后要设置房态,要用0C
|
|
|
|
|
|
//只会上报 01 出租,02退房
|
|
|
|
|
|
var PMS = reader.ReadByte();
|
|
|
|
|
|
//if (PMS != 0x01 && PMS != 0x02)
|
|
|
|
|
|
if (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
string Key = CacheKey.SyncRoomStatus + "_" + HostNNN;
|
|
|
|
|
|
var Q = CSRedisCacheHelper.Get_Partition<RoomStatusRequest>(Key);
|
|
|
|
|
|
|
|
|
|
|
|
//测试使用
|
|
|
|
|
|
//IReceiver receiver1 = receivers[CommandType.RoomStatusChanged];
|
|
|
|
|
|
//(receiver1 as RoomStatusChangedReceiver).SendRoomStatusSelfWithFrameNo("111", "2222", new RoomStatus { ID = 10 }, framenolist);//处理业务逻辑
|
|
|
|
|
|
|
|
|
|
|
|
if (Q != null && PMS != Q.Status.ID)
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver receiver = receivers[CommandType.RoomStatusChanged];
|
|
|
|
|
|
if (Q != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(receiver as RoomStatusChangedReceiver).SendRoomStatusSelfWithFrameNo(Q.HostNumber, Q.MAC, Q.Status, framenolist);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Domain.RoomStatus RS = new RoomStatus();
|
|
|
|
|
|
RS.Name = "空房";
|
|
|
|
|
|
RS.ID = 16;
|
|
|
|
|
|
(receiver as RoomStatusChangedReceiver).SendRoomStatusSelfWithFrameNo(HostNNN, "", RS, framenolist);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//碳达人
|
|
|
|
|
|
var CarbonVIP = reader.ReadByte();
|
|
|
|
|
|
var DeviceCount = reader.ReadByte();
|
|
|
|
|
|
int DeviceCount_I = (int)DeviceCount;
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < DeviceCount_I; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var QA = reader.ReadBytes(4);
|
|
|
|
|
|
//说明是能耗设备
|
|
|
|
|
|
#region 能耗
|
|
|
|
|
|
if (QA[0] == 0x39)
|
|
|
|
|
|
{
|
|
|
|
|
|
string address = new DeviceAddress(QA).ToString();
|
|
|
|
|
|
//设备数据长度
|
|
|
|
|
|
var DeviceInfoLen = reader.ReadByte();
|
|
|
|
|
|
var Len = Convert.ToInt32(DeviceInfoLen);
|
|
|
|
|
|
//设备数据
|
|
|
|
|
|
var Data = reader.ReadBytes(Len);
|
|
|
|
|
|
|
|
|
|
|
|
//byte Len = Data.Skip(28).Take(1).FirstOrDefault();
|
|
|
|
|
|
byte[] DianYa = Data.Take(2).ToArray();
|
|
|
|
|
|
byte[] DianLiu = Data.Skip(2).Take(2).ToArray();
|
|
|
|
|
|
byte[] Power = Data.Skip(4).Take(4).ToArray();
|
|
|
|
|
|
byte[] PowerUsed = Data.Skip(8).Take(4).ToArray();
|
|
|
|
|
|
byte[] TotalPowerUsed = Data.Skip(12).Take(4).ToArray();
|
|
|
|
|
|
uint dianya = BitConverter.ToUInt16(DianYa, 0);
|
|
|
|
|
|
uint dianliu = BitConverter.ToUInt16(DianLiu, 0);
|
|
|
|
|
|
uint gonglv = BitConverter.ToUInt32(Power, 0);
|
|
|
|
|
|
|
|
|
|
|
|
uint nenghao = BitConverter.ToUInt32(PowerUsed, 0);
|
|
|
|
|
|
uint zongnenghao = BitConverter.ToUInt32(TotalPowerUsed, 0);
|
|
|
|
|
|
|
|
|
|
|
|
double V = (double)dianya * 10 / 1000;
|
|
|
|
|
|
double A = (double)dianliu * 10 / 1000;
|
|
|
|
|
|
double P = (double)gonglv / 1000;
|
|
|
|
|
|
|
|
|
|
|
|
double KW_H = (double)nenghao / 1000;
|
|
|
|
|
|
double Sum_KW_H = (double)zongnenghao / 1000;
|
|
|
|
|
|
|
|
|
|
|
|
NengHao n = new NengHao();
|
|
|
|
|
|
n.HotelCode = long.Parse(hotelCode);
|
|
|
|
|
|
n.HostNumber = HostNNN;
|
|
|
|
|
|
n.RoomNumber = RoomNUMBER;
|
|
|
|
|
|
n.CarbonVIP = CarbonVIP;
|
|
|
|
|
|
n.Mac = "";
|
|
|
|
|
|
n.EndPoint = EndPoint;
|
|
|
|
|
|
n.Version = ((int)Version).ToString();
|
|
|
|
|
|
if (TakeCardStatus == 0x01)
|
|
|
|
|
|
{
|
|
|
|
|
|
n.IsTakeCard = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
n.IsTakeCard = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
n.V = Math.Round(V, 2);
|
|
|
|
|
|
n.A = Math.Round(A, 2);
|
|
|
|
|
|
n.P = Math.Round(P, 2);
|
|
|
|
|
|
n.KW_H = KW_H;
|
|
|
|
|
|
n.Sum_KW_H = Sum_KW_H;
|
|
|
|
|
|
|
|
|
|
|
|
long ti = Tools.GetUnixTime();
|
|
|
|
|
|
n.CreateTime = ti;
|
|
|
|
|
|
|
|
|
|
|
|
string KKey = CacheKey.NengHao + "_" + HostNNN;
|
|
|
|
|
|
CSRedisCacheHelper.Set_PartitionWithTime<NengHao>(KKey, n, 30, 1);
|
|
|
|
|
|
|
|
|
|
|
|
//这里不再发送这个了,改发送全部的数据
|
|
|
|
|
|
|
|
|
|
|
|
NengHao4BaoJing ns2 = new NengHao4BaoJing()
|
|
|
|
|
|
{
|
|
|
|
|
|
HotelCode = n.HotelCode,
|
|
|
|
|
|
HostNumber = n.HostNumber,
|
|
|
|
|
|
RoomNumber = n.RoomNumber,
|
|
|
|
|
|
Mac = n.Mac,
|
|
|
|
|
|
EndPoint = n.EndPoint,
|
|
|
|
|
|
Version = n.Version,
|
|
|
|
|
|
IsTakeCard = n.IsTakeCard,
|
|
|
|
|
|
CarbonVIP = n.CarbonVIP,
|
|
|
|
|
|
V = dianya,
|
|
|
|
|
|
A = dianliu,
|
|
|
|
|
|
P = gonglv,
|
|
|
|
|
|
Energy_Consumption = nenghao,
|
|
|
|
|
|
Sum_Energy_Consumption = zongnenghao,
|
|
|
|
|
|
CreateTime = n.CreateTime,
|
|
|
|
|
|
ReportTime = n.ReportTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
|
|
|
|
|
AllDeviceData = DeviceStatusList,
|
|
|
|
|
|
IdentityInfo = IdentityInfo
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
string mns = Newtonsoft.Json.JsonConvert.SerializeObject(ns2);
|
|
|
|
|
|
CSRedisCacheHelper.Publish("redis-power", mns);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string KeyFilter = "能耗";
|
|
|
|
|
|
RCUHost.RCUHostCommon.tools.LanJieData(KeyFilter, hotelCode.ToString());
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 是温控
|
|
|
|
|
|
//定期上报,
|
|
|
|
|
|
//原本的0E 修改了命令字,改成其它命令字,内容不变,但是空调 只有操作上报。
|
|
|
|
|
|
//空调定期上报的数据,改为在这里上报
|
|
|
|
|
|
else if (QA[0] == 0x07)
|
|
|
|
|
|
{
|
|
|
|
|
|
//07 //设备类型 - 温控
|
|
|
|
|
|
//01 //设备地址
|
|
|
|
|
|
//01 00 //设备回路
|
|
|
|
|
|
//02 //设备数据长度
|
|
|
|
|
|
//00 00 //设备数据
|
|
|
|
|
|
string address = new DeviceAddress(QA).ToString();
|
|
|
|
|
|
|
|
|
|
|
|
//设备数据长度
|
|
|
|
|
|
var WenKongQiDataLen = reader.ReadByte();
|
|
|
|
|
|
//温控器
|
|
|
|
|
|
var DataLen1 = Convert.ToInt32(WenKongQiDataLen);
|
|
|
|
|
|
|
|
|
|
|
|
///ushort StatusReceiver = reader.ReadUInt16();
|
|
|
|
|
|
ushort StatusReceiver = BitConverter.ToUInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
//int status = StatusReceiver >> 15;//开关
|
|
|
|
|
|
//int mode = (StatusReceiver >> 13) & 0x03;//模式
|
|
|
|
|
|
//int fanSpeed = (StatusReceiver >> 11) & 0x03;//风速
|
|
|
|
|
|
int valve = (StatusReceiver >> 10) & 0x01;//阀门
|
|
|
|
|
|
//int temperature = (StatusReceiver >> 5) & 0x1F;//设定温度
|
|
|
|
|
|
//int currentTemp = StatusReceiver & 0x01F;//当前温度(室内温度)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int status = 0;
|
|
|
|
|
|
int mode;
|
|
|
|
|
|
int fanspeed;
|
|
|
|
|
|
int temperature = 0;//设定温度
|
|
|
|
|
|
int currentTemp = 0;//当前温度(室内温度)
|
|
|
|
|
|
KongTiaoReport(StatusReceiver, out status, out temperature, out mode, out fanspeed, out currentTemp);
|
|
|
|
|
|
if (!string.IsNullOrEmpty(HostID))
|
|
|
|
|
|
{
|
|
|
|
|
|
string KKey = CacheKey.HostModalStatus_Prefix + "_" + HostID + "_" + address;
|
|
|
|
|
|
var HHostModalData = CSRedisCacheHelper.Get_Partition<HostModal_Cache>(KKey);
|
|
|
|
|
|
if (HHostModalData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.AirStatus = status;
|
|
|
|
|
|
HHostModalData.AirConditionData.Mode = mode;
|
|
|
|
|
|
HHostModalData.AirConditionData.FanSpeed = fanspeed;
|
|
|
|
|
|
HHostModalData.AirConditionData.Valve = valve == 1 ? 1 : 2;
|
|
|
|
|
|
HHostModalData.AirConditionData.UpdateTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (temperature == 0 || temperature > 32)
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.SettingTemp = 32;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (temperature < 16)
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.SettingTemp = 16;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.SettingTemp = temperature;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
if (currentTemp == 0 || currentTemp > 32)
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.CurrentTemp = 32;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (currentTemp < 16)
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.CurrentTemp = 16;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
HHostModalData.AirConditionData.CurrentTemp = currentTemp;
|
|
|
|
|
|
}
|
|
|
|
|
|
CSRedisCacheHelper.Set_Partition(KKey, HHostModalData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error("定是上报出错:" + ex.Message);
|
|
|
|
|
|
logger.Error("定是上报出错:" + ex.StackTrace);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//向服务器获取房态
|
|
|
|
|
|
if (cmdType == 0x32)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IReceiver receiver = receivers[CommandType.AskRoomStatus];
|
|
|
|
|
|
if (receiver != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
string Key = CacheKey.SyncRoomStatus + "_" + HostNNN;
|
|
|
|
|
|
var Q = CSRedisCacheHelper.Get_Partition<RoomStatusRequest>(Key);
|
|
|
|
|
|
if (Q != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
(receiver as AskRoomStatusChangedReceiver).SendRoomStatusSelf(HostNNN, Q.MAC, Q.Status, framenolist);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Domain.RoomStatus RS = new RoomStatus();
|
|
|
|
|
|
RS.Name = "空房";
|
|
|
|
|
|
RS.ID = 16;
|
|
|
|
|
|
(receiver as AskRoomStatusChangedReceiver).SendRoomStatusSelf(HostNNN, "FF-FF-FF-FF-FF-FF", RS, framenolist);//处理业务逻辑
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.Error("CmdType Error" + ex.StackTrace);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}, Tuple);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 空调上报解析
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="StatusReceiver"></param>
|
|
|
|
|
|
/// <param name="temperature"></param>
|
|
|
|
|
|
/// <param name="mode"></param>
|
|
|
|
|
|
/// <param name="fanspeed"></param>
|
|
|
|
|
|
private static void KongTiaoReport(ushort StatusReceiver, out int status, out int temperature, out int mode, out int fanspeed, out int currenttemp)
|
|
|
|
|
|
{
|
|
|
|
|
|
mode = 0;
|
|
|
|
|
|
fanspeed = 0;
|
|
|
|
|
|
status = 0;
|
|
|
|
|
|
|
|
|
|
|
|
//StringBuilder sssasa = new StringBuilder();
|
|
|
|
|
|
byte[] b_data = BitConverter.GetBytes(StatusReceiver);
|
|
|
|
|
|
|
|
|
|
|
|
b_data = b_data.Reverse().ToArray();
|
|
|
|
|
|
BitArray bit = new BitArray(b_data);
|
|
|
|
|
|
|
|
|
|
|
|
//BitArray bit2 = new BitArray(new byte[] { b_data[1] });
|
|
|
|
|
|
BitArray bit3 = new BitArray(5);
|
|
|
|
|
|
BitArray bit4 = new BitArray(5);
|
|
|
|
|
|
|
|
|
|
|
|
//00 0011 1010
|
|
|
|
|
|
//Bit9~5:设置温度 16~32℃
|
|
|
|
|
|
//Bit4~0:室内温度 16~32℃
|
|
|
|
|
|
bit3[0] = bit[5];
|
|
|
|
|
|
bit3[1] = bit[6];
|
|
|
|
|
|
bit3[2] = bit[7];
|
|
|
|
|
|
bit3[3] = bit[8];
|
|
|
|
|
|
bit3[4] = bit[9];
|
|
|
|
|
|
|
|
|
|
|
|
bit4[0] = bit[0];
|
|
|
|
|
|
bit4[1] = bit[1];
|
|
|
|
|
|
bit4[2] = bit[2];
|
|
|
|
|
|
bit4[3] = bit[3];
|
|
|
|
|
|
bit4[4] = bit[4];
|
|
|
|
|
|
|
|
|
|
|
|
int[] array1 = new int[1];
|
|
|
|
|
|
int[] array2 = new int[1];
|
|
|
|
|
|
bit3.CopyTo(array1, 0);
|
|
|
|
|
|
bit4.CopyTo(array2, 0);
|
|
|
|
|
|
|
|
|
|
|
|
temperature = array1[0];
|
|
|
|
|
|
currenttemp = array2[0];
|
|
|
|
|
|
bool b000 = bit[15];
|
|
|
|
|
|
if (b000 == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
status = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
status = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
bool b111 = bit[14];
|
|
|
|
|
|
bool b222 = bit[13];
|
|
|
|
|
|
|
|
|
|
|
|
bool b333 = bit[12];
|
|
|
|
|
|
bool b444 = bit[11];
|
|
|
|
|
|
//1制冷,2制热,3送风
|
|
|
|
|
|
if (b222 == true && b111 == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
mode = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (b222 == false && b111 == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
mode = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (b222 == true && b111 == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
mode = 3;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//0自动,1低速,2中速,3高速
|
|
|
|
|
|
if (b444 == true && b333 == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
fanspeed = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (b444 == false && b333 == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
fanspeed = 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (b444 == true && b333 == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
fanspeed = 3;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (b444 == false && b333 == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
fanspeed = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 解码 SystemHeader
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private SystemHeader? DecodeSystemHeader(byte[] data)
|
|
|
|
|
|
{
|
|
|
|
|
|
return StructConverter.BytesToStruct(data, typeof(SystemHeader)) as SystemHeader?;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Command Queue Methods
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将命令放入队列
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
private void PushCommandToQueue(byte[] data, IPEndPoint endPoint)
|
|
|
|
|
|
{
|
|
|
|
|
|
CommandData commandData = new CommandData();
|
|
|
|
|
|
commandData.RemoteEndPoint = endPoint;
|
|
|
|
|
|
commandData.FrameNo = BitConverter.ToUInt16(data, 9);
|
|
|
|
|
|
commandData.Data = data;
|
|
|
|
|
|
commandData.ResendTime = 2;
|
|
|
|
|
|
commandQueue.Add(commandData);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 清理命令队列
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void CleanCommandQueue()
|
|
|
|
|
|
{
|
|
|
|
|
|
RemoveCommandData(commandQueue.Where(r => r.ResendTime < 1));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RemoveCommandDataFromCommandQueueByFrameNo(ushort frameNo)
|
|
|
|
|
|
{
|
|
|
|
|
|
RemoveCommandData(commandQueue.Where(r => r.FrameNo == frameNo));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RemoveCommandData(IEnumerable<CommandData> commands)
|
|
|
|
|
|
{
|
|
|
|
|
|
CommandData takeCommand;
|
|
|
|
|
|
foreach (var command in commands)
|
|
|
|
|
|
{
|
|
|
|
|
|
commandQueue.TryTake(out takeCommand);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 阿宝
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Start_AirConditionMisson()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
Destroy();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal class UdpState
|
|
|
|
|
|
{
|
|
|
|
|
|
private UdpClient udpClient;
|
|
|
|
|
|
public UdpState(UdpClient client)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.udpClient = client;
|
|
|
|
|
|
}
|
|
|
|
|
|
public UdpClient UdpClient
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return this.udpClient; }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|