wxr
2024-12-02 ea0b1e8e5f43c5fd0a7d479e25ede3b8cbea464a
HDL_ON/DAL/DriverLayer/Control.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using HDL_ON.DAL.Mqtt;
using HDL_ON.DAL.Server;
using HDL_ON.Entity;
using HDL_ON.UI;
@@ -83,8 +84,10 @@
        /// <summary>
        /// 判断是否本地加密并且加密key不为空
        /// </summary>
        public bool IsLocalEncryptAndGetAesKey {
            get {
        public bool IsLocalEncryptAndGetAesKey
        {
            get
            {
                return IsLocalEncrypt && (!string.IsNullOrEmpty(DB_ResidenceData.Instance.CurrentRegion.localSecret));
            }
        }
@@ -108,7 +111,7 @@
                    {
                        //修改主页连接状态
                        HomePage.LoadEvent_CheckLinkStatus();
                        MainPage.Log($"网关局域网在线,刷新设备状态");
                        //MainPage.Log($"网关局域网在线,刷新设备状态");
                        new System.Threading.Thread(() =>
                        {
                            System.Threading.Thread.Sleep(1000);
@@ -121,6 +124,10 @@
                        //修改主页连接状态
                        HomePage.LoadEvent_CheckLinkStatus();
                    }
                }
                else
                {
                    //MainPage.Log($"状态一致,不更新数据(本地)");
                }
            }
        }
@@ -136,45 +143,65 @@
            }
            set
            {
                if (_GatewayOnline_Cloud != value)
                try
                {
                    _GatewayOnline_Cloud = value;
                    if(GatewayOnline_Local)
                    if (_GatewayOnline_Cloud != value)
                    {
                        return;
                    }
                    if (value)
                    {
                        if (DB_ResidenceData.Instance.HomeGateway == null)
                        _GatewayOnline_Cloud = value;
                        if (GatewayOnline_Local)
                        {
                            return;
                        }
                        if (!DB_ResidenceData.Instance.HomeGateway.gatewayStatus)//远程情况下,网关未链接服务器不能修改主页网关状态
                        if (value)
                        {
                            if (DB_ResidenceData.Instance.HomeGateway == null)
                            {
                                return;
                            }
                            if (!DB_ResidenceData.Instance.HomeGateway.gatewayStatus)//远程情况下,网关未链接服务器不能修改主页网关状态
                            {
                                new System.Threading.Thread(() =>
                                {
                                    System.Threading.Thread.Sleep(3000);
                                    var pm = new DAL.Server.HttpServerRequest();
                                    pm.GetGatewayInfo();
                                })
                                { IsBackground = true }.Start();
                                return;
                            }
                            //修改主页连接状态
                            HomePage.LoadEvent_CheckLinkStatus();
                            MainPage.Log($"网关云端在线,刷新设备状态");
                            new System.Threading.Thread(() =>
                            {
                                System.Threading.Thread.Sleep(3000);
                                var pm = new DAL.Server.HttpServerRequest();
                                pm.GetGatewayInfo();
                                int count = 20;
                                while (true)
                                {
                                    System.Threading.Thread.Sleep(500);
                                    if (MqttClient.isSubscribeSuccess || count < 1)
                                    {
                                        break;
                                    }
                                    count--;
                                }
                                FunctionList.List.ReadAllFunctionStatus();
                            })
                            { IsBackground = true }.Start();
                            return;
                            { IsBackground = true, Priority = System.Threading.ThreadPriority.AboveNormal }.Start();
                        }
                        //修改主页连接状态
                        HomePage.LoadEvent_CheckLinkStatus();
                        MainPage.Log($"网关云端在线,刷新设备状态");
                        new System.Threading.Thread(() =>
                        else
                        {
                            System.Threading.Thread.Sleep(1000);
                            FunctionList.List.ReadAllFunctionStatus();
                        })
                        { IsBackground = true, Priority = System.Threading.ThreadPriority.AboveNormal }.Start();
                            //修改主页连接状态
                            HomePage.LoadEvent_CheckLinkStatus();
                        }
                    }
                    else
                    {
                        //修改主页连接状态
                        HomePage.LoadEvent_CheckLinkStatus();
                        MainPage.Log($"状态一致,不更新数据(云端)");
                    }
                }
                catch (Exception ex)
                {
                    MainPage.Log($"Set GatewayCloudOnline Error:{ex.Message}");
                }
            }
        }
@@ -237,9 +264,11 @@
        {
            if (myTcpClient == null)
            {
                myTcpClient = new Control_TcpClient(reportIp);
                myTcpClient = new Control_TcpClient(reportIp, 8586);
            }
            myTcpClient.Connect();
            MainPage.Log("打开tcp");
            myTcpClient.init();
            Ins.LoginGateway();
        }
@@ -249,7 +278,7 @@
        public void SearchLoaclGateway()
        {
            //2021-01-15 : 住宅没有绑定网关的时候不用搜索,并且不能链接mqtt
            if(DB_ResidenceData.Instance.HomeGateway == null || string.IsNullOrEmpty(DB_ResidenceData.Instance.HomeGateway.gatewayId))
            if (DB_ResidenceData.Instance.HomeGateway == null || string.IsNullOrEmpty(DB_ResidenceData.Instance.HomeGateway.gatewayId))
            {
                return;
            }
@@ -264,10 +293,11 @@
            }
            else if (MainPage.InternetStatus == 1)
            {
                DAL.Mqtt.MqttClient.InitState();
                MqttClient.InitState();
            }
            else if (MainPage.InternetStatus == 2)
            {
                MqttClient.InitState();
                OpenUdp(DB_ResidenceData.Instance.GatewayType == 0 ? 6000 : 8585);
                //重置搜索网关标志
                IsSearchLocalGatewaySuccessful = false;
@@ -294,12 +324,10 @@
                        System.Threading.Thread.Sleep(500);
                    }
                    DAL.Mqtt.MqttClient.InitState();
                })
                { IsBackground = true }.Start();
            }
        }
        private System.Threading.Thread loginGatewayThread;
