HDL Home App 第二版本 旧平台金堂用 正在使用
chenqiyang
2022-06-22 dc0309e64f02227d8e1468b7326c07955f804612
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlDevicePanelLogic.cs
old mode 100755 new mode 100644
@@ -1,943 +1,984 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZigBee.Device;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 干接点的逻辑
    /// </summary>
    public class HdlDevicePanelLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 干接点的逻辑
using System;
using System.Collections.Generic;
using System.Text;
using ZigBee.Device;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 干接点的逻辑
    /// </summary>
    public class HdlDevicePanelLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 干接点的逻辑
        /// </summary>
        private static HdlDevicePanelLogic m_Current = null;
        /// <summary>
        /// 干接点的逻辑
        /// <summary>
        /// 干接点的逻辑
        /// </summary>
        public static HdlDevicePanelLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlDevicePanelLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 干接点的私有属性  keys:设备主键,value:各级别的值
        /// </summary>
        private Dictionary<string, DryContactFunctionInfo> dicDryContactFunction = new Dictionary<string, DryContactFunctionInfo>();
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 初始化
        /// </summary>
        public HdlDevicePanelLogic()
        {
            //从本地文件还原干接点的私有属性
            this.LoadDryContactFunctionFromLocaltion();
        }
        #endregion
        #region ■ 颜色调节___________________________
        /// <summary>
        /// 获取按键面板指定端点的【指示灯开关颜色】的信息(出错会返回null)
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <returns></returns>
        public Panel.KeyColorData GetPanelEpointColorInfo(CommonDevice panel)
        {
            Panel.KeyNum keyNum = (Panel.KeyNum)panel.DeviceEpoint;
            var result = this.GetPanelColorInfoAsync(panel, keyNum);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.keyColorData == null)
            {
                //获取按键面板颜色调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelColorRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.keyColorData;
        }
        /// <summary>
        /// 获取面板颜色的信息(出错会返回null)
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <returns></returns>
        public Panel.KeyColorData GetPanelColorInfo(CommonDevice panel)
        {
            panel.DeviceEpoint = 1;
            Panel.KeyNum keyNum = (Panel.KeyNum)panel.DeviceEpoint;
            var result = this.GetPanelColorInfoAsync(panel, keyNum);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.keyColorData == null)
            {
                //获取按键面板颜色调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelColorRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.keyColorData;
        }
        ///<summary >
        ///获取按键指示灯开关颜色.
        /// </summary>
        public Panel.KeyColorDataResponseAllData GetPanelColorInfoAsync(CommonDevice device, Panel.KeyNum keyNum)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.GetPanelColorInfo(device, keyNum);
            }
            //发送数据 keyNum转为16进制 范围:01~10
            var passData = "0504040101" + Convert.ToString((int)keyNum, 16).ToUpper().PadLeft(2, '0');
            var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var dataObject = new JObject { { "PassData", passData } };
            jObject.Add("Data", dataObject);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, jObject.ToString(), "0405", 24, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                return null;
            }
            string data = result.ReceiptData;
            var tempR = new Panel.KeyColorData();
            tempR.OpenColorR = data[12].ToString() + data[13].ToString();
            tempR.OpenColorG = data[14].ToString() + data[15].ToString();
            tempR.OpenColorB = data[16].ToString() + data[17].ToString();
            tempR.CloseColorR = data[18].ToString() + data[19].ToString();
            tempR.CloseColorG = data[20].ToString() + data[21].ToString();
            tempR.CloseColorB = data[22].ToString() + data[23].ToString();
            var key = data[10].ToString() + data[11].ToString();
            int keyEnum1 = Convert.ToInt32(key, 16);
            tempR.keyNum = (Panel.KeyNum)keyEnum1;
            return new Panel.KeyColorDataResponseAllData { keyColorData = tempR };
        }
        /// <summary>
        /// 设置按键面板指定端点的【指示灯开关颜色】的信息
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <param name="colorData">开和关的颜色都需要一起设置</param>
        /// <returns></returns>
        public bool SetPanelEpointColorInfo(CommonDevice panel, Panel.KeyColorData colorData)
        {
            var keyNum = new Panel.KeyNumStatus();
            Type type = keyNum.GetType();
            type.InvokeMember("Key" + panel.DeviceEpoint, System.Reflection.BindingFlags.SetField, null, keyNum, new object[] { true });
            var result = this.SetPanelColorInfoAsync(panel, colorData, keyNum);
            if (result == null || result.responseData == null)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.responseData.status != 0)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 设置面板颜色
        /// </summary>
        /// <param name="panel">按键面板的</param>
        /// <param name="colorData">只设置开的颜色</param>
        /// <returns></returns>
        public bool SetPanelColorInfo(CommonDevice panel, Panel.KeyColorData colorData)
        {
            var keyNum = new Panel.KeyNumStatus();
            //默认第一个用面板第一个按键颜色作为整个面板的颜色
            keyNum.Key1 = true;
            var result = this.SetPanelColorInfoAsync(panel, colorData, keyNum);
            if (result == null || result.responseData == null)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.responseData.status != 0)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        ///<summary >
        ///配置按键指示灯颜色
        /// </summary>
        public CommonDevice.ResponseAllData SetPanelColorInfoAsync(CommonDevice device, Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.SetPanelColorInfo(device, keyColorData, keyNumStatus, "ZbDataPassthrough");
            }
            //获取配置按键指示灯颜色的命令字符
            var sendData = this.GetPanelColorCommandText(device.DeviceAddr, keyColorData, keyNumStatus);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                return null;
            }
            var data = result.ReceiptData;
            var tempD = new CommonDevice.ResponseData();
            tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
            tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
            return new CommonDevice.ResponseAllData { responseData = tempD };
        }
        /// <summary>
        /// 获取配置按键指示灯颜色的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="keyColorData"></param>
        /// <param name="keyNumStatus"></param>
        /// <returns></returns>
        public string GetPanelColorCommandText(string DeviceAddr, Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            var passData = this.GetPanelColorPassData(keyColorData, keyNumStatus);
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 配置按键指示灯颜色数据
        /// <para>发配置按键指示灯颜色命令时,此时为发送到网关的透传数据</para>
        /// </summary>
        /// <returns>The passthorugh data.</returns>
        /// <param name="keyColorData">Key color data.</param>
        /// <param name="keyNum">Key number.</param>
        private string GetPanelColorPassData(Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            string data = "";
            string dataLength = "0c";
            string dataComand1 = "01";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "08";
            int attributeData = 0;
            try
            {
                for (int i = 1; i <= 16; i++)
                {
                    Type type = keyNumStatus.GetType();
                    var obj = type.InvokeMember("Key" + i, System.Reflection.BindingFlags.GetField, null, keyNumStatus, null);
                    int value0 = 0;
                    if (Convert.ToBoolean(obj) == true)
                    {
                        value0 = 1;
                    }
                    int v = (int)Math.Pow(2, i - 1);
                    attributeData += value0 * v;
                }
                string td = attributeData.ToString("X4");
                char[] td1 = td.ToCharArray();
                string tempAttributeData = string.Concat(td1[2].ToString(), td1[3].ToString(), td1[0].ToString(), td1[1].ToString());
                string temp = "";
                var tempColor1 = keyColorData.OpenColorR.ToString();
                var sbString1 = new System.Text.StringBuilder();
                switch (tempColor1.Length)
                {
                    case 1:
                        temp = "0" + tempColor1;
                        break;
                    case 2:
                        temp = tempColor1;
                        break;
                }
                sbString1.Append(temp.ToUpper());
                var tempColor2 = keyColorData.OpenColorG.ToString();
                var sbString2 = new System.Text.StringBuilder();
                switch (tempColor2.Length)
                {
                    case 1:
                        temp = "0" + tempColor2;
                        break;
                    case 2:
                        temp = tempColor2;
                        break;
                }
                sbString2.Append(temp.ToUpper());
                var tempColor3 = keyColorData.OpenColorB.ToString();
                var sbString3 = new System.Text.StringBuilder();
                switch (tempColor3.Length)
                {
                    case 1:
                        temp = "0" + tempColor3;
                        break;
                    case 2:
                        temp = tempColor3;
                        break;
                }
                sbString3.Append(temp.ToUpper());
                var tempColor4 = keyColorData.CloseColorR.ToString();
                var sbString4 = new System.Text.StringBuilder();
                switch (tempColor3.Length)
                {
                    case 1:
                        temp = "0" + tempColor4;
                        break;
                    case 2:
                        temp = tempColor4;
                        break;
                }
                sbString4.Append(temp.ToUpper());
                var tempColor5 = keyColorData.CloseColorG.ToString();
                var sbString5 = new System.Text.StringBuilder();
                switch (tempColor5.Length)
                {
                    case 1:
                        temp = "0" + tempColor5;
                        break;
                    case 2:
                        temp = tempColor5;
                        break;
                }
                sbString5.Append(temp.ToUpper());
                var tempColor6 = keyColorData.CloseColorB.ToString();
                var sbString6 = new System.Text.StringBuilder();
                switch (tempColor6.Length)
                {
                    case 1:
                        temp = "0" + tempColor6;
                        break;
                    case 2:
                        temp = tempColor6;
                        break;
                }
                sbString6.Append(temp.ToUpper());
                if (keyColorData != null)
                {
                    data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                           tempAttributeData + sbString1 + sbString2 + sbString3 +
                           sbString4 + sbString5 + sbString6;
                }
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 亮度调节___________________________
        ///<summary >
        ///获取设备亮度配置(ui叫亮度调节,使用返回值的panelDirectionsLevel)
        /// </summary>
        public Panel.PanelSwitchLevelInfo GetDeviceLightSettion(CommonDevice device)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.GetDeviceLightSettion(device);
            }
            //获取发送的命令字符
            var passData = "050604010101";
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            var sendData = jObject.ToString();
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0407", 14, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //获取按键面板亮度调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelLightRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            var receiptData = result.ReceiptData;
            var level1 = Convert.ToInt32(receiptData[10].ToString() + receiptData[11].ToString(), 16);
            var level2 = Convert.ToInt32(receiptData[12].ToString() + receiptData[13].ToString(), 16);
            return new Panel.PanelSwitchLevelInfo { panelDirectionsLevel = level1, panelBacklightLevel = level2 };
        }
        /// <summary>
        /// 设置设备亮度(ui叫亮度调节)
        /// </summary>
        /// <param name="panel">设备对象</param>
        /// <param name="directionsLevel">0-100(这个是点击后的值)</param>
        /// <param name="backlightLevel">0-100(这个是点击前的值)</param>
        /// <returns></returns>
        public bool SetDeviceLightSettion(CommonDevice device, int directionsLevel, int backlightLevel)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.SetDeviceLightSettion(device, directionsLevel, backlightLevel, "ZbDataPassthrough");
            }
            //获取修改面板的亮度调节的命令字符
            var sendData = this.GetPanelLevelCommadText(device.DeviceAddr, directionsLevel, backlightLevel);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return false;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //设置亮度调节失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetLightRegulationFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            //这里还有一个 0402
            //tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
            var status = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            if (status != 0)
            {
                //设置亮度调节失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetLightRegulationFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //修改缓存
            ModelData.DeviceModelDataLogic.Current.SetDeviceLightSettion(device, directionsLevel, backlightLevel, "ZbDataPassthrough");
            return true;
        }
        /// <summary>
        /// 获取修改面板的亮度调节的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="directionsLevel">0-100(这个是点击后的值)</param>
        /// <param name="backlightLevel">0-100(这个是点击前的值)</param>
        /// <returns></returns>
        public string GetPanelLevelCommadText(string DeviceAddr, int directionsLevel, int backlightLevel)
        {
            var passData = this.GetSetPanelLevelPassData(directionsLevel, backlightLevel);
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 获取配置按键指示灯面板亮度的命令字符
        /// </summary>
        private string GetSetPanelLevelPassData(int level1, int level2)
        {
            string data = "";
            string dataLength = "06";
            string dataComand1 = "02";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "02";
            string l1 = "";
            string l2 = "";
            try
        public static HdlDevicePanelLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlDevicePanelLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 干接点的私有属性  keys:设备主键,value:各级别的值
        /// </summary>
        private Dictionary<string, DryContactFunctionInfo> dicDryContactFunction = new Dictionary<string, DryContactFunctionInfo>();
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 初始化
        /// </summary>
        public HdlDevicePanelLogic()
        {
            //从本地文件还原干接点的私有属性
            this.LoadDryContactFunctionFromLocaltion();
        }
        #endregion
        #region ■ 颜色调节___________________________
        /// <summary>
        /// 获取按键面板指定端点的【指示灯开关颜色】的信息(出错会返回null)
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <returns></returns>
        public Panel.KeyColorData GetPanelEpointColorInfo(CommonDevice panel)
        {
            Panel.KeyNum keyNum = (Panel.KeyNum)panel.DeviceEpoint;
            var result = this.GetPanelColorInfoAsync(panel, keyNum);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.keyColorData == null)
            {
                //获取按键面板颜色调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelColorRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.keyColorData;
        }
        /// <summary>
        /// 获取面板颜色的信息(出错会返回null)
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <returns></returns>
        public Panel.KeyColorData GetPanelColorInfo(CommonDevice panel)
        {
            panel.DeviceEpoint = 1;
            Panel.KeyNum keyNum = (Panel.KeyNum)panel.DeviceEpoint;
            var result = this.GetPanelColorInfoAsync(panel, keyNum);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.keyColorData == null)
            {
                //获取按键面板颜色调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelColorRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.keyColorData;
        }
        ///<summary >
        ///获取按键指示灯开关颜色.
        /// </summary>
        public Panel.KeyColorDataResponseAllData GetPanelColorInfoAsync(CommonDevice device, Panel.KeyNum keyNum)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                //这里特殊,这里是按回路分的
                return TemplateData.TemplateDeviceDataLogic.Current.GetPanelColorInfo(device.DeviceAddr, device.DeviceEpoint, keyNum);
            }
            //发送数据 keyNum转为16进制 范围:01~10
            var passData = "0504040101" + Convert.ToString((int)keyNum, 16).ToUpper().PadLeft(2, '0');
            var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var dataObject = new JObject { { "PassData", passData } };
            jObject.Add("Data", dataObject);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, jObject.ToString(), "0405", 24, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                return null;
            }
            string data = result.ReceiptData;
            var tempR = new Panel.KeyColorData();
            tempR.OpenColorR = data[12].ToString() + data[13].ToString();
            tempR.OpenColorG = data[14].ToString() + data[15].ToString();
            tempR.OpenColorB = data[16].ToString() + data[17].ToString();
            tempR.CloseColorR = data[18].ToString() + data[19].ToString();
            tempR.CloseColorG = data[20].ToString() + data[21].ToString();
            tempR.CloseColorB = data[22].ToString() + data[23].ToString();
            var key = data[10].ToString() + data[11].ToString();
            int keyEnum1 = Convert.ToInt32(key, 16);
            tempR.keyNum = (Panel.KeyNum)keyEnum1;
            return new Panel.KeyColorDataResponseAllData { keyColorData = tempR };
        }
        /// <summary>
        /// 设置按键面板指定端点的【指示灯开关颜色】的信息
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <param name="colorData">开和关的颜色都需要一起设置</param>
        /// <returns></returns>
        public bool SetPanelEpointColorInfo(CommonDevice panel, Panel.KeyColorData colorData)
        {
            var keyNum = new Panel.KeyNumStatus();
            Type type = keyNum.GetType();
            type.InvokeMember("Key" + panel.DeviceEpoint, System.Reflection.BindingFlags.SetField, null, keyNum, new object[] { true });
            var result = this.SetPanelColorInfoAsync(panel, colorData, keyNum);
            if (result == null || result.responseData == null)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.responseData.status != 0)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 设置面板颜色
        /// </summary>
        /// <param name="panel">按键面板的</param>
        /// <param name="colorData">只设置开的颜色</param>
        /// <returns></returns>
        public bool SetPanelColorInfo(CommonDevice panel, Panel.KeyColorData colorData)
        {
            var keyNum = new Panel.KeyNumStatus();
            //默认第一个用面板第一个按键颜色作为整个面板的颜色
            keyNum.Key1 = true;
            var result = this.SetPanelColorInfoAsync(panel, colorData, keyNum);
            if (result == null || result.responseData == null)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.responseData.status != 0)
            {
                //设置按键面板指示灯颜色失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetPanelPilolightSettionFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        ///<summary >
        ///配置按键指示灯颜色
        /// </summary>
        public CommonDevice.ResponseAllData SetPanelColorInfoAsync(CommonDevice device, Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                //这个也是特殊,按回路来分
                return TemplateData.TemplateDeviceDataLogic.Current.SetPanelColorInfo(device.DeviceAddr, device.DeviceEpoint, keyColorData, keyNumStatus, null);
            }
            //获取配置按键指示灯颜色的命令字符
            var sendData = this.GetPanelColorCommandText(device.DeviceAddr, keyColorData, keyNumStatus);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                return null;
            }
            var data = result.ReceiptData;
            var tempD = new CommonDevice.ResponseData();
            tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
            tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
            //添加缓存
            TemplateData.TemplateDeviceDataLogic.Current.SetPanelColorInfo(device.DeviceAddr, device.DeviceEpoint, keyColorData, keyNumStatus, result.JsonData[0]);
            return new CommonDevice.ResponseAllData { responseData = tempD };
        }
        /// <summary>
        /// 获取配置按键指示灯颜色的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="keyColorData"></param>
        /// <param name="keyNumStatus"></param>
        /// <returns></returns>
        public string GetPanelColorCommandText(string DeviceAddr, Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            var passData = this.GetPanelColorPassData(keyColorData, keyNumStatus);
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 配置按键指示灯颜色数据
        /// <para>发配置按键指示灯颜色命令时,此时为发送到网关的透传数据</para>
        /// </summary>
        /// <returns>The passthorugh data.</returns>
        /// <param name="keyColorData">Key color data.</param>
        /// <param name="keyNum">Key number.</param>
        private string GetPanelColorPassData(Panel.KeyColorData keyColorData, Panel.KeyNumStatus keyNumStatus)
        {
            string data = "";
            string dataLength = "0c";
            string dataComand1 = "01";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "08";
            int attributeData = 0;
            try
            {
                for (int i = 1; i <= 16; i++)
                {
                    Type type = keyNumStatus.GetType();
                    var obj = type.InvokeMember("Key" + i, System.Reflection.BindingFlags.GetField, null, keyNumStatus, null);
                    int value0 = 0;
                    if (Convert.ToBoolean(obj) == true)
                    {
                        value0 = 1;
                    }
                    int v = (int)Math.Pow(2, i - 1);
                    attributeData += value0 * v;
                }
                string td = attributeData.ToString("X4");
                char[] td1 = td.ToCharArray();
                string tempAttributeData = string.Concat(td1[2].ToString(), td1[3].ToString(), td1[0].ToString(), td1[1].ToString());
                string temp = "";
                var tempColor1 = keyColorData.OpenColorR.ToString();
                var sbString1 = new System.Text.StringBuilder();
                switch (tempColor1.Length)
                {
                    case 1:
                        temp = "0" + tempColor1;
                        break;
                    case 2:
                        temp = tempColor1;
                        break;
                }
                sbString1.Append(temp.ToUpper());
                var tempColor2 = keyColorData.OpenColorG.ToString();
                var sbString2 = new System.Text.StringBuilder();
                switch (tempColor2.Length)
                {
                    case 1:
                        temp = "0" + tempColor2;
                        break;
                    case 2:
                        temp = tempColor2;
                        break;
                }
                sbString2.Append(temp.ToUpper());
                var tempColor3 = keyColorData.OpenColorB.ToString();
                var sbString3 = new System.Text.StringBuilder();
                switch (tempColor3.Length)
                {
                    case 1:
                        temp = "0" + tempColor3;
                        break;
                    case 2:
                        temp = tempColor3;
                        break;
                }
                sbString3.Append(temp.ToUpper());
                var tempColor4 = keyColorData.CloseColorR.ToString();
                var sbString4 = new System.Text.StringBuilder();
                switch (tempColor3.Length)
                {
                    case 1:
                        temp = "0" + tempColor4;
                        break;
                    case 2:
                        temp = tempColor4;
                        break;
                }
                sbString4.Append(temp.ToUpper());
                var tempColor5 = keyColorData.CloseColorG.ToString();
                var sbString5 = new System.Text.StringBuilder();
                switch (tempColor5.Length)
                {
                    case 1:
                        temp = "0" + tempColor5;
                        break;
                    case 2:
                        temp = tempColor5;
                        break;
                }
                sbString5.Append(temp.ToUpper());
                var tempColor6 = keyColorData.CloseColorB.ToString();
                var sbString6 = new System.Text.StringBuilder();
                switch (tempColor6.Length)
                {
                    case 1:
                        temp = "0" + tempColor6;
                        break;
                    case 2:
                        temp = tempColor6;
                        break;
                }
                sbString6.Append(temp.ToUpper());
                if (keyColorData != null)
                {
                    data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                           tempAttributeData + sbString1 + sbString2 + sbString3 +
                           sbString4 + sbString5 + sbString6;
                }
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 亮度调节___________________________
        ///<summary >
        ///获取设备亮度配置(ui叫亮度调节,使用返回值的panelDirectionsLevel)
        /// </summary>
        public Panel.PanelSwitchLevelInfo GetDeviceLightSettion(CommonDevice device)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.GetDeviceLightSettion(device.DeviceAddr, 200);
            }
            //获取发送的命令字符
            var passData = "050604010101";
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            var sendData = jObject.ToString();
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0407", 14, 9);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //获取按键面板亮度调节信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelLightRegulationInfoFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            var receiptData = result.ReceiptData;
            var level1 = Convert.ToInt32(receiptData[10].ToString() + receiptData[11].ToString(), 16);
            var level2 = Convert.ToInt32(receiptData[12].ToString() + receiptData[13].ToString(), 16);
            return new Panel.PanelSwitchLevelInfo { panelDirectionsLevel = level1, panelBacklightLevel = level2 };
        }
        /// <summary>
        /// 设置设备亮度(ui叫亮度调节)
        /// </summary>
        /// <param name="panel">设备对象</param>
        /// <param name="directionsLevel">0-100(这个是点击后的值)</param>
        /// <param name="backlightLevel">0-100(这个是点击前的值)</param>
        /// <returns></returns>
        public bool SetDeviceLightSettion(CommonDevice device, int directionsLevel, int backlightLevel)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.SetDeviceLightSettion(device.DeviceAddr, 200, directionsLevel, backlightLevel, null);
            }
            //获取修改面板的亮度调节的命令字符
            var sendData = this.GetPanelLevelCommadText(device.DeviceAddr, directionsLevel, backlightLevel);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return false;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //设置亮度调节失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetLightRegulationFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            //这里还有一个 0402
            //tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
            var status = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            if (status != 0)
            {
                //设置亮度调节失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetLightRegulationFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //修改缓存
            TemplateData.TemplateDeviceDataLogic.Current.SetDeviceLightSettion(device.DeviceAddr, 200, directionsLevel, backlightLevel, result.JsonData[0]);
            return true;
        }
        /// <summary>
        /// 获取修改面板的亮度调节的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="directionsLevel">0-100(这个是点击后的值)</param>
        /// <param name="backlightLevel">0-100(这个是点击前的值)</param>
        /// <returns></returns>
        public string GetPanelLevelCommadText(string DeviceAddr, int directionsLevel, int backlightLevel)
        {
            var passData = this.GetSetPanelLevelPassData(directionsLevel, backlightLevel);
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 获取配置按键指示灯面板亮度的命令字符
        /// </summary>
        private string GetSetPanelLevelPassData(int level1, int level2)
        {
            string data = "";
            string dataLength = "06";
            string dataComand1 = "02";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "02";
            string l1 = "";
            string l2 = "";
            try
            {
                var sbString1 = new System.Text.StringBuilder();
                var sbString2 = new System.Text.StringBuilder();
                string temp1 = Convert.ToString(level1, 16);
                string temp2 = Convert.ToString(level2, 16);
                switch (temp1.Length)
                {
                    case 1:
                        l1 = "0" + temp1;
                        break;
                    case 2:
                        l1 = temp1;
                        break;
                }
                switch (temp2.Length)
                {
                    case 1:
                        l2 = "0" + temp2;
                        break;
                    case 2:
                        l2 = temp2;
                        break;
                }
                sbString1.Append(l1.ToString().ToUpper());
                sbString2.Append(l2.ToString().ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                    sbString1 + sbString2;
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 接近感应___________________________
        /// <summary>
        /// 获取接近感应配置(ui叫接近感应,使用返回值的panelProximitySensorInfo)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public async Task<Panel.PanelProximitySensorInfo> GetDeviceProximitySensorsSettion(CommonDevice device)
        {
            //借用它的函数
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = device.DeviceEpoint;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = await panel.GetProximitySensorAsync();
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.panelProximitySensorInfo == null || string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                //获取接近感应信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.GetPanelProximityFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.panelProximitySensorInfo;
        }
        /// <summary>
        /// 配置接近传感
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <para>sensorEnable:传感器使能</para>
        /// <returns></returns>
        public async Task<bool> SetProximitySensorStatus(CommonDevice device, bool sensorEnable)
        {
            //借用它的函数
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = device.DeviceEpoint;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = await panel.SetProximitySensor(sensorEnable);
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return false;
            }
            if (result == null || result.responseData == null)
            {
                //接近传感配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.SetPannelProximityFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 节能模式___________________________
        /// <summary>
        /// 获取设备节能模式的配置状态(ui叫节能模式)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public Panel.PanelSaveEnergyModeInfo GetDeviceEnergyConservationMode(CommonDevice device)
        {
            //如果当前住宅是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.GetDeviceEnergyConservationMode(device);
            }
            //发送命令
            string passData = "050804010101";
            var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            //16:旧版本 18:新版本
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, jObject.ToString(), "0409", 16, 9, new List<int> { 18 });
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return null;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //获取按键面板节能模式信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelEnergyConservationInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            var energyInfo = new Panel.PanelSaveEnergyModeInfo();
            if (result.ReceiptData[10].ToString() + result.ReceiptData[11].ToString() == "01")
            {
                energyInfo.enable = true;
            }
            else
            {
                energyInfo.enable = false;
            }
            //新版本:07 0904 11 04 01 3C00 32
            if (result.ReceiptData.Length == 18)
            {
                energyInfo.time = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString() +
                    result.ReceiptData[12].ToString() + result.ReceiptData[13].ToString(), 16);
                string temp1 = Convert.ToString(level1, 16);
                string temp2 = Convert.ToString(level2, 16);
                switch (temp1.Length)
                {
                    case 1:
                        l1 = "0" + temp1;
                        break;
                    case 2:
                        l1 = temp1;
                        break;
                }
                switch (temp2.Length)
                {
                    case 1:
                        l2 = "0" + temp2;
                        break;
                    case 2:
                        l2 = temp2;
                        break;
                }
                sbString1.Append(l1.ToString().ToUpper());
                sbString2.Append(l2.ToString().ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                    sbString1 + sbString2;
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 接近感应___________________________
        /// <summary>
        /// 获取接近感应配置(ui叫接近感应,使用返回值的panelProximitySensorInfo)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public async Task<Panel.PanelProximitySensorInfo> GetDeviceProximitySensorsSettion(CommonDevice device)
        {
            //借用它的函数
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = device.DeviceEpoint;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = await panel.GetProximitySensorAsync();
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.panelProximitySensorInfo == null || string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                //获取接近感应信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.GetPanelProximityFail);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.panelProximitySensorInfo;
        }
        /// <summary>
        /// 配置接近传感
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <para>sensorEnable:传感器使能</para>
        /// <returns></returns>
        public async Task<bool> SetProximitySensorStatus(CommonDevice device, bool sensorEnable)
        {
            //借用它的函数
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = device.DeviceEpoint;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = await panel.SetProximitySensor(sensorEnable);
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return false;
            }
            if (result == null || result.responseData == null)
            {
                //接近传感配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.SetPannelProximityFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 校正温度___________________________
        /// <summary>
        /// 校正温度
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="correctValue">校正温度值</param>
        /// <param name="direction">补偿方向0不补偿 1:正向;2:反向</param>
        /// <param name="type">0 温度  ;1 湿度</param>
        /// <returns></returns>
        public async Task<bool> CorrectTemperature(CommonDevice device, double correctValue, int direction = 0, int type = 0)
        {
            //借用它的函t
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = 200;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = await panel.CorrectTemperature(correctValue, direction, type);
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return false;
            }
            if (result == null || result.responseData == null)
            {
                //矫正温度失败
                string msg = Language.StringByID(R.MyInternationalizationString.DataCorrectionFailed);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 节能模式___________________________
        /// <summary>
        /// 获取设备节能模式的配置状态(ui叫节能模式)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <returns></returns>
        public Panel.PanelSaveEnergyModeInfo GetDeviceEnergyConservationMode(CommonDevice device)
        {
            //如果当前住宅是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.GetDeviceEnergyConservationMode(device.DeviceAddr, 200);
            }
            //发送命令
            string passData = "050804010101";
            var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            //16:旧版本 18:新版本
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, jObject.ToString(), "0409", 16, 9, new List<int> { 18 });
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return null;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //获取按键面板节能模式信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelEnergyConservationInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            var energyInfo = new Panel.PanelSaveEnergyModeInfo();
            if (result.ReceiptData[10].ToString() + result.ReceiptData[11].ToString() == "01")
            {
                energyInfo.enable = true;
            }
            else
            {
                energyInfo.enable = false;
            }
            //新版本:07 0904 11 04 01 3C00 32
            if (result.ReceiptData.Length == 18)
            {
                energyInfo.time = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString() +
                    result.ReceiptData[12].ToString() + result.ReceiptData[13].ToString(), 16);
                energyInfo.level = Convert.ToInt32(result.ReceiptData[16].ToString() + result.ReceiptData[17].ToString(), 16);
            }
            //旧版本:07 0904 11 03 01 3C 32
            else
            {
                energyInfo.time = Convert.ToInt32(result.ReceiptData[12].ToString() + result.ReceiptData[13].ToString(), 16);
                energyInfo.level = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            }
            return energyInfo;
        }
        /// <summary>
        /// 设置设备的节能模式(ui叫节能模式)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="modeEnable">节能模式是否有效</param>
        /// <param name="modeTime">无操作进入节能模式时间 0-255</param>
        /// <param name="level">节能模式亮度:0-100</param>
        /// <returns></returns>
        public bool SetDeviceEnergyConservationMode(CommonDevice device, bool modeEnable, int modeTime, int level)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.SetDeviceEnergyConservationMode(device, modeEnable, modeTime, level, "ZbDataPassthrough");
            }
            //获取设置设备的节能模式的命令字符
            var sendData = this.GetDeviceEnergyConservationModeCommandText(device.DeviceAddr, modeEnable, modeTime, level);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return false;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //节能模式配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetEnergyConservationFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            var status = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            if (status != 0)
            {
                //节能模式配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetEnergyConservationFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //修改缓存
            ModelData.DeviceModelDataLogic.Current.SetDeviceEnergyConservationMode(device, modeEnable, modeTime, level, "ZbDataPassthrough");
            return true;
        }
        /// <summary>
        /// 获取设置设备的节能模式的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="modeEnable"></param>
        /// <param name="modeTime"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public string GetDeviceEnergyConservationModeCommandText(string DeviceAddr, bool modeEnable, int modeTime, int level)
        {
            var passData = this.GetPanelModeModePassData(modeEnable, modeTime, level);
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 获取设置设备的节能模式的命令字符
        /// </summary>
        private string GetPanelModeModePassData(bool modeEnable, int modeTime, int modelevel)
        {
            string data = "";
            string dataLength = "08";
            string dataComand1 = "03";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "04";
            string mode = "";
            string time = "";
            string level = "";
            try
            }
            //旧版本:07 0904 11 03 01 3C 32
            else
            {
                energyInfo.time = Convert.ToInt32(result.ReceiptData[12].ToString() + result.ReceiptData[13].ToString(), 16);
                energyInfo.level = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            }
            return energyInfo;
        }
        /// <summary>
        /// 设置设备的节能模式(ui叫节能模式)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="modeEnable">节能模式是否有效</param>
        /// <param name="modeTime">无操作进入节能模式时间 0-255</param>
        /// <param name="level">节能模式亮度:0-100</param>
        /// <returns></returns>
        public bool SetDeviceEnergyConservationMode(CommonDevice device, bool modeEnable, int modeTime, int level)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.SetDeviceEnergyConservationMode(device.DeviceAddr, 200, modeEnable, modeTime, level, null);
            }
            //获取设置设备的节能模式的命令字符
            var sendData = this.GetDeviceEnergyConservationModeCommandText(device.DeviceAddr, modeEnable, modeTime, level);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 9);
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return false;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //节能模式配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetEnergyConservationFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            var status = Convert.ToInt32(result.ReceiptData[14].ToString() + result.ReceiptData[15].ToString(), 16);
            if (status != 0)
            {
                //节能模式配置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetEnergyConservationFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //修改缓存
            TemplateData.TemplateDeviceDataLogic.Current.SetDeviceEnergyConservationMode(device.DeviceAddr, 200, modeEnable, modeTime, level, result.JsonData[0]);
            return true;
        }
        /// <summary>
        /// 获取设置设备的节能模式的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="modeEnable"></param>
        /// <param name="modeTime"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public string GetDeviceEnergyConservationModeCommandText(string DeviceAddr, bool modeEnable, int modeTime, int level)
        {
            var passData = this.GetPanelModeModePassData(modeEnable, modeTime, level);
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 获取设置设备的节能模式的命令字符
        /// </summary>
        private string GetPanelModeModePassData(bool modeEnable, int modeTime, int modelevel)
        {
            string data = "";
            string dataLength = "08";
            string dataComand1 = "03";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "04";
            string mode = "";
            string time = "";
            string level = "";
            try
            {
                if (modeEnable)
                {
                    mode = "01";
                }
                else
                {
                    mode = "00";
                }
                if (modeTime == -1)
                {
                    //当节能模式没有给时间,默认给60秒
                    modeTime = 60;
                }
                var tempBytes = new byte[2];
                for (int i = 0; i < 2; i++)
                {
                    tempBytes[i] = (byte)(modeTime >> (i * 8) & 0xff);
                }
                var time1 = Convert.ToString(tempBytes[0], 16);
                var time2 = Convert.ToString(tempBytes[1], 16);
                if (time1.Length == 1)
                {
                    time1 = "0" + time1;
                }
                if (time2.Length == 1)
                {
                    time2 = "0" + time2;
                }
                time = (time1 + time2).ToUpper();
                var sbString2 = new System.Text.StringBuilder();
                string temp2 = Convert.ToString(modelevel, 16);
                switch (temp2.Length)
                {
                    case 1:
                    mode = "01";
                }
                else
                {
                    mode = "00";
                }
                if (modeTime == -1)
                {
                    //当节能模式没有给时间,默认给60秒
                    modeTime = 60;
                }
                var tempBytes = new byte[2];
                for (int i = 0; i < 2; i++)
                {
                    tempBytes[i] = (byte)(modeTime >> (i * 8) & 0xff);
                }
                var time1 = Convert.ToString(tempBytes[0], 16);
                var time2 = Convert.ToString(tempBytes[1], 16);
                if (time1.Length == 1)
                {
                    time1 = "0" + time1;
                }
                if (time2.Length == 1)
                {
                    time2 = "0" + time2;
                }
                time = (time1 + time2).ToUpper();
                var sbString2 = new System.Text.StringBuilder();
                string temp2 = Convert.ToString(modelevel, 16);
                switch (temp2.Length)
                {
                    case 1:
                        level = "0" + temp2;
                        break;
                    case 2:
                        level = temp2;
                        break;
                }
                sbString2.Append(level.ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   mode + time + sbString2;
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 获取干接点配置信息_________________
        /// <summary>
        /// 获取干接点配置信息
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <returns></returns>
        public async Task<List<CommonDevice.AttributeDataObj>> GetDryContactConfigureInfo(CommonDevice device)
        {
            //借用它的函数
            var panel = new Panel();
            panel.DeviceAddr = device.DeviceAddr;
            panel.DeviceEpoint = device.DeviceEpoint;
            panel.CurrentGateWayId = device.CurrentGateWayId;
            var result = HdlDeviceBindLogic.Current.ReadPanelConfigureInfoAsync(panel);
            panel = null;
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.deviceStatusReportData == null)
            {
                //获取设备配置信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetDeviceConfigureInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            //如果不是6的话,这个数据是不对的
            if (result.deviceStatusReportData.CluterID != 6)
            {
                return new List<CommonDevice.AttributeDataObj>();
            }
            return result.deviceStatusReportData.AttriBute;
        }
        #endregion
        #region ■ 获取干接点功能系___________________
        /// <summary>
        /// <para>获取干接点功能系(异常时返回null,或者它没有指定功能,也会返回null)</para>
        /// <para>第一级别(参数全部省略时):</para>
        /// <para> 1024:灯类|256:按键类|768:PIR类</para>
        /// <para>第二级别:</para>
        /// <para> 1:特殊功能|100:Switch,开关(按键类)</para>
        /// <para> 200:Dimmer,调光(按键类)|300:Curtain,窗帘(按键类)</para>
        /// <para> 0:EnergySavingMode,节能模式(灯类)|1:SleepMode,睡眠模式(灯类)</para>
        /// <para> 100:WhiteBalance,白平衡(灯类)|101:RGBColor,RGB指示灯颜色(灯类)</para>
        /// <para> 102:RGBLevel,RGB指示灯亮度(灯类)</para>
        /// <para>第三级别:</para>
        /// <para>1:场景触发|65535:禁止发送功能</para>
        /// <para>100:SwitchOpen,开关开(按键类)|101:SwitchClose,开关关(按键类)</para>
        /// <para>102:SwitchChange,开关切换(按键类)|200:DimmerStepUp,增大调光(按键类)</para>
        /// <para>201:DimmerStepDown,降低调光(按键类)|202:DimmerStepChange,调光切换(按键类)</para>
        /// <para>300:CurtainOpen,窗帘开(按键类)|301:CurtainClose,窗帘关(按键类)</para>
        /// <para>302:CurtainStop,窗帘停|303:CurtainUpStop,窗帘上升停</para>
        /// <para>304:CurtainDownstop,窗帘下降停</para>
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <param name="level1">请参照第一级别的参数,省略时返回第一级别列表,设置时返回第二级别列表</param>
        /// <param name="level2">请参照第二级别的参数,省略时返回第二级别列表,设置时返回第三级别列表</param>
        /// <param name="reLevel3">重新获取第三级别的数据</param>
        /// <returns></returns>
        public async Task<List<int>> GetDryContactFunction(Panel panel, int level1 = -1, int level2 = -1, bool reLevel3 = false)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                //创建对象
                dicDryContactFunction[mainkeys] = new DryContactFunctionInfo();
            }
            var functionInfo = dicDryContactFunction[mainkeys];
            //获取第一级别(属性应该不会改变)
            Panel.PanelPrivateFunctionsResponseInfo result = null;
            if (functionInfo.listLevel1 == null)
            {
                result = await this.GetDryContactFunctionInterface(panel);
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelFirstList, -1, -1);
                if (level1 == -1)
                {
                    return result.privateFuncTypeLevelFirstList;
                }
            }
            //获取第二级别(属性应该不会改变)
            if (functionInfo.dicLevel2.ContainsKey(level1) == false)
            {
                result = await this.GetDryContactFunctionInterface(panel, new int[] { level1 });
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelSecondList, level1, -1);
                if (level2 == -1)
                {
                    return result.privateFuncTypeLevelSecondList;
                }
            }
            //获取第三级别(属性有可能会改变)
            if (reLevel3 == true || functionInfo.dicLevel3.ContainsKey(level2) == false)
            {
                result = await this.GetDryContactFunctionInterface(panel, new int[] { level1, level2 });
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelThirdList, level1, level2);
            }
            //从本地缓存当中获取它的私有属性
            return this.GetDryContactFunctionFromLocation(panel, level1, level2);
        }
        /// <summary>
        /// 获取按键面板的功能
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <param name="parameter">
                        break;
                    case 2:
                        level = temp2;
                        break;
                }
                sbString2.Append(level.ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   mode + time + sbString2;
            }
            catch { };
            return data;
        }
        #endregion
        #region ■ 获取干接点配置信息_________________
        /// <summary>
        /// 获取干接点配置信息
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <returns></returns>
        public List<CommonDevice.AttributeDataObj> GetDryContactConfigureInfo(CommonDevice device)
        {
            var result = HdlDeviceBindLogic.Current.ReadPanelConfigureInfoAsync(device);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.deviceStatusReportData == null)
            {
                //获取设备配置信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetDeviceConfigureInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            //如果不是6的话,这个数据是不对的
            if (result.deviceStatusReportData.CluterID != 6)
            {
                return new List<CommonDevice.AttributeDataObj>();
            }
            return result.deviceStatusReportData.AttriBute;
        }
        #endregion
        #region ■ 获取干接点功能系___________________
        /// <summary>
        /// <para>获取干接点功能系(异常时返回null,或者它没有指定功能,也会返回null)</para>
        /// <para>第一级别(参数全部省略时):</para>
        /// <para> 1024:灯类|256:按键类|768:PIR类</para>
        /// <para>第二级别:</para>
        /// <para> 1:特殊功能|100:Switch,开关(按键类)</para>
        /// <para> 200:Dimmer,调光(按键类)|300:Curtain,窗帘(按键类)</para>
        /// <para> 0:EnergySavingMode,节能模式(灯类)|1:SleepMode,睡眠模式(灯类)</para>
        /// <para> 100:WhiteBalance,白平衡(灯类)|101:RGBColor,RGB指示灯颜色(灯类)</para>
        /// <para> 102:RGBLevel,RGB指示灯亮度(灯类)</para>
        /// <para>第三级别:</para>
        /// <para>1:场景触发|65535:禁止发送功能</para>
        /// <para>100:SwitchOpen,开关开(按键类)|101:SwitchClose,开关关(按键类)</para>
        /// <para>102:SwitchChange,开关切换(按键类)|200:DimmerStepUp,增大调光(按键类)</para>
        /// <para>201:DimmerStepDown,降低调光(按键类)|202:DimmerStepChange,调光切换(按键类)</para>
        /// <para>300:CurtainOpen,窗帘开(按键类)|301:CurtainClose,窗帘关(按键类)</para>
        /// <para>302:CurtainStop,窗帘停|303:CurtainUpStop,窗帘上升停</para>
        /// <para>304:CurtainDownstop,窗帘下降停</para>
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <param name="level1">请参照第一级别的参数,省略时返回第一级别列表,设置时返回第二级别列表</param>
        /// <param name="level2">请参照第二级别的参数,省略时返回第二级别列表,设置时返回第三级别列表</param>
        /// <param name="reLevel3">重新获取第三级别的数据</param>
        /// <returns></returns>
        public async Task<List<int>> GetDryContactFunction(Panel panel, int level1 = -1, int level2 = -1, bool reLevel3 = false)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                //创建对象
                dicDryContactFunction[mainkeys] = new DryContactFunctionInfo();
            }
            var functionInfo = dicDryContactFunction[mainkeys];
            //获取第一级别(属性应该不会改变)
            Panel.PanelPrivateFunctionsResponseInfo result = null;
            if (functionInfo.listLevel1 == null)
            {
                result = await this.GetDryContactFunctionInterface(panel);
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelFirstList, -1, -1);
                if (level1 == -1)
                {
                    return result.privateFuncTypeLevelFirstList;
                }
            }
            //获取第二级别(属性应该不会改变)
            if (functionInfo.dicLevel2.ContainsKey(level1) == false)
            {
                result = await this.GetDryContactFunctionInterface(panel, new int[] { level1 });
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelSecondList, level1, -1);
                if (level2 == -1)
                {
                    return result.privateFuncTypeLevelSecondList;
                }
            }
            //获取第三级别(属性有可能会改变)
            if (reLevel3 == true || functionInfo.dicLevel3.ContainsKey(level2) == false)
            {
                result = await this.GetDryContactFunctionInterface(panel, new int[] { level1, level2 });
                if (result == null)
                {
                    return null;
                }
                //保存属性
                this.SetDryContactFunctionToMemory(panel, result.privateFuncTypeLevelThirdList, level1, level2);
            }
            //从本地缓存当中获取它的私有属性
            return this.GetDryContactFunctionFromLocation(panel, level1, level2);
        }
        /// <summary>
        /// 获取按键面板的功能
        /// </summary>
        /// <param name="panel">按键面板的某一个回路</param>
        /// <param name="parameter">
        /// <para>方法1:当int[]传空,返回值是“面板具有的功能大类,即返回“第一级别。1024:灯类,256:按键类,768:PIR类</para> 
        /// <para>方法2:、当int[]值为第一级别PrivateFuncTypeFir中选择一个。</para>
        /// <para>返回值是“面按键发送功能类”,即返回“第二级别。</para>
