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

        //public System.Timers.Timer FaultReport = new System.Timers.Timer();
        #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, 1000, 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)
            {
                logger.Error("消息队列失败:"+ex.Message);
            }
        }

        /// <summary>
        /// 启动 HostServer
        /// </summary>
        public void Start()
        {
            var DDD = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
            CSRedisCacheHelper.Forever<string>(CacheKey.ServerStartTime, DDD);
            //FaultReport.Interval = 10000;
            //FaultReport.Elapsed += new System.Timers.ElapsedEventHandler(FaultReport_Elapsed);
            //FaultReport.Start();

            Close();

            //CSRedisCacheHelper.StreamAdd(1,UDPAllDataKey, data);
            //CSRedisCacheHelper.StreamConsume(1, UDPAllDataKey);
            try
            {
                udpClient = new UdpClient(3339);
                udpClient.Client.ReceiveBufferSize = 5 * 1024 * 1024;
                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);
                for (int i = 1; i <= 15; i++)
                {
                    Task.Factory.StartNew((iii) =>
                        {
                            string osos = iii.ToString();
                            while (true)
                            {
                                StreamConsume("UDPData", "Crics" + osos, "task" + osos);
                            }
                        }, i, TaskCreationOptions.LongRunning);
                }

            }
            catch (Exception ex)
            {
                logger.Error("Host Server启动失败，端口：3339");
                Close();
                throw ex;//不能去掉，否则重启iis服务，通讯服务不会再次启动
            }
        }


        //public Random rs = new Random();
        ///// <summary>
        ///// 定时上报 错误
        ///// </summary>
        ///// <param name="sender"></param>
        ///// <param name="e"></param>
        //void FaultReport_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        //{
        //    try
        //    {

        //        //FaultReport.Stop();
        //        string FaultKey = CacheKey.FaultKey_;
        //        //string FFFFFKey = HotelCode + "_" + host.RoomNumber + "_" + hostModal.Modal.ModalAddress;
        //        var data = CSRedisCacheHelper.HMGetAll(5, FaultKey);
        //        foreach (var item in data)
        //        {
        //            var key = item.Key;
        //            var val = item.Value;
        //            var v = JsonConvert.DeserializeObject<XuanZhuResponse_Fault>(val);
        //            TimeSpan span = DateTime.Now - v.updatetime;
        //            if (span.TotalSeconds <= 20)
        //            {
        //                var fault_data = new Tuple<string, XuanZhuResponse>(v.url, v.data);
        //                Task.Factory.StartNew((State) =>
        //                {
        //                    var DDD = State as Tuple<string, XuanZhuResponse>;
        //                    string Res_P = MyHttp.SendHttpData(DDD.Item1, DDD.Item1);
        //                    //XuanZhuOperation.ReportService(DDD.Item1, DDD.Item2);
        //                    logger.Error("Fault Return:" + "");
        //                }, fault_data);
        //            }
        //        }
        //    }
        //    catch (Exception)
        //    {

        //    }
        //    finally
        //    {
        //        var ts = rs.Next(10000, 15000);
        //        FaultReport.Interval = ts;
        //        FaultReport.Start();
        //    }
        //}
        /// <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);
                }

                //logger.Error("升级拉取指令:" + Tools.ByteToString(data));
                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");
                    }

                    try
                    {
                        //故障数量，默认0
                        int faultNumber = reader.ReadByte();
                        for (int i = 0; i < faultNumber; i++)
                        {
                            string faultNo = new DeviceAddress(reader.ReadBytes(4)).ToString();//设备类型1、设备地址1、回路地址2
                            byte type = reader.ReadByte();
                            if (!roomStatus.Faults.ContainsKey(faultNo + type.ToString()))
                            {
                                roomStatus.Faults[faultNo + type.ToString()] = new FaultStaus();
                            }
                            roomStatus.Faults[faultNo + type.ToString()].FaultNo = faultNo;
                            roomStatus.Faults[faultNo + type.ToString()].Type = type;//类型：1在线状态（0在线，1离线），2电量（0~100%），3电流，4 1901故障检测次数
                            roomStatus.Faults[faultNo + type.ToString()].Data = reader.ReadByte();//内容
                        }
                    }
                    catch (Exception)
                    {

                    }


                    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;
                        string WelcomeBGM = host.SysHotel.WelcomeBGM;

                        //欢送词
                        string GoodbyeSpeech = host.SysHotel.GoodbyeSpeech;

                        int HotelID = host.SysHotel.ID;

                        //断电重置
                        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))//取电打开时，播放欢迎词
                            {
                                var TTT = new Tuple<string, string, string, string, string, int>(TianMaoCUID, WelcomeSpeech, hotelcode, roomnumber, WelcomeBGM, HotelID);

                                Task.Factory.StartNew((state) =>
                                {
                                    var hhh = state as Tuple<string, string, string, string, string, int>;
                                    var a = hhh.Item1.Split(',');

                                    var b = hhh.Item2;
                                    var c = hhh.Item3;
                                    var d = hhh.Item4;
                                    var e = hhh.Item5;
                                    var f = hhh.Item6;

                                    foreach (string cuid in a)//多个英文逗号隔开
                                    {
                                        //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);//通知天猫精灵播放欢迎词
                                        //}

                                        if (!string.IsNullOrEmpty(e))
                                        {
                                            string ffg = "https://www.boonlive-rcu.com/welcomebgm/" + e;
                                            //TianMaoOperation.PostWebRequestToTianMao("AddOrUpdateWelcomeText",
                                            //Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], MusicUrl = ffg, WelcomeText = b }), c, d);//通知天猫精灵播放欢迎词
                                            TianMaoOperation.PostWebRequestToTianMao("PushWelcome",
                                                 Newtonsoft.Json.JsonConvert.SerializeObject(new { HotelId = cuid.Split('&')[0], RoomNo = cuid.Split('&')[1], WelcomeText = b, WelcomeMusicUrl = ffg }), c, d);//通知天猫精灵播放欢迎词
                                        }
                                        else
                                        {

                                            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);
                            }
                            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);
        }

        public static SearchHostPacketReply? DecodeSearchHostPacketReply(byte[] data, int startIndex)
        {
            return StructConverter.BytesToStruct(data, startIndex, typeof(SearchHostPacketReply)) as SearchHostPacketReply?;
        }

        public static SearchHostPacketReplyV2? DecodeSearchHostPacketReplyV2(byte[] data, int startIndex)
        {
            return StructConverter.BytesToStruct(data, startIndex, typeof(SearchHostPacketReplyV2)) as SearchHostPacketReplyV2?;
        }
        //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;
            if (cmdType == 0x68)
            {
                //logger.Error("收到升级返回:" + Tools.ByteToString(gga.Data));
            }
            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 == 0x02)
            {
                string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                if (!string.IsNullOrEmpty(RoomNUMBER))
                {
                    string hotelid = CODE;
                    string roomid = RoomNUMBER;
                    Kafka_XinTiao k = new Kafka_XinTiao();
                    k.hotel_id = CODE;
                    k.device_id = HostNNN;
                    k.room_id = RoomNUMBER;
                    k.ts_ms = Tools.GetUnixTime_MS();
                    k.current_time = CPUData.GetNowPrecise().ToString("yyyy-MM-dd HH:mm:ss.ffffff");
                    CSRedisCacheHelper.Publish("redis-heartbeat", Newtonsoft.Json.JsonConvert.SerializeObject(k));
                }
            }
            if (cmdType != 0x01 && cmdType != 0xb1)
            //if (!(cmdType==0x01||cmdType==0xb1)  )
            //在线状态 不排队 注册0x01
            //if (true)
            {
                #region 只要有数据包，就是心跳
                string EndPointStr = context111.RemoteEndPoint.ToString();

                OnOffLineData o = new OnOffLineData();
                string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                if (!string.IsNullOrEmpty(RoomNUMBER))
                {
                    o.RoomNumber = RoomNUMBER;
                }
                o.HostNumber = HostNNN;
                o.HotelCode = hotelCode;
                o.CurrentStatus = "on";
                o.CurrentTime = DateTime.Now;
                o.EndPoint = EndPointStr;
                o.UnixTime = Tools.GetUnixTime();
                o.MAC = BitConverter.ToString(gga.Data.Skip(9).Take(2).ToArray());
                //新来的数据
                var n = Newtonsoft.Json.JsonConvert.SerializeObject(o);


                //上线
                //string EEE = CSRedisCacheHelper.Get<string>(EndPointStr);
                var EEE = CSRedisCacheHelper.Get_Partition<string>(HostNNN, 6);
                var dtstart = CSRedisCacheHelper.ForeverGet<string>(CacheKey.ServerStartTime);
                DateTime SSS = DateTime.Now;
                DateTime.TryParse(dtstart, out SSS);
                TimeSpan ssspan = DateTime.Now - SSS;
                if (string.IsNullOrEmpty(EEE) && ssspan.TotalMinutes > 5)
                {
                    CSRedisCacheHelper.Publish("redis-on_off_line", n);
                }
                //6号分区 做离在线数据
                //但是离线的时候，只能得到Key值
                CSRedisCacheHelper.Set_PartitionWithTime(HostNNN, n, 5, 6);

                //所以4号分区再存储一下 详细信息
                CSRedisCacheHelper.Set_PartitionWithTime(HostNNN, n, 20, 4);



                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

            ///注册指令 也要推送
            if (cmdType == 0x01)
            {
                string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                if (string.IsNullOrEmpty(RoomNUMBER))
                {
                    return;
                }
                int startIndex = StructConverter.SizeOf(context111.SystemHeader);
                SearchHostPacketReply? reply = DecodeSearchHostPacketReply(context111.Data, startIndex);
                //SearchHostPacketReplyV2? C_Xilie_zhuji = null;
                //if (context111.Data.Length > 100)//V2版本新补充的内容
                //{
                //    C_Xilie_zhuji = DecodeSearchHostPacketReplyV2(context111.Data, 58);
                //}
                string MAC = "";
                if (reply.HasValue)
                {
                    MAC = BitConverter.ToString(reply.Value.MAC);
                    //string version = reply.Value.Version;
                    //var ConfigVersion = String.Join(".", reply.Value.ConfigVersion);
                    //var SubnetMask = String.Join(".", reply.Value.SubnetMask);
                    //var Gateway = String.Join(".", reply.Value.Gateway);
                }

                LMRegisterInfo lma = new LMRegisterInfo();
                lma.HotelCode = CODE;
                lma.RoomNumber = RoomNUMBER;
                lma.HostNumber = HostNNN;
                lma.MAC = MAC;
                lma.Original_Data = context111.Data;

                string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                lma.CurrentDateTime = ti;
                lma.UnixTime = Tools.GetUnixTime();

                string sss = Newtonsoft.Json.JsonConvert.SerializeObject(lma);
                CSRedisCacheHelper.Publish("redis-0X01", sss);
            }

            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, MyFrameNO);
                    }
                    else
                    {
                        if (cmdType == 0x0F)
                        {
                            string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                            if (!string.IsNullOrEmpty(RoomNUMBER))
                            {
                                //控制回复 
                                DeviceActionData d1 = new DeviceActionData();
                                d1.ts_ms = Tools.GetUnixTime();
                                d1.hotel_id = hotelCode;
                                d1.room_id = RoomNUMBER;
                                d1.device_id = HostNNN;
                                d1.frame_id = MyFrameNO;
                                d1.cmd_word = "0F";
                                d1.udp_raw = OriginalByte;
                                d1.direction = "上报";
                                string sss = Newtonsoft.Json.JsonConvert.SerializeObject(d1);
                                CSRedisCacheHelper.Publish("redis-0X36-0X0F", sss);

                            }
                        }
                        #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);
                                                string sb = string.Concat(VVV1, VVV2);
                                                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);

                        byte cmdTypeTTT = context.SystemHeader.Value.CmdType;
                        if (cmdTypeTTT == 0x36)
                        {
                            if (receivers.ContainsKey((CommandType)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 byte[] nocard_enum = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
        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, ushort MyFrameNO)
        {
            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;
                    #region 主机重启
                    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).ToArray();
                        var RestartReason = data.Skip(20).Take(1).ToArray();

                        string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                        if (string.IsNullOrEmpty(RoomNUMBER))
                        {
                            return;
                        }
                        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);

                        ns.RoomNumber = RoomNUMBER;
                        ns.MAC = BitConverter.ToString(OriginalByte.Skip(9).Take(2).ToArray());
                        ns.CurrentStatus = "on";
                        ns.UnixTime = Tools.GetUnixTime();
                        ns.LauncherVersion = LauncherVersion;
                        ns.RebootReason = RestartReason;
                        string mns1 = Newtonsoft.Json.JsonConvert.SerializeObject(ns);
                        CSRedisCacheHelper.Publish("redis-rcu-restart", mns1);
                    }
                    #endregion

                    #region 取电
                    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);
                            }
                        }
                    }
                    #endregion

                    //    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）

                    #region 定时上报
                    if (cmdType == 0x36)
                    {

                        string RoomNUMBER = CSRedisCacheHelper.HMGet<string>(5, CacheKey.RoomNumber_HostNumber, HostNNN)[0];
                        if (string.IsNullOrEmpty(RoomNUMBER))
                        {
                            return;
                        }

                        byte[] OriginalByte = context111.Data;
                        int offset = StructConverter.SizeOf(context111.SystemHeader);
                        int length = context111.Data.Length - offset - 2;

                        DeviceActionData d1 = new DeviceActionData();
                        d1.ts_ms = Tools.GetUnixTime();
                        d1.hotel_id = hotelCode;
                        d1.room_id = RoomNUMBER;
                        d1.device_id = HostNNN;
                        d1.frame_id = MyFrameNO;
                        d1.cmd_word = "36";
                        d1.udp_raw = OriginalByte;
                        d1.direction = "上报";

                        List<ts_deviceitem> lll1 = new List<ts_deviceitem>();
                        List<ts_faultitem> lll2 = new List<ts_faultitem>();



                        using (MemoryStream stream = new MemoryStream(context111.Data, offset, length))
                        {
                            Status status = NewStatusParse(stream);
                            if (status.SysLock)
                            {
                                d1.sys_lock_status = 1;
                            }
                            else
                            {
                                d1.sys_lock_status = 2;
                            }

                            if (status != null && status.Devices.Count > 0)
                            {
                                foreach (var item in status.Devices)
                                {
                                    string ItemKKK = item.Key;
                                    Device VVV = item.Value;

                                    ts_deviceitem t1 = new ts_deviceitem();

                                    string dizhi = VVV.Address;
                                    t1.dev_type = short.Parse(dizhi.Substring(0, 3));
                                    t1.dev_addr = short.Parse(dizhi.Substring(3, 3));
                                    t1.dev_loop = short.Parse(dizhi.Substring(6, 3));
                                    t1.dev_data = VVV.StatusReceiver;
                                    lll1.Add(t1);
                                }
                            }

                            if (status.Faults != null && status.Faults.Count > 0)
                            {
                                var F1 = status.Faults;
                                foreach (var item in F1)
                                {
                                    string dizhi = item.Value.FaultNo;
                                    ts_faultitem t1 = new ts_faultitem();
                                    t1.dev_type = short.Parse(dizhi.Substring(0, 3));
                                    t1.dev_addr = short.Parse(dizhi.Substring(3, 3));
                                    t1.dev_loop = short.Parse(dizhi.Substring(6, 3));
                                    t1.error_type = item.Value.Type;
                                    t1.error_data = item.Value.Data;
                                    lll2.Add(t1);
                                }
                            }
                        }

                        d1.device_list = lll1;
                        d1.fault_list = lll2;
                        d1.report_count = lll1.Count;
                        d1.fault_count = lll2.Count;

                        string sss = Newtonsoft.Json.JsonConvert.SerializeObject(d1);
                        CSRedisCacheHelper.Publish("redis-0X36-0X0F", sss);
                        //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));
                    }
                    #endregion

                    #region 定时上报
                    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];
                            if (string.IsNullOrEmpty(RoomNUMBER))
                            {
                                return;
                            }


                            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))
                                {
                                    //版本
                                    //默认是02
                                    var Version = reader.ReadByte();

                                    //取电
                                    //P1:插卡与取电状态设备类型(1Byte)
                                    //bit0-bit1 
                                    //00 当前未取电
                                    //01 当前已经取电
                                    //bit2-bit3
                                    //00 无插卡
                                    //01 已经插卡

                                    //下面的是是否取电
                                    var TakeCardStatus = reader.ReadByte();

                                    bool 是否取电 = false;
                                    ushort 是否取电_Int = 0;
                                    int 是否插卡 = 0;
                                    if (Version == 0x02 || Version == 0x03 || Version == 0x04)
                                    {
                                        BitArray bit_a = new BitArray(new byte[] { TakeCardStatus });
                                        bool b0 = bit_a.Get(0);
                                        bool b1 = bit_a.Get(1);
                                        bool b2 = bit_a.Get(2);
                                        bool b3 = bit_a.Get(3);
                                        if (b0 == false && b1 == false)
                                        {
                                            //是否取电 = false;
                                            是否取电_Int = 0;
                                        }
                                        else if (b0 == false && b1 == true)
                                        {
                                            是否取电_Int = 2;
                                        }
                                        else if (b0 == true && b1 == false)
                                        {
                                            //是否取电 = true;
                                            是否取电_Int = 1;
                                        }

                                        if (b2 == false && b3 == false)
                                        {
                                            是否插卡 = 0;
                                        }
                                        else if (b2 == false && b3 == true)
                                        {
                                            是否插卡 = 2;
                                        }
                                        else if (b2 == true && b3 == false)
                                        {
                                            是否插卡 = 1;
                                        }
                                    }
                                    //如果是01就只有取电
                                    //从取电动作那里取数据
                                    if (Version == 0x01)
                                    {
                                        string HostID_redis = 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)
                                            {
                                                var aaa = OldHostModal.Status;
                                                if (aaa == 01)
                                                {
                                                    是否取电 = true;
                                                    是否取电_Int = 1;
                                                }
                                                else if (aaa == 02)
                                                {
                                                    是否取电 = false;
                                                    是否取电_Int = 2;
                                                }
                                            }
                                            else
                                            {

                                            }
                                        }
                                    }


                                    //身份
                                    var IdentityInfo = reader.ReadByte();

                                    byte[] nocard_enum = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };
                                    //无卡逻辑状态(对应事件状态)
                                    //0x01：开门进入事件
                                    //0x02：卡在人离事件
                                    //0x03：无卡人离事件
                                    //0x04：室内雷达有人事件
                                    //0x05：室内雷达无人事件
                                    //0x06：室内按键触发
                                    //0x07：短暂人离事件
                                    //0x08：长时间人离事件
                                    //0x09:短暂人离超时
                                    //0x0A:长时间人离超时
                                    var NOCardInfo = reader.ReadByte();
                                    var NOCardInfo_NoFilter = NOCardInfo;
                                    if (!nocard_enum.Contains(NOCardInfo))
                                    {
                                        NOCardInfo = 0x00;
                                    }
                                    #region BUG处理
                                    //只有同派酒店做这个处理
                                    if (hotelCode.Equals("2144"))
                                    {
                                        if (NOCardInfo == 0x03)
                                        {
                                            是否插卡 = 2;
                                        }
                                    }
                                    #endregion

                                    //服务信息全部回路状态 1~64 64Bit 0 :关 1：开
                                    //把8个字节转换成64个二进制位
                                    var N = reader.ReadBytes(8);
                                    BitArray bitlist = new BitArray(N);

                                    #region 服务信息
                                    int iii = 0;
                                    for (int i = 0; i < bitlist.Length; i++)
                                    {
                                        iii = i + 1;
                                        //if (i == 1)
                                        //{
                                        //    continue;
                                        //}
                                        string SerNo = iii.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;
                                                }
                                            }
                                            else
                                            {
                                                HostModal_Cache ccc = new HostModal_Cache();
                                                ccc.HostID = int.Parse(HostID);
                                                ccc.ModalType = DeviceType.ServiceInfo;
                                                if (bitlist[i])
                                                {
                                                    ccc.Status = 1;
                                                }
                                                else
                                                {
                                                    ccc.Status = 2;
                                                }
                                                ccc.UpdateTime = DateTime.Now;
                                                ccc.Modal = new RoomTypeModalCache() { };
                                                ccc.AirConditionData = new AirConditionData();
                                                CSRedisCacheHelper.Set_Partition<HostModal_Cache>(KKey, ccc);
                                            }
                                        }

                                        //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);
                                        //}
                                    }
                                    #endregion

                                    string PMS_CurrentStatus = "";
                                    //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_CurrentStatus = Q.Status.Name;
                                        }
                                        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();

                                    int Bright_Va = -1;
                                    if (Version == 0x03 || Version == 0x04)
                                    {
                                        var LiangDu = reader.ReadBytes(4);
                                        Bright_Va = (int)LiangDu[0];
                                    }
                                    if (Bright_Va == -1 || Bright_Va == 0)
                                    {
                                        Bright_Va = 100;
                                    }

                                    var CarbonVIP_NoFilter = CarbonVIP;
                                    byte[] carbon_enum = new byte[] { 0x01, 0x02 };
                                    if (!carbon_enum.Contains(CarbonVIP))
                                    {
                                        CarbonVIP = 0x00;
                                    }

                                    ///碳达人状态更新
                                    if (!string.IsNullOrEmpty(HostID))
                                    {
                                        string KKey = CacheKey.HostModalStatus_Prefix + "_" + HostID + "_" + "054000001";
                                        var OldHostModal = CSRedisCacheHelper.Get_Partition<HostModal_Cache>(KKey);
                                        if (OldHostModal != null)
                                        {
                                            OldHostModal.Status = CarbonVIP;
                                            CSRedisCacheHelper.Set_Partition<HostModal_Cache>(KKey, OldHostModal);
                                        }


                                        StringBuilder sb = new StringBuilder();
                                        sb.Append(CacheKey.CarbonVIP_Prefix);
                                        sb.Append("_");
                                        sb.Append(HostID.ToString());
                                        string Key = sb.ToString();

                                        string current_status_new = "";
                                        if (CarbonVIP == 0x01)
                                        {
                                            current_status_new = "open";
                                        }
                                        else if (CarbonVIP == 0x02)
                                        {
                                            current_status_new = "close";
                                        }
                                        else
                                        {
                                            current_status_new = "unknow";
                                        }

                                        CSRedisCacheHelper.Set(Key, current_status_new);
                                    }

                                    var DeviceCount = reader.ReadByte();
                                    int DeviceCount_I = (int)DeviceCount;


                                    List<NengHao_Repeat> nenghaoList = new List<NengHao_Repeat>();
                                    List<NengHaolog> nenghaoList1 = new List<NengHaolog>();
                                    List<KongTiao> kongtiaoList = new List<KongTiao>();
                                    for (int i = 0; i < DeviceCount_I; i++)
                                    {
                                        byte[] QA = reader.ReadBytes(4);
                                        //if (Version == 0x04)
                                        //{
                                        //    QA = reader.ReadBytes(5);
                                        //}
                                        //说明是能耗设备
                                        #region 能耗
                                        if (QA[0] == 0x39)
                                        {
                                            NengHao_Repeat nr = new NengHao_Repeat();
                                            NengHaolog nr1 = new NengHaolog();
                                            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.IsTakeCard = 是否取电;
                                            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);

                                            //这里不再发送这个了，改发送全部的数据

                                            nr.address = address;
                                            nr.dianya = n.V;
                                            nr.dianliu = n.A;
                                            nr.gonglv = n.P;
                                            nr.nenghao = n.KW_H;
                                            nr.zongnenghao = n.Sum_KW_H;
                                            nenghaoList.Add(nr);

                                            nr1.address = address;
                                            nr1.voltage = n.V;
                                            nr1.ampere = n.A;
                                            nr1.power = n.P;
                                            nr1.energy = n.KW_H;
                                            nr1.sum_energy = n.Sum_KW_H;
                                            nenghaoList1.Add(nr1);

                                            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);
                                            int XiaoShu_BuFen = 0;
                                            float xiaoshu_l = 0.0f;
                                            if (Version == 0x04)
                                            {
                                                var XiaoShu = reader.ReadByte();
                                                XiaoShu_BuFen = XiaoShu;
                                                xiaoshu_l = (float)XiaoShu_BuFen / 10;
                                            }

                                            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 (hotelCode.Equals("2144"))
                                                {
                                                    if (fanspeed == 2 || fanspeed == 3)
                                                    {
                                                        string KKKSpec = HostNNN + "_" + address;
                                                        if (status == 1)
                                                        {
                                                            string ReportTime111 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                                                            //JiNamTongPaiTeShu j111 = new JiNamTongPaiTeShu();
                                                            //j111.HostNumber = HostNNN;
                                                            //j111.Address = address;
                                                            //j111.CurrentTime = ReportTime111;

                                                            CSRedisCacheHelper.HMSet(5, CacheKey.JiNan_TongPai_Spec, KKKSpec, ReportTime111);
                                                        }
                                                        if (status == 0)
                                                        {
                                                            CSRedisCacheHelper.HDel(5, CacheKey.JiNan_TongPai_Spec, KKKSpec);
                                                        }
                                                    }
                                                }

                                                KongTiao kkk = new KongTiao();
                                                kkk.state = status;
                                                kkk.address = address;
                                                kkk.model = mode;
                                                kkk.speed = fanspeed;
                                                kkk.now_temp = Convert.ToInt32((currentTemp + xiaoshu_l) * 10);
                                                kkk.set_temp = temperature;
                                                kkk.solenoid_valve = valve;
                                                kongtiaoList.Add(kkk);
                                                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
                                    }

                                    #region 给宝镜推送的数据
                                    long tf0 = Tools.GetUnixTime();
                                    NengHao4BaoJing ns2 = new NengHao4BaoJing()
                                    {
                                        HotelCode = long.Parse(hotelCode),
                                        HostNumber = HostNNN,
                                        RoomNumber = RoomNUMBER,
                                        Mac = "",
                                        EndPoint = EndPoint,
                                        Version = ((int)Version).ToString(),
                                        IsTakeCard = 是否取电_Int,
                                        IsInsertCard = 是否插卡,
                                        CarbonVIP = CarbonVIP,
                                        NengHaoList = nenghaoList,
                                        //V = dianya,
                                        //A = dianliu,
                                        //P = gonglv,
                                        //Energy_Consumption = nenghao,
                                        //Sum_Energy_Consumption = zongnenghao,
                                        CreateTime = tf0,
                                        ReportTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                        AllDeviceData = DeviceStatusList,
                                        IdentityInfo = IdentityInfo,
                                        //CardID = IdentityInfo,
                                        CardEvent = NOCardInfo,
                                        PMS_Status = PMS_CurrentStatus,
                                        Bright_G = Bright_Va
                                    };

                                    string mns = Newtonsoft.Json.JsonConvert.SerializeObject(ns2);
                                    if (hotelCode.Equals("2302"))
                                    {
                                        //logger.Error("宝镜推送:"+mns); 
                                    }
                                    CSRedisCacheHelper.Publish("redis-power", mns);
                                    #endregion


                                    #region TSlog
                                    NewVersionLog tslog = new NewVersionLog()
                                    {
                                        version = (int)Version,
                                        hotel_id = hotelCode,
                                        room_id = RoomNUMBER,
                                        device_id = HostNNN,
                                        ip = EndPoint,
                                        power_state = 是否取电_Int,
                                        insert_card = 是否插卡,
                                        bright_g = Bright_Va,
                                        cardless_state = Convert.ToUInt16(NOCardInfo_NoFilter),
                                        guest_type = Convert.ToUInt16(IdentityInfo),
                                        service_mask = BitConverter.ToUInt64(N, 0),
                                        pms_state = Convert.ToUInt16(PMS),
                                        carbon_state = Convert.ToUInt16(CarbonVIP_NoFilter),
                                        device_count = DeviceCount_I,
                                        comm_seq = MyFrameNO,
                                        electricity = nenghaoList1,
                                        air_conditioner = kongtiaoList,
                                        extra = new extra_data()
                                        {
                                            original_byte = OriginalByte
                                        }
                                    };
                                    string mns111 = Newtonsoft.Json.JsonConvert.SerializeObject(tslog);
                                    CSRedisCacheHelper.Publish("redis-tslog", mns111);
                                    #endregion
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            logger.Error("定时上报出错:" + Tools.ByteToString(context111.Data));
                            logger.Error("定时上报出错:" + ex.Message);
                            logger.Error("定时上报出错:" + ex.StackTrace);
                        }
                    }
                    #endregion

                    #region 向服务器获取房态
                    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);
                        }
                    }
                    #endregion

                }, tuple);
        }
        public struct JiNamTongPaiTeShu
        {
            public string HostNumber { get; set; }
            public string Address { get; set; }
            public string CurrentTime { get; set; }
        }

        /// <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; }
        }
    }
}