@@ -308,46 +336,25 @@
        /// </summary>
        public void LoginGateway()
        {
            if(loginGatewayThread== null)
            if (loginGatewayThread == null && !LocalTcpClientLogin)
            {
                loginGatewayThread = new System.Threading.Thread(() => {
                    while (!Ins.myTcpClient.isConnected)
                loginGatewayThread = new System.Threading.Thread(() =>
                {
                    if (Ins.GatewayOnline_Local)
                    {
                        if (Ins.GatewayOnline_Local && myTcpClient.isConnected)
                        while (!LocalTcpClientLogin)
                        {
                            var sendData = new { clientType = "app", version = "1.0" };
                            var sendJob = new { id = Control.Ins.msg_id.ToString(), time_stamp = Utlis.GetTimestamp(), objects = sendData };
                            var bodyString = JsonConvert.SerializeObject(sendJob);
                            var sendBytes = ConvertSendBodyData($"/user/{GatewayId}/custom/gateway/login", bodyString);
                            Ins.myTcpClient.SendMessage(sendBytes);
                            Ins.myTcpClient.CommSend(sendBytes, sendBytes.Length);
                            System.Threading.Thread.Sleep(1000);
                        }
                        System.Threading.Thread.Sleep(2000);
                    }
                    //loginGatewayThread?.Abort();
                    //loginGatewayThread = null;
                });
                loginGatewayThread.Start();
            }
            else
            {
                try
                {
                    loginGatewayThread?.Abort();
                }catch (Exception ex)
                {
                    MainPage.Log($"重启登录网关线程异常:{ex.Message}");
                }
                finally
                {
                    loginGatewayThread = null;
                    LoginGateway();
                }
            }
        }
@@ -357,9 +364,9 @@
        public void ControlScene(Scene scene)
        {
            //体验模式
            if(MainPage.NoLoginMode)
            if (MainPage.NoLoginMode)
            {
                foreach(var sceneFunction in scene.functions)
                foreach (var sceneFunction in scene.functions)
                {
                    var revString = "";
                    var upDataObj = new AlinkFunctionStatusObj();
@@ -373,7 +380,7 @@
                    }
                    asd.status = status1;
                    upDataObj.objects.Add(asd);
                    revString = Newtonsoft.Json.JsonConvert.SerializeObject(upDataObj);
                    revString = JsonConvert.SerializeObject(upDataObj);
                    UpdataFunctionStatus(revString, null, true);
                }
                return;
@@ -406,14 +413,14 @@
        /// <param name="function"></param>
        /// <param name="useRemote">是否直接使用远程发送</param>
        /// <returns></returns>
        public bool SendWriteCommand(Function function, Dictionary<string, string> commandDictionary, bool useRemote = false,int resend = 3)
        public bool SendWriteCommand(Function function, Dictionary<string, string> commandDictionary, bool useRemote = false, int resend = 3)
        {
            function.controlCounter++;
            function.refreshTime = DateTime.Now;
            //如果是控制调光的开时,亮度值不能为0
            if (commandDictionary.Count > 2)
            if (commandDictionary.Count >= 2)
            {
                if (commandDictionary.ContainsKey(FunctionAttributeKey.OnOff) && commandDictionary.ContainsKey(FunctionAttributeKey.Brightness))
                {
@@ -449,13 +456,12 @@
                }
                asd.status = status1;
                upDataObj.objects.Add(asd);
                revString = Newtonsoft.Json.JsonConvert.SerializeObject(upDataObj);
                revString = JsonConvert.SerializeObject(upDataObj);
                UpdataFunctionStatus(revString, null, true);
                return true;
            }
            //MainPage.Log($"发送数据:{Newtonsoft.Json.JsonConvert.SerializeObject(commandDictionary)}");
            //MainPage.Log($"发送数据:{JsonConvert.SerializeObject(commandDictionary)}");
            ///第三方涂鸦设备统一使用远程控制
            switch (function.spk)
@@ -502,10 +508,11 @@
                    else
                    {
                        var functionControlDataObj = function.GetGatewayAlinkControlData(commandDictionary);
                        var functionControlDataJson = Newtonsoft.Json.JsonConvert.SerializeObject(functionControlDataObj);
                        var functionControlDataJson = JsonConvert.SerializeObject(functionControlDataObj);
                        var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.ControlFunctionTopic, functionControlDataJson);
                        new Control_Udp().SendLocalHdlLinkData(sendBytes, functionControlDataObj.id,resend);
                        new Control_Udp().SendLocalHdlLinkData(sendBytes, functionControlDataObj.id, resend);
                        MainPage.Log($"本地通讯 发送HDL-Link数据:{functionControlDataJson}");
                        //Ins.myTcpClient.SendMessage(sendBytes);
                    }
                }
                //远程通讯
@@ -522,7 +529,7 @@
                                commandDictionary.Add(FunctionAttributeKey.OnOff, commandDictionary[FunctionAttributeKey.Brightness] == "0" ? "off" : "on");
                            }
                        }
                        if(function.spk == SPK.LightCCT)
                        if (function.spk == SPK.LightCCT)
                        {
                            if (!commandDictionary.ContainsKey(FunctionAttributeKey.CCT))
                            {
@@ -546,10 +553,10 @@
        /// <summary>
        /// 全开全关功能
        /// </summary>
        public void SwtichFunctions(bool open,List<Function> functions)
        public void SwtichFunctions(bool open, List<Function> functions)
        {
            //dome模式控制
            if(MainPage.NoLoginMode)
            if (MainPage.NoLoginMode)
            {
                new System.Threading.Thread(() =>
                {
@@ -557,7 +564,7 @@
                    {
                        Dictionary<string, string> d1 = new Dictionary<string, string>();
                        d1.Add(FunctionAttributeKey.OnOff, open ? "on" : "off");
                         if (function.spk == SPK.PanelSocket)
                        if (function.spk == SPK.PanelSocket)
                        {
                            if (function.attributes.Find((obj) => obj.key == "on_off_usb") != null)
                            {
@@ -595,6 +602,10 @@
            {
                foreach (var temp in functions)
                {
                    if ((temp.trait_on_off.state.ToString() == "on" && open) || temp.trait_on_off.state.ToString() == "off" && !open)
                    {
                        continue;
                    }
                    var apiControlData = temp.GetApiControlData(d);
                    actionObjs.Add(apiControlData);
                    count++;
@@ -606,7 +617,10 @@
                        System.Threading.Thread.Sleep(100);
                    }
                }
                var pack = pm.ControlDevice(actionObjs);
                if (actionObjs.Count > 0)
                {
                    var pack = pm.ControlDevice(actionObjs);
                }
            }
        }
@@ -623,16 +637,16 @@
        {
            var pm = new DAL.Server.HttpServerRequest();
            var pack = pm.GetDeviceInfoList(functionIds);
            if(pack!= null&& pack.Data!=null)
            if (pack != null && pack.Data != null)
            {
                //待测试2021-03-04
                var ddd = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AlinkStatusData>>(pack.Data.ToString());
                if(ddd!= null)
                var ddd = JsonConvert.DeserializeObject<List<AlinkStatusData>>(pack.Data.ToString());
                if (ddd != null)
                {
                    foreach(var function in ddd)
                    foreach (var function in ddd)
                    {
                        var temp = FunctionList.List.GetDeviceFunctionList().Find((obj) => obj.deviceId == function.deviceId);
                        if(temp!= null)
                        if (temp != null)
                        {
                            if (SPK.Get3tySpk(SPK.BrandType.Tuya).Contains(temp.spk))
                            {
@@ -648,7 +662,7 @@
        /// 发送读取命令
        /// 自动判断是否为A协议设备
        /// </summary>
        public void SendReadCommand(Function function ,bool forceRemote = false)
        public void SendReadCommand(Function function, bool forceRemote = false)
        {
            function.refreshTime = DateTime.Now;
            if (forceRemote)
@@ -686,7 +700,7 @@
                                        },
                            time_stamp = Utlis.GetTimestamp()
                        };
                        var functionControlDataJson = Newtonsoft.Json.JsonConvert.SerializeObject(readDataObj);
                        var functionControlDataJson = JsonConvert.SerializeObject(readDataObj);
                        var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.ReadStatus, functionControlDataJson);
                        MainPage.Log($"本地通讯 发送HDL-Link数据:{functionControlDataJson}");
                        new Control_Udp().SendLocalHdlLinkData(sendBytes, readDataObj.id);
@@ -694,8 +708,19 @@
                }
                else
                {
                    var pm = new DAL.Server.HttpServerRequest();
                    var pack = pm.RefreshDeviceStatus(new List<string>() { function.deviceId });
                    var pm = new HttpServerRequest();
                    try
                    {
                        pm.RefreshDeviceStatus(new List<string>() { function.deviceId });
                    }
                    catch (Exception ex)
                    {
                        MainPage.Log($"远程读取设备状态异常:{ex.Message}");
                    }
                    finally
                    {
                        pm = null;
                    }
                }
            }
        }
@@ -732,7 +757,7 @@
                            {
                                busClient.ReadBusData(function);
                            }
                        }
                        catch (Exception ex)
                        {
@@ -758,7 +783,7 @@
                            objects = objects,
                            time_stamp = Utlis.GetTimestamp()
                        };
                        var functionControlDataJson = Newtonsoft.Json.JsonConvert.SerializeObject(readDataObj);
                        var functionControlDataJson = JsonConvert.SerializeObject(readDataObj);
                        var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.ReadStatus, functionControlDataJson);
                        MainPage.Log($"本地通讯 发送HDL-Link数据:{functionControlDataJson}");
                        new Control_Udp().SendLocalHdlLinkData(sendBytes, readDataObj.id);
@@ -776,7 +801,7 @@
        /// <summary>
        /// 安防控制
        /// </summary>
        public void ControlSecurity(SecurityAlarm securityAlarm,string state)
        public void ControlSecurity(SecurityAlarm securityAlarm, string state)
        {
            if (!Ins.GatewayOnline_Local)//网关本地不在线
            {
@@ -802,7 +827,7 @@
                        },
                    time_stamp = Utlis.GetTimestamp()
                };
                var aLinkJson = Newtonsoft.Json.JsonConvert.SerializeObject(aLinkData);
                var aLinkJson = JsonConvert.SerializeObject(aLinkData);
                var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.ControlSeurity, aLinkJson);
                new Control_Udp().SendLocalHdlLinkData(sendBytes, aLinkData.id);
            }
@@ -832,9 +857,9 @@
                        },
                    time_stamp = Utlis.GetTimestamp()
                };
                var aLinkJson = Newtonsoft.Json.JsonConvert.SerializeObject(aLinkData);
                var aLinkJson = JsonConvert.SerializeObject(aLinkData);
                var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.ControlScene, aLinkJson);
                new Control_Udp().SendLocalHdlLinkData(sendBytes, aLinkData.id,0);
                new Control_Udp().SendLocalHdlLinkData(sendBytes, aLinkData.id, 0);
            }
        }