@@ -947,389 +988,389 @@
        /// <para>返回值是“面按键具体功能配置”,即返回“第二级别。</para>
        /// <para>100:SwitchOpen,开关开(按键类);101:SwitchClose,开关关(按键类);102:SwitchChange,开关切换(按键类)</para> 
        /// <para>200:DimmerStepUp,增大调光(按键类);201:DimmerStepDown,降低调光(按键类);202:DimmerStepChange,调光切换(按键类)</para> 
        /// <para>300:CurtainOpen,窗帘开(按键类);301:CurtainClose,窗帘关(按键类);302:CurtainStop,窗帘停;303:CurtainUpStop,窗帘上升停;304:CurtainDownstop,窗帘下降停</para>
        /// </param>
        /// <returns></returns>
        private async Task<Panel.PanelPrivateFunctionsResponseInfo> GetDryContactFunctionInterface(Panel panel, params int[] parameter)
        {
            var result = await panel.GetPanelPrivateFunctionsAsync(parameter);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.panelPrivateFunctionsResponseInfo == null)
            {
                //获取按键功能类信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelFunctionInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.panelPrivateFunctionsResponseInfo;
        }
        #endregion
        #region ■ 修改干接点私有属性_________________
        /// <summary>
        /// 修改干接点第三级别的私有属性
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <param name="i_value">干接点的第三级别属性的值,具体请参照第三级别属性</param>
        /// <returns></returns>
        public bool EditorDryContactThirdFunction(Panel panel, int i_value)
        {
            var result = HdlDeviceBindLogic.Current.ConfigureHdlKeyValueAsync(panel, (Panel.KeyMode)i_value);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //设备属性变更失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeChangedFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 134)
            {
                //设备不支持此属性(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceNotSupportTheAttribute);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 135)
            {
                //无效的设备属性值(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeIsIneffectiveness);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 141)
            {
                //无效的数据类型(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDataTypeIsIneffectiveness);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //设备属性变更失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeChangedFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 简约面板震动功能___________________
        /// <summary>
        /// 获取简约面板震动功能的信息(null表示出错)
        /// </summary>
        /// <param name="device">某一回路</param>
        /// <returns></returns>
        public PanelVibrationInfo GetPanelVibrationData(CommonDevice device)
        {
            //如果是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.GetPanelVibrationInfo(device);
            }
            //发送数据
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", "050108110101" } };
            jObject.Add("Data", data);
            var sendData = jObject.ToString();
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0802", 18, 6);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //获取震动反馈配置信息失败
                string errorMsg = Language.StringByID(R.MyInternationalizationString.uGetVibrationFeedbackSettionFail);
                errorMsg = UserCenterLogic.CombineGatewayTimeOutMsg(errorMsg, null, "回复超时", false);
                this.ShowTipMsg(errorMsg);
                return null;
            }
            var returnData = new PanelVibrationInfo();
            returnData.A震动使能 = result.ReceiptData.Substring(10, 2) == "01" ? true : false;
            returnData.A震动强度 = Convert.ToInt32(result.ReceiptData.Substring(12, 2), 16);
            returnData.A震动时间 = Convert.ToInt32(result.ReceiptData.Substring(14, 4), 16);
            return returnData;
        }
        /// <summary>
        /// 设置简约面板震动功能的信息
        /// </summary>
        /// <param name="device">某一回路</param>
        /// <param name="datainfo">设置的信息</param>
        /// <returns></returns>
        public bool SetPanelVibrationData(CommonDevice device, PanelVibrationInfo datainfo)
        {
            //如果是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return ModelData.DeviceModelDataLogic.Current.SetPanelVibrationInfo(device, datainfo, "ClientDataPassthrough");
            }
            //获取编辑面板震动功能的命令字符
            var sendData = this.GetPanelVibrationCommandText(device.DeviceAddr, datainfo);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 6);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //设置震动反馈配置信息失败
                string errorMsg = Language.StringByID(R.MyInternationalizationString.uSetVibrationFeedbackSettionFail);
                errorMsg = UserCenterLogic.CombineGatewayTimeOutMsg(errorMsg, null, "回复超时", false);
                this.ShowTipMsg(errorMsg);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 获取编辑面板震动功能的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="datainfo"></param>
        /// <returns></returns>
        public string GetPanelVibrationCommandText(string DeviceAddr, PanelVibrationInfo datainfo)
        {
            string passData = "0800081104";
            passData += datainfo.A震动使能 ? "01" : "00";
            passData += Convert.ToString(datainfo.A震动强度, 16).PadLeft(2, '0');
            string time = Convert.ToString(datainfo.A震动时间, 16).PadLeft(4, '0');
            //低位在前,高位在后
            passData += time.Substring(2, 2);
            passData += time.Substring(0, 2);
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 简约面板震动功能信息
        /// </summary>
        public class PanelVibrationInfo
        {
            /// <summary>
            /// 震动使能
            /// </summary>
            public bool A震动使能 = false;
            /// <summary>
            /// 震动强度(十进制)
            /// </summary>
            public int A震动强度 = 0;
            /// <summary>
            /// 震动时间(十进制)
            /// </summary>
            public int A震动时间 = 0;
        }
        #endregion
        #region ■ 缓存中的设备私有属性_______________
        /// <summary>
        /// 从缓存中获取设备的私有属性
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="level1"></param>
        /// <param name="level2"></param>
        /// <returns></returns>
        private List<int> GetDryContactFunctionFromLocation(Panel panel, int level1 = -1, int level2 = -1)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                return null;
            }
            var listLevel = new List<int>();
            var functionInfo = dicDryContactFunction[mainkeys];
            //第一级别
            if (level1 == -1)
            {
                if (functionInfo.listLevel1 == null)
                {
                    //第一级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.listLevel1);
            }
            //第二级别
            else if (level2 == -1)
            {
                if (functionInfo.dicLevel2.ContainsKey(level1) == false)
                {
                    //第二级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.dicLevel2[level1]);
            }
            //第三级别
            else
            {
                if (functionInfo.dicLevel3.ContainsKey(level2) == false)
                {
                    //第三级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.dicLevel3[level2]);
            }
            return listLevel;
        }
        /// <summary>
        /// 将设备的私有属性存入缓存中
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="listLevel"></param>
        /// <param name="level1"></param>
        /// <param name="level2"></param>
        private void SetDryContactFunctionToMemory(Panel panel, List<int> listLevel, int level1, int level2)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                //创建对象
                dicDryContactFunction[mainkeys] = new DryContactFunctionInfo();
            }
            var functionInfo = dicDryContactFunction[mainkeys];
            //第一级别
            if (level1 == -1)
            {
                //这个属性应该是不会变的
                functionInfo.listLevel1 = new List<int>();
                functionInfo.listLevel1.AddRange(listLevel);
            }
            //第二级别
            else if (level2 == -1)
            {
                if (functionInfo.dicLevel2.ContainsKey(level1) == false)
                {
                    functionInfo.dicLevel2[level1] = new List<int>();
                }
                functionInfo.dicLevel2[level1].Clear();
                functionInfo.dicLevel2[level1].AddRange(listLevel);
            }
            //第三级别
            else
            {
                if (functionInfo.dicLevel3.ContainsKey(level2) == false)
                {
                    //初始化容器
                    functionInfo.dicLevel3[level2] = new List<int>();
                }
                //第三级别的属性有可能会变更
                functionInfo.dicLevel3[level2].Clear();
                functionInfo.dicLevel3[level2].AddRange(listLevel);
            }
            //保存现阶段的干接点的私有属性到本地文件
            this.SaveDryContactFunctionToLocaltion();
        }
        /// <summary>
        /// 保存现阶段的干接点的私有属性到本地文件
        /// </summary>
        private void SaveDryContactFunctionToLocaltion()
        {
            var file = Newtonsoft.Json.JsonConvert.SerializeObject(dicDryContactFunction);
            var bytes = System.Text.Encoding.UTF8.GetBytes(file);
            Common.Global.WriteFileByBytesByHomeId(DirNameResourse.DryContactFunctionFile, bytes);
        }
        /// <summary>
        /// 从本地文件还原干接点的私有属性
        /// </summary>
        private void LoadDryContactFunctionFromLocaltion()
        {
            if (Common.Global.IsExistsByHomeId(DirNameResourse.DryContactFunctionFile) == false)
            {
                return;
            }
            byte[] filebyte = Common.Global.ReadFileByHomeId(DirNameResourse.DryContactFunctionFile);
            string strvalue = System.Text.Encoding.UTF8.GetString(filebyte);
            this.dicDryContactFunction = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, DryContactFunctionInfo>>(strvalue);
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 显示错误信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowErrorMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Error, msg);
                contr.Show();
            });
        }
        /// <summary>
        /// 显示Tip信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowTipMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                contr.Show();
            });
        }
        #endregion
        #region ■ 结构体_____________________________
        /// <summary>
        /// 干接点功能信息
        /// </summary>
        private class DryContactFunctionInfo
        {
            /// <summary>
            /// 第一级别(注意,这个东西和【dicLevel2,dicLevel3】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public List<int> listLevel1 = null;
            /// <summary>
            /// 第二级别(主键为第一级别。注意,这个东西和【listLevel1,dicLevel3】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public Dictionary<int, List<int>> dicLevel2 = new Dictionary<int, List<int>>();
            /// <summary>
            /// 第三级别(主键为第二级别。注意,这个东西和【listLevel1,dicLevel2】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public Dictionary<int, List<int>> dicLevel3 = new Dictionary<int, List<int>>();
        }
        #endregion
    }
}
        /// <para>300:CurtainOpen,窗帘开(按键类);301:CurtainClose,窗帘关(按键类);302:CurtainStop,窗帘停;303:CurtainUpStop,窗帘上升停;304:CurtainDownstop,窗帘下降停</para>
        /// </param>
        /// <returns></returns>
        private async Task<Panel.PanelPrivateFunctionsResponseInfo> GetDryContactFunctionInterface(Panel panel, params int[] parameter)
        {
            var result = await panel.GetPanelPrivateFunctionsAsync(parameter);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return null;
            }
            if (result == null || result.panelPrivateFunctionsResponseInfo == null)
            {
                //获取按键功能类信息失败
                string msg = Language.StringByID(R.MyInternationalizationString.uGetPanelFunctionInfoFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return null;
            }
            return result.panelPrivateFunctionsResponseInfo;
        }
        #endregion
        #region ■ 修改干接点私有属性_________________
        /// <summary>
        /// 修改干接点第三级别的私有属性
        /// </summary>
        /// <param name="panel">干接点对象</param>
        /// <param name="i_value">干接点的第三级别属性的值,具体请参照第三级别属性</param>
        /// <returns></returns>
        public bool EditorDryContactThirdFunction(Panel panel, int i_value)
        {
            var result = HdlDeviceBindLogic.Current.ConfigureHdlKeyValueAsync(panel, (Panel.KeyMode)i_value);
            //共通错误检测
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowErrorMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //设备属性变更失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeChangedFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 134)
            {
                //设备不支持此属性(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceNotSupportTheAttribute);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 135)
            {
                //无效的设备属性值(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeIsIneffectiveness);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status == 141)
            {
                //无效的数据类型(XXX)
                string msg = Language.StringByID(R.MyInternationalizationString.uDataTypeIsIneffectiveness);
                msg += "(" + i_value + ")";
                this.ShowErrorMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //设备属性变更失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeviceAttributeChangedFail);
                this.ShowErrorMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 简约面板震动功能___________________
        /// <summary>
        /// 获取简约面板震动功能的信息(null表示出错)
        /// </summary>
        /// <param name="device">某一回路</param>
        /// <returns></returns>
        public PanelVibrationInfo GetPanelVibrationData(CommonDevice device)
        {
            //如果是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.GetPanelVibrationInfo(device.DeviceAddr, 200);
            }
            //发送数据
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", "050108110101" } };
            jObject.Add("Data", data);
            var sendData = jObject.ToString();
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0802", 18, 6);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //获取震动反馈配置信息失败
                string errorMsg = Language.StringByID(R.MyInternationalizationString.uGetVibrationFeedbackSettionFail);
                errorMsg = UserCenterLogic.CombineGatewayTimeOutMsg(errorMsg, null, "回复超时", false);
                this.ShowTipMsg(errorMsg);
                return null;
            }
            var returnData = new PanelVibrationInfo();
            returnData.A震动使能 = result.ReceiptData.Substring(10, 2) == "01" ? true : false;
            returnData.A震动强度 = Convert.ToInt32(result.ReceiptData.Substring(12, 2), 16);
            returnData.A震动时间 = Convert.ToInt32(result.ReceiptData.Substring(14, 4), 16);
            return returnData;
        }
        /// <summary>
        /// 设置简约面板震动功能的信息
        /// </summary>
        /// <param name="device">某一回路</param>
        /// <param name="datainfo">设置的信息</param>
        /// <returns></returns>
        public bool SetPanelVibrationData(CommonDevice device, PanelVibrationInfo datainfo)
        {
            //如果是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.SetPanelVibrationInfo(device.DeviceAddr, 200, datainfo, null);
            }
            //获取编辑面板震动功能的命令字符
            var sendData = this.GetPanelVibrationCommandText(device.DeviceAddr, datainfo);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway2(device, sendData, "0002", 16, 6);
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //设置震动反馈配置信息失败
                string errorMsg = Language.StringByID(R.MyInternationalizationString.uSetVibrationFeedbackSettionFail);
                errorMsg = UserCenterLogic.CombineGatewayTimeOutMsg(errorMsg, null, "回复超时", false);
                this.ShowTipMsg(errorMsg);
                return false;
            }
            //添加缓存
            TemplateData.TemplateDeviceDataLogic.Current.SetPanelVibrationInfo(device.DeviceAddr, 200, datainfo, result.JsonData[0]);
            return true;
        }
        /// <summary>
        /// 获取编辑面板震动功能的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="datainfo"></param>
        /// <returns></returns>
        public string GetPanelVibrationCommandText(string DeviceAddr, PanelVibrationInfo datainfo)
        {
            string passData = "0800081104";
            passData += datainfo.A震动使能 ? "01" : "00";
            passData += Convert.ToString(datainfo.A震动强度, 16).PadLeft(2, '0');
            string time = Convert.ToString(datainfo.A震动时间, 16).PadLeft(4, '0');
            //低位在前,高位在后
            passData += time.Substring(2, 2);
            passData += time.Substring(0, 2);
            var jObject = new Newtonsoft.Json.Linq.JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
            var data = new Newtonsoft.Json.Linq.JObject { { "PassData", passData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        /// <summary>
        /// 简约面板震动功能信息
        /// </summary>
        public class PanelVibrationInfo
        {
            /// <summary>
            /// 震动使能
            /// </summary>
            public bool A震动使能 = false;
            /// <summary>
            /// 震动强度(十进制)
            /// </summary>
            public int A震动强度 = 0;
            /// <summary>
            /// 震动时间(十进制)
            /// </summary>
            public int A震动时间 = 0;
        }
        #endregion
        #region ■ 缓存中的设备私有属性_______________
        /// <summary>
        /// 从缓存中获取设备的私有属性
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="level1"></param>
        /// <param name="level2"></param>
        /// <returns></returns>
        private List<int> GetDryContactFunctionFromLocation(Panel panel, int level1 = -1, int level2 = -1)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                return null;
            }
            var listLevel = new List<int>();
            var functionInfo = dicDryContactFunction[mainkeys];
            //第一级别
            if (level1 == -1)
            {
                if (functionInfo.listLevel1 == null)
                {
                    //第一级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.listLevel1);
            }
            //第二级别
            else if (level2 == -1)
            {
                if (functionInfo.dicLevel2.ContainsKey(level1) == false)
                {
                    //第二级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.dicLevel2[level1]);
            }
            //第三级别
            else
            {
                if (functionInfo.dicLevel3.ContainsKey(level2) == false)
                {
                    //第三级别从来都没有获取过
                    return null;
                }
                listLevel.AddRange(functionInfo.dicLevel3[level2]);
            }
            return listLevel;
        }
        /// <summary>
        /// 将设备的私有属性存入缓存中
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="listLevel"></param>
        /// <param name="level1"></param>
        /// <param name="level2"></param>
        private void SetDryContactFunctionToMemory(Panel panel, List<int> listLevel, int level1, int level2)
        {
            string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(panel);
            if (dicDryContactFunction.ContainsKey(mainkeys) == false)
            {
                //创建对象
                dicDryContactFunction[mainkeys] = new DryContactFunctionInfo();
            }
            var functionInfo = dicDryContactFunction[mainkeys];
            //第一级别
            if (level1 == -1)
            {
                //这个属性应该是不会变的
                functionInfo.listLevel1 = new List<int>();
                functionInfo.listLevel1.AddRange(listLevel);
            }
            //第二级别
            else if (level2 == -1)
            {
                if (functionInfo.dicLevel2.ContainsKey(level1) == false)
                {
                    functionInfo.dicLevel2[level1] = new List<int>();
                }
                functionInfo.dicLevel2[level1].Clear();
                functionInfo.dicLevel2[level1].AddRange(listLevel);
            }
            //第三级别
            else
            {
                if (functionInfo.dicLevel3.ContainsKey(level2) == false)
                {
                    //初始化容器
                    functionInfo.dicLevel3[level2] = new List<int>();
                }
                //第三级别的属性有可能会变更
                functionInfo.dicLevel3[level2].Clear();
                functionInfo.dicLevel3[level2].AddRange(listLevel);
            }
            //保存现阶段的干接点的私有属性到本地文件
            this.SaveDryContactFunctionToLocaltion();
        }
        /// <summary>
        /// 保存现阶段的干接点的私有属性到本地文件
        /// </summary>
        private void SaveDryContactFunctionToLocaltion()
        {
            HdlFileLogic.Current.SaveFileContent(DirNameResourse.DryContactFunctionFile, dicDryContactFunction);
        }
        /// <summary>
        /// 从本地文件还原干接点的私有属性
        /// </summary>
        private void LoadDryContactFunctionFromLocaltion()
        {
            this.dicDryContactFunction = new Dictionary<string, DryContactFunctionInfo>();
            byte[] filebyte = HdlFileLogic.Current.ReadFileByteContent(DirNameResourse.DryContactFunctionFile);
            if (filebyte == null)
            {
                return;
            }
            string strvalue = System.Text.Encoding.UTF8.GetString(filebyte);
            this.dicDryContactFunction = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, DryContactFunctionInfo>>(strvalue);
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 显示错误信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowErrorMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Error, msg);
                contr.Show();
            });
        }
        /// <summary>
        /// 显示Tip信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowTipMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                contr.Show();
            });
        }
        #endregion
        #region ■ 结构体_____________________________
        /// <summary>
        /// 干接点功能信息
        /// </summary>
        private class DryContactFunctionInfo
        {
            /// <summary>
            /// 第一级别(注意,这个东西和【dicLevel2,dicLevel3】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public List<int> listLevel1 = null;
            /// <summary>
            /// 第二级别(主键为第一级别。注意,这个东西和【listLevel1,dicLevel3】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public Dictionary<int, List<int>> dicLevel2 = new Dictionary<int, List<int>>();
            /// <summary>
            /// 第三级别(主键为第二级别。注意,这个东西和【listLevel1,dicLevel2】不同步,因为它遵从于获取后才保存的原则)
            /// </summary>
            public Dictionary<int, List<int>> dicLevel3 = new Dictionary<int, List<int>>();
        }
        #endregion
    }
}