@@ -856,7 +881,7 @@
                    objects = objects,
                    time_stamp = Utlis.GetTimestamp()
                };
                var functionControlDataJson = Newtonsoft.Json.JsonConvert.SerializeObject(readDataObj);
                var functionControlDataJson = JsonConvert.SerializeObject(readDataObj);
                var sendBytes = Ins.ConvertSendBodyData($"/base/{DB_ResidenceData.Instance.HomeGateway.gatewayId}/thing/service/MusicPlayGroupListGet/down", functionControlDataJson);
                MainPage.Log($"本地通讯 发送HDL-Link数据:{functionControlDataJson}");
                new Control_Udp().SendLocalHdlLinkData(sendBytes, readDataObj.id);
@@ -874,7 +899,7 @@
            var sendId = Ins.msg_id.ToString();
            var sendObj = new { objects = objects1, id = sendId, time_stamp = Utlis.GetTimestamp() };
            var aLinkJson = Newtonsoft.Json.JsonConvert.SerializeObject(sendObj);
            var aLinkJson = JsonConvert.SerializeObject(sendObj);
            var sendBytes = Ins.ConvertSendBodyData(CommunicationTopic.ct.AuthGateway, aLinkJson);
            new Control_Udp().SendLocalHdlLinkData(sendBytes, Ins.msg_id.ToString());
        }
@@ -888,14 +913,6 @@
        /// <returns></returns>
        public byte[] ConvertSendBodyData(string topic, string bodyDataString, bool isEncryption = true)
        {
            //string topicString = "Topic:" + topic + "\r\n";
            //byte[] bodyBytes = Encoding.ASCII.GetBytes(bodyDataString);
            //string lengthString = "Length:" + bodyBytes.Length.ToString() + "\r\n" + "\r\n";
            //string sendDataString = topicString + lengthString + bodyDataString;
            //byte[] sendDataBytes = Encoding.ASCII.GetBytes(sendDataString);
            //MainPage.Log($"转换HDL-Link数据\r\n{sendDataString}\r\n");
            //***************************************************************
            //2021-09-23 增加本地通信加密处理
            //1.拼接头
@@ -906,8 +923,6 @@
            if (isEncryption && IsLocalEncryptAndGetAesKey)
            {
                bodyBytes = Securitys.EncryptionService.AesEncryptPayload(bodyBytes, DB_ResidenceData.Instance.CurrentRegion.localSecret);
                //bodyDataString = Encoding.UTF8.GetString(bodyBytes);
                //MainPage.Log($"转换HDL-Link数据 加密key:" + DB_ResidenceData.Instance.CurrentRegion.localSecret);
            }
            //3.拼接body的Length长度数据
            string lengthString = "Length:" + bodyBytes.Length.ToString() + "\r\n" + "\r\n";
@@ -919,7 +934,6 @@
            bodyBytes.CopyTo(sendDataBytes, topicAndLengthBytes.Length);
            var sendDataString = Encoding.UTF8.GetString(sendDataBytes);
            MainPage.Log($"转换HDL-Link数据\r\n{sendDataString}\r\n");
            //***************************************************************
            return sendDataBytes;
@@ -928,10 +942,10 @@
        /// 转换接收到的数据
        /// </summary>
        /// <returns></returns>
        public void ConvertReceiveData(byte[] receiveBytes,string ip)
        public void ConvertReceiveData(byte[] receiveBytes, string ip)
        {
            var reString = Encoding.UTF8.GetString(receiveBytes);
            AnalysisReceiveData(reString, receiveBytes,ip);
            AnalysisReceiveData(reString, receiveBytes, ip);
        }
        /// <summary>
        /// 转换接收到的数据
@@ -939,17 +953,14 @@
        /// <param name="receiveString">转String后的数据</param>
        /// <param name="originalReceiveBytes"原始Bytes数据</param>
        /// <returns></returns>
        public LocalCommunicationData AnalysisReceiveData(string receiveString, byte[] originalReceiveBytes , string sIp = null)
        public LocalCommunicationData AnalysisReceiveData(string receiveString, byte[] originalReceiveBytes, string sIp = null)
        {
            LocalCommunicationData receiveObj = new LocalCommunicationData();
            var res = receiveString.Split("\r\n\r\n");
            if (res.Length == 2)
            {
                var topics = res[0].Split("\r\n");
                //MainPage.Log(res[1]);
                foreach (var ts in topics)
                {
                    var key = ts.Split(":");
@@ -964,20 +975,11 @@
                    }
                }
                //MainPage.Log($"局域网信息: {receiveObj.Topic}  : 内容: {res[1]}");
                //验证有效数据长度
                //if (res[1].Length != receiveObj.Length)
                //{
                //    MainPage.Log($"收到数据包长度不够");
                //    return receiveObj;
                //}
                receiveObj.BodyDataString = res[1];
                ///UDP不出tcp心跳包
                if (receiveObj.Topic == CommunicationTopic.ct.HeartBeat + "_reply")
                {
                    Ins.myTcpClient.ClearHeartBeatLog();
                    MainPage.Log("tcp心跳回复");
                    return null;
                }
@@ -998,61 +1000,49 @@
                            {
                                var revString = Encoding.UTF8.GetString(receiveBytes);
                                receiveObj.BodyDataString = revString;
                                MainPage.Log($"局域网信息: 解密后:" + receiveObj.BodyDataString);
                                //if (receiveObj.Topic.EndsWith("/thing/property/up"))
                                //{
                                //    MsgInfoList.Add(revString + "\r\n");
                                //}
                            }
                        }
                        else
                        {
                            //目前不拿原始Bytes数据 解密不了
                            //byte[] receiveBytes = Encoding.UTF8.GetBytes(res[1]);
                            //MainPage.Log($"局域网信息 receiveBytes {receiveBytes.Length}");
                            //receiveBytes = Securitys.EncryptionService.AesDecryptPayload(receiveBytes, DB_ResidenceData.Instance.CurrentRegion.localSecret);
                            //MainPage.Log($"局域网信息 解密后:receiveBytes {receiveBytes.Length}");
                            //var revString = Encoding.UTF8.GetString(receiveBytes);
                            //receiveObj.BodyDataString = revString;
                            //MainPage.Log($"局域网信息: 解密后:" + receiveObj.BodyDataString);
                        }
                    }
                }
                    }
                    else
                    {
                        MainPage.Log($"局域网信息: 明文:" + receiveObj.BodyDataString);
                    }
                if (receiveObj.BodyDataString == null)
                {
                    MainPage.Log($"UDP receiveObj.BodyDataString == null");
                    return null;
                }
                try
                {
                    var idMsg = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack>(res[1]);
                    var idMsg = JsonConvert.DeserializeObject<ResponsePack>(receiveObj.BodyDataString);
                    var hasProcess = hasItBeenProcessed(idMsg.id);
                    if (hasProcess)
                    {
                        return null;
                        if (receiveObj.Topic != CommunicationTopic.SearchLoaclGatewayReply)
                        {
                            //MainPage.Log($"UDP不处理重复数据:{idMsg.id}");
                            return null;
                        }
                    }
                    MainPage.Log($"处理局域网数据id:{idMsg.id}");
                }
                catch (Exception ex)
                {
                    MainPage.Log($"解析局域网数据异常{ex.Message}");
                    MainPage.Log($"解析数据异常:{ex.StackTrace}\r\n<<-->>{receiveObj.BodyDataString}");
                }
                MainPage.Log($"UDP处理数据:Topic:{receiveObj.Topic}===Context====" + receiveObj.BodyDataString);
                if (receiveObj.Topic == CommunicationTopic.SearchLoaclGatewayReply || receiveObj.Topic == CommunicationTopic.GatewayBroadcast)
                {
                    var bodyJObj = Newtonsoft.Json.JsonConvert.DeserializeObject<ResponsePack>(res[1]);
                    var bodyJObj = JsonConvert.DeserializeObject<ResponsePack>(res[1]);
                    if (bodyJObj == null)
                    {
                        return receiveObj;
                    }
                    var device = Newtonsoft.Json.JsonConvert.DeserializeObject<DeviceModule>(bodyJObj.objects.ToString());
                    var device = JsonConvert.DeserializeObject<DeviceModule>(bodyJObj.objects.ToString());
                    if (device.device_mac.ToUpper() == DB_ResidenceData.Instance.HomeGateway.mac.ToUpper())
                    {
                        MainPage.Log("本地搜索网关成功");
                        MainPage.Log("网关本地在线");
                        Ins.IsSearchLocalGatewaySuccessful = true;
                        Ins.GatewayOnline_Local = true;
                        if (!string.IsNullOrEmpty(device.gatewayId))
@@ -1070,19 +1060,17 @@
                        reportIp = device.ip_address;//主播地址也能控制设备//"239.0.168.188";//
                        //2021-09-23 新增获取当前网关是否本地加密
                        Ins.IsLocalEncrypt = device.isLocalEncrypt;
                        //MainPage.Log("网关本地加密状态:" + device.local_encrypt.ToString());
                        //登录网关Tcp
                        //登录网关Tcp  tcp连接网关
                        OpenTcpClent();
                    }
                }
                else if (receiveObj.Topic == CommunicationTopic.ct.ReadStatus + "_reply" ||
                    receiveObj.Topic == CommunicationTopic.ct.ControlFunctionTopic + "_reply" ||
                    receiveObj.Topic == CommunicationTopic.ct.ControlGroupControlTopic + "_reply" ||
                    receiveObj.Topic == CommunicationTopic.ct.GatewayUpStatus ||
                    receiveObj.Topic.Contains(CommunicationTopic.ct.GatewayUpSortTopic))
                {
                    //TODO 暂时不传正确的数据上去,如果后面要优化前面这些代码
                    UpdataFunctionStatus(receiveObj.BodyDataString, null);
                }
                else if (receiveObj.Topic == CommunicationTopic.ct.ControlSeurity + "_reply"
@@ -1091,11 +1079,10 @@
                {
                    try
                    {
                        MainPage.Log($"局域网安防信息: {receiveObj.Topic}  : 内容: {res[1]}");
                        var tt = "";
                        lock (tt)
                        {
                            var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<SecurityStatusObj>(receiveObj.BodyDataString);
                            var temp = JsonConvert.DeserializeObject<SecurityStatusObj>(receiveObj.BodyDataString);
                            if (temp != null)
                            {
                                Control_Udp.ReceiveRepeatManager(temp.id, null);
@@ -1118,8 +1105,9 @@
                        MainPage.Log($"安防局域网异常:{ex.Message}");
                    }
                }
                else if (receiveObj.Topic == $"/user/{GatewayId}/custom/gateway/login_reply") {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(receiveObj.BodyDataString);
                else if (receiveObj.Topic == $"/user/{GatewayId}/custom/gateway/login_reply")
                {
                    var temp = JsonConvert.DeserializeObject<JObject>(receiveObj.BodyDataString);
                    if (temp.GetValue("objects").ToString().Contains("success"))
                    {
                        LocalTcpClientLogin = true;
@@ -1147,6 +1135,128 @@
            return receiveObj;
        }
        public LocalCommunicationData AnalysisReceiveData(string topic, byte[] bodyBytes)
        {
            LocalCommunicationData receiveObj = new LocalCommunicationData();
            receiveObj.Topic = topic;
            if (receiveObj.Topic == CommunicationTopic.ct.HeartBeat + "_reply")
            {
                Ins.myTcpClient.ClearHeartBeatLog();
                MainPage.Log("tcp心跳回复");
                return null;
            }
            //2021-09-23 过滤不需要解密的主题 目前搜索网关主题不加密
            if (receiveObj.Topic != CommunicationTopic.SearchLoaclGatewayReply)
            {
                //判断当前网关是否开启了本地加密
                if (IsLocalEncryptAndGetAesKey)
                {
                    byte[] receiveBytes = Securitys.EncryptionService.AesDecryptPayload(bodyBytes, DB_ResidenceData.Instance.CurrentRegion.localSecret);
                    if (receiveBytes != null)
                    {
                        receiveObj.BodyDataString = Encoding.UTF8.GetString(receiveBytes);
                    }
                }
            }
            else
            {
                receiveObj.BodyDataString = Encoding.UTF8.GetString(bodyBytes);
            }
            if (receiveObj.BodyDataString == null)
            {
                MainPage.Log($"TCP receiveObj.BodyDataString == null");
                return null;
            }
            try
            {
                var idMsg = JsonConvert.DeserializeObject<ResponsePack>(receiveObj.BodyDataString);
                var hasProcess = hasItBeenProcessed(idMsg.id);
                if (hasProcess)
                {
                    //MainPage.Log($"TCP不处理重复数据{idMsg.id}");
                    return null;
                }
            }
            catch (Exception ex)
            {
                MainPage.Log($"解析数据异常:{ex.StackTrace}\r\n<<-->>{receiveObj.BodyDataString}");
            }
            MainPage.Log($"TCP处理数据:Topic:{receiveObj.Topic}===Context====" + receiveObj.BodyDataString);
            if (receiveObj.Topic == CommunicationTopic.ct.ReadStatus + "_reply" ||
                receiveObj.Topic == CommunicationTopic.ct.ControlFunctionTopic + "_reply" ||
                receiveObj.Topic == CommunicationTopic.ct.ControlGroupControlTopic + "_reply" ||
                receiveObj.Topic == CommunicationTopic.ct.GatewayUpStatus ||
                receiveObj.Topic.Contains(CommunicationTopic.ct.GatewayUpSortTopic))
            {
                UpdataFunctionStatus(receiveObj.BodyDataString, null);
            }
            else if (receiveObj.Topic == CommunicationTopic.ct.ControlSeurity + "_reply"
                || receiveObj.Topic == CommunicationTopic.ct.ReadSecurityStatus + "_reply"
                || receiveObj.Topic == CommunicationTopic.ct.SecurityStatusUp)
            {
                try
                {
                    var tt = "";
                    lock (tt)
                    {
                        var temp = JsonConvert.DeserializeObject<SecurityStatusObj>(receiveObj.BodyDataString);
                        if (temp != null)
                        {
                            Control_Udp.ReceiveRepeatManager(temp.id, null);
                            foreach (var updataSecurity in temp.objects)
                            {
                                var updataLocalSecurity = FunctionList.List.securities.Find((obj) => obj.sid == updataSecurity.sid);
                                if (updataLocalSecurity != null)
                                {
                                    updataLocalSecurity.status = updataSecurity.status;
                                    updataLocalSecurity.alarm = updataSecurity.alarm;
                                    ArmCenterPage.LoadEvent_RefreshSecurityStatus(updataLocalSecurity);
                                }
                            }
                            HomePage.LoadEvent_RefreshSecurityStatus();
                        }
                    }
                }
                catch (Exception ex)
                {
                    MainPage.Log($"安防局域网异常:{ex.Message}");
                }
            }
            else if (receiveObj.Topic == $"/user/{GatewayId}/custom/gateway/login_reply")
            {
                var temp = JsonConvert.DeserializeObject<JObject>(receiveObj.BodyDataString);
                if (temp.GetValue("objects").ToString().Contains("success"))
                {
                    LocalTcpClientLogin = true;
                    try
                    {
                        loginGatewayThread?.Abort();
                    }
                    catch (Exception ex)
                    {
                        MainPage.Log($"终止登录网关tcp异常:{ex.Message}");
                    }
                    finally
                    {
                        loginGatewayThread = null;
                    }
                    MainPage.Log("局域网tcp连接登录网关成功");
                }
            }
            else
            {
                //一些特殊的主题处理(为了执行速度,尽可能的别加耗时的操作)
                Stan.HdlCloudReceiveLogic.Current.CloudOverallMsgReceiveEx(receiveObj.Topic, receiveObj.BodyDataString);
            }
            return receiveObj;
        }
        private List<string> processedDataList = new List<string>();
        /// <summary>
@@ -1155,27 +1265,81 @@
        /// <returns></returns>
        private bool hasItBeenProcessed(string msgId)
        {
            if (processedDataList.Contains(msgId))
            lock (processedDataList)
            {
                return true;
            }
            else
            {
                if(processedDataList.Count> 50)
                if (processedDataList.Contains(msgId))
                {
                    processedDataList.RemoveAt(0);
                    return true;
                }
                return false;
                else
                {
                    processedDataList.Add(msgId);
                    if (processedDataList.Count > 50)
                    {
                        processedDataList.RemoveAt(0);
                    }
                    return false;
                }
            }
        }
        /// <summary>
        /// 更新群控设备状态
        /// A协议数据
        /// </summary>
        public void UpdataGroupControlStatus(string revString, byte[] usefulBytes, bool isCloudData = false)
        {
            var temp = JsonConvert.DeserializeObject<AlinkFunctionStatusObj>(revString);
            if (temp != null)
            {
                Control_Udp.ReceiveRepeatManager(temp.id, usefulBytes);
                var allLocalFuntion = FunctionList.List.groupControls;
                foreach (var updateTemp in temp.objects)
                {
                    try
                    {
                        var localFunction = allLocalFuntion.Find((obj) => obj.sid == updateTemp.sid);
                        if (localFunction == null)
                        {
                            continue;
                        }
                        MainPage.Log($"收到群控数据:{revString}");
                        foreach (var attr in updateTemp.status)
                        {
                            localFunction.time_stamp = temp.time_stamp;
                            localFunction.SetAttrState(attr.key, attr.value);
                        }
                        //更新界面状态
                        switch (localFunction.spk)
                        {
                            case SPK.ElectricEnergy:
                                EnergyMainPage.UpdataStatus(localFunction);
                                break;
                        }
                        HomePage.UpdataFunctionStates(localFunction);
                        RoomPage.UpdataStates(localFunction);
                        FunctionPage.UpdataStates(localFunction);
                        ClassificationPage.UpdataInfo(localFunction);
                    }
                    catch (Exception ex)
                    {
                        MainPage.Log($"A协议更新状态异常:{ex.Message}");
                    }
                }
            }
        }
        /// <summary>
        /// 更新设备状态
        /// A协议数据
        /// </summary>
        /// <param name="updateBytes"></param>
        public void UpdataFunctionStatus(string revString, byte[] usefulBytes,bool isCloudData = false)
        public void UpdataFunctionStatus(string revString, byte[] usefulBytes, bool isCloudData = false)
        {
            ////test 云端连接成功时,不适用本地数据更新
            //if (Ins.GatewayOnline_Cloud && !isCloudData)
@@ -1183,7 +1347,7 @@
            //    return;
            //}
            var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<AlinkFunctionStatusObj>(revString);
            var temp = JsonConvert.DeserializeObject<AlinkFunctionStatusObj>(revString);
            if (temp != null)
            {
                Control_Udp.ReceiveRepeatManager(temp.id, usefulBytes);
@@ -1197,7 +1361,7 @@
                        {
                            if (FunctionList.List.OtherBrandFunction.Count == 0)
                            {
                                MainPage.Log($"A协议更新状态:本地链接,除了涂鸦设备数据之外的云端数据不处理...");
                                //MainPage.Log($"A协议更新状态:本地链接,除了涂鸦设备数据之外的云端数据不处理...");
                                return;
                            }
                            else
@@ -1214,17 +1378,6 @@
                        {
                            continue;
                        }
                        MainPage.Log(localFunction.name);
                        if (Ins.GatewayOnline_Local && isCloudData)//本地链接,除了涂鸦设备数据之外的云端数据不处理
                        {
                            if (!SPK.Get3tySpk(SPK.BrandType.All3tyBrand).Contains(localFunction.spk) && !SPK.MusicSpkList().Contains( localFunction.spk))
                            {
                                //MainPage.Log($"A协议更新状态:本地链接,除了涂鸦设备数据之外的云端数据不处理........");
                                return;
                            }
                        }
                        //if (SPK.MusicSpkList().Contains(localFunction.spk))
                        //{
@@ -1235,24 +1388,50 @@
                        //        return;
                        //    }
                        //}
                        //MainPage.Log($"A协议更新状态:{revString}");
                        //MainPage.Log($"收到数据:{revString}");
                        foreach (var attr in updateTemp.status)
                        {
                            localFunction.time_stamp = temp.time_stamp;
                            localFunction.SetAttrState(attr.key, attr.value);
                            //Console.WriteLine("音乐播放器添加缓存数据=======" + revString);
                        }
                        if (localFunction.spk == SPK.AirSwitchP3)
                        {
                            localFunction.online = updateTemp.online;
                        }
                        if (SPK.LightSpkList().Contains(localFunction.spk))
                        {
                            localFunction.updateTime = DateTime.Now;
                        }
                        //更新界面状态
                        switch (localFunction.spk)
                        {
                            case SPK.AcstParent:
                                AcstParentPage.UpdateAcstParentInfo(localFunction);
                                break;
                            case SPK.AcstSub:
                                AcstParentPage.UpdateAcstSubInfo(localFunction);
                                AcstSubPage.UpdateStatus(localFunction);
                                break;
                            //case SPK.WaterHeaterJinmao:
                            //    AcstParentPage.UpdateAcstSubInfo(localFunction);
                            //    WaterHeaterJinmaoPage.UpdateStatus();
                            //    break;
                            //case SPK.InverterJinmao:
                            //    InverterJinmaoPage.UpdateStatus(localFunction);
                            //    break;
                            case SPK.AirSwitch:
                                AirSwitchPage.UpdataState(localFunction);
                                if(localFunction.GetAttribute(FunctionAttributeKey.Power)!=null)//如果是带电量的空开也要更新能源界面
                                if (localFunction.GetAttribute(FunctionAttributeKey.Power) != null)//如果是带电量的空开也要更新能源界面
                                {
                                    EnergyMainPage.UpdataStatus(localFunction);
                                }
                                break;
                            case SPK.AirSwitchP3:
                                AirSwitchP3Page.UpdataState(localFunction);
                                AirSwitchP3SubloopEnergyPage.UpdataStatus(localFunction);
                                break;
                            case SPK.ElectricEnergy:
                                EnergyMainPage.UpdataStatus(localFunction);
@@ -1288,7 +1467,7 @@
                                CurtainModulePage.UpdataState(localFunction);
                                break;
                            case SPK.CurtainDream:
                                if(localFunction.GetAttrState(FunctionAttributeKey.Percent) == "0")
                                if (localFunction.GetAttrState(FunctionAttributeKey.Percent) == "0")
                                {
                                    localFunction.SetAttrState(FunctionAttributeKey.OnOff, "off");
                                }
@@ -1309,6 +1488,7 @@
                                break;
                            case SPK.AcStandard:
                            case SPK.HvacAC:
                            case SPK.HvacAcPanel:
                            case SPK.AcIr:
                                Stan.HdlDeviceStatuPushLogic.Current.UpdateDeviceStatu(updateTemp.sid, updateTemp.status);
                                if (localFunction != null)
@@ -1352,6 +1532,7 @@
                                }
                                break;
                            case SPK.HvacFloorHeat:
                            case SPK.HvacFloorHeatPanel:
                            case SPK.FloorHeatStandard:
                                localFunction.lastState = "";
                                switch (localFunction.GetAttrState(FunctionAttributeKey.Mode))
@@ -1376,12 +1557,14 @@
                                FloorHeatingPage.UpdataStates(localFunction);
                                break;
                            case SPK.SensorPm25:
                            case SPK.SensorPm10:
                            case SPK.SensorCO2:
                            case SPK.SensorTVOC:
                            case SPK.SensorTemperature:
                            case SPK.SensorHumidity:
                            case SPK.SensorHcho:
                                if(localFunction.spk == SPK.SensorTemperature)
                            case SPK.SensorLight:
                                if (localFunction.spk == SPK.SensorTemperature)
                                {
                                    HomePage.LoadEvent_RefreshEnvirIndoorTemp();
                                }
@@ -1393,6 +1576,7 @@
                                //A_EnvironmentalDataCenter.LoadEvent_UpdataStatus(localFunction);
                                break;
                            case SPK.SensorEnvironment:
                            case SPK.SensorEnvironmentHailin:
                            case SPK.SensorEnvironment2:
                            case SPK.SensorEnvironment3:
                                if (localFunction.GetAttributes().Contains(FunctionAttributeKey.Temperature))
@@ -1421,7 +1605,6 @@
                            case SPK.ElectricTuyaWeepRobot2:
                            case SPK.ElectricTuyaWaterValve:
                            case SPK.ElectricTuyaWaterValve2:
                            case SPK.SensorPir:
                            case SPK.SensorDoorWindow:
                            case SPK.SensorSmoke:
                            case SPK.SensorWater:
@@ -1429,10 +1612,27 @@
                            case SPK.AirFreshStandard:
                            case SPK.HvacAirFresh:
                            case SPK.SensorGas:
                            case SPK.HvacCac:
                            case SPK.SensorHelp:
                            case SPK.MechanicalArm:
                                //设备状态推送
                                //状态更新
                                Stan.HdlDeviceStatuPushLogic.Current.UpdateDeviceStatu(updateTemp.sid, updateTemp.status);
                                break;
                            case SPK.SensorPir:
                            case SPK.SensorPirHold:
                                var tempPirStatus = localFunction.attributes.Find((sta) => sta.key == "people_status");
                                if (tempPirStatus != null)
                                {
                                    if (tempPirStatus.state == "true")
                                    {
                                        localFunction.lastState = Language.StringByID(StringId.Someone);
                                    }
                                    else
                                    {
                                        localFunction.lastState = Language.StringByID(StringId.wuren);
                                    }
                                }
                                Stan.HdlDeviceStatuPushLogic.Current.UpdateDeviceStatu(updateTemp.sid, updateTemp.status);
                                break;
                            case SPK.SenesorMegahealth:
@@ -1446,7 +1646,7 @@
                                    switch (tempStatus.state)
                                    {//0空,1走,2跑,3坐,4跌倒,5站
                                        case "0":
                                            localFunction.lastState = Language.StringByID(StringId.SensorNormalState);
                                            localFunction.lastState = Language.StringByID(StringId.wuren);
                                            break;
                                        case "1":
                                            localFunction.lastState = Language.StringByID(StringId.SomeoneIn);
@@ -1482,10 +1682,30 @@
                            case SPK.AvMusic:
                            case SPK.MusicStandard:
                                //UI.Music.MusicMain.mMusicMain.RefreshView(updateTemp);
                                //Console.WriteLine("音乐播放器显示状态======="+ revString);
                                Console.WriteLine("音乐播放器显示状态=======" + revString);
                                foreach (var music in UI.Music.A31MusicModel.A31MusicModelList)//每次收到数据都要更新一下时间
                                {
                                    if (music.functionMusic.sid == localFunction.sid)
                                    {
                                        music.LastDateTime = DateTime.Now;
                                    }
                                }
                                if (UI.Music.A31MusicModel.Current != null)
                                {
                                    UI.Music.A31MusicModel.Current.LastDateTime = DateTime.Now;
                                }
                                //wjc
                                break;
                            //case SPK.Inverter:
                            //case SPK.InverterRst:
                            //    var status = new Dictionary<string, object> { ["method"] = "status", ["data"] = temp.objects };
                            //    Application.RunOnMainThread(() =>
                            //    {
                            //        Inverter.Ins.H5Page.CallJS($"nativeToJs(\'{JsonConvert.SerializeObject(status)}\')");
                            //    });
                            //    break;
                        }
                        HomePage.UpdataFunctionStates(localFunction);
                        RoomPage.UpdataStates(localFunction);
@@ -1508,13 +1728,13 @@
        /// <summary>
        /// //一键(远程)开锁
        /// </summary>
        public void OneKeyUnlocking(Function doorlock,string extStr)
        public void OneKeyUnlocking(Function doorlock, string extStr)
        {
            if (Ins.GatewayOnline_Local)
            {
                Dictionary<string, string> dic = new Dictionary<string, string>();
                var functionControlDataObj = doorlock.GetGatewayAlinkDoorlockData(UserInfo.Current.ID,extStr);
                var functionControlDataJson = Newtonsoft.Json.JsonConvert.SerializeObject(functionControlDataObj);
                var functionControlDataObj = doorlock.GetGatewayAlinkDoorlockData(UserInfo.Current.ID, extStr);
                var functionControlDataJson = JsonConvert.SerializeObject(functionControlDataObj);
                var sendBytes = Ins.ConvertSendBodyData($"/base/{Control.Ins.GatewayId}/thing/service/doorRemoteOpen/down", functionControlDataJson);
                new Control_Udp().SendLocalHdlLinkData(sendBytes, functionControlDataObj.id, 0);
            }
@@ -1528,7 +1748,7 @@
        /// </summary>
        /// <param name="functionId"></param>
        /// <param name="pwd"></param>
        public void ConfirmUnlocking(string functionId,string pwd)
        public void ConfirmUnlocking(string functionId, string pwd)
        {
            Loading loading = new Loading();
            MainPage.BaseView.AddChidren(loading);
@@ -1547,7 +1767,7 @@
                    var pack = HttpUtil.RequestHttpsPost("/home-wisdom/app/device/door/pwdConfirm", requestJson);
                    if (pack.Code == StateCode.SUCCESS)
                    {
                        Newtonsoft.Json.Linq.JObject pairs = Newtonsoft.Json.Linq.JObject.Parse(pack.Data.ToString());
                        JObject pairs = JObject.Parse(pack.Data.ToString());
                        var scrip = pairs.GetValue("scrip");
                        d = new Dictionary<string, object>();
@@ -1564,8 +1784,10 @@
                        //{
                        //    return false;
                        //}
                        if (pack.Code != StateCode.SUCCESS) {
                            Application.RunOnMainThread(() => {
                        if (pack.Code != StateCode.SUCCESS)
                        {
                            Application.RunOnMainThread(() =>
                            {
                                new PublicAssmebly().TipMsg(Language.StringByID(StringId.Tip), pack.message);
                                UserInfo.Current.doorPasswordString = "";//
                                UserInfo.Current.LastTimeOpenDoor = DateTime.MinValue;
@@ -1574,8 +1796,9 @@
                    }
                    if (pack.Code != StateCode.SUCCESS)
                    {
                        Application.RunOnMainThread(() => {
                            if(string.IsNullOrEmpty(pack.message))
                        Application.RunOnMainThread(() =>
                        {
                            if (string.IsNullOrEmpty(pack.message))
                            {
                                new PublicAssmebly().TipMsg(Language.StringByID(StringId.Tip),
                                    Language.StringByID(StringId.OperationFailed));