黄学彪
2020-12-16 0d9f64668fd7350d6a21fd157e32009a96d98134
ZigbeeApp/Shared/Phone/Common/Logic/HdlDeviceCommonLogic.cs
File was renamed from ZigbeeApp/Shared/Common/Device.cs
@@ -1,33 +1,33 @@
using Shared.Phone.UserCenter;
using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
using Shared.Common;
namespace Shared.Common
namespace Shared.Phone
{
    /// <summary>
    /// 本地设备
    /// 设备的共通逻辑
    /// </summary>
    public class LocalDevice
    public class HdlDeviceCommonLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 本地设备
        /// 设备的共通逻辑
        /// </summary>
        private static LocalDevice m_Current = null;
        private static HdlDeviceCommonLogic m_Current = null;
        /// <summary>
        /// 本地设备
        /// 设备的共通逻辑
        /// </summary>
        public static LocalDevice Current
        public static HdlDeviceCommonLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new LocalDevice();
                    m_Current = new HdlDeviceCommonLogic();
                }
                return m_Current;
            }
@@ -106,7 +106,7 @@
                try
                {
                    //读取它的内容
                    var fileData = HdlFileLogic.Current.ReadFileTextContent(System.IO.Path.Combine(Config.Instance.FullPath, file));
                    var fileData = HdlFileLogic.Current.ReadFileTextContent(System.IO.Path.Combine(Common.Config.Instance.FullPath, file));
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(fileData);
                    if (jobject.Property("DeviceID") == null)
                    {
@@ -125,7 +125,7 @@
                //如果这个设备的网关ID不存在的话
                if (HdlGatewayLogic.Current.IsGatewayExist(device.CurrentGateWayId) == false)
                {
                    if (UserCenterResourse.UserInfo.AuthorityNo == 3)
                    if (HdlUserCenterResourse.ResidenceOption.AuthorityNo == 3)
                    {
                        //如果他是成员的话,帮他新建一个网关
                        HdlGatewayLogic.Current.AddVirtualGateway(device.CurrentGateWayId);
@@ -145,14 +145,6 @@
                    this.dicOTADevice[mainKey] = (OTADevice)device;
                    continue;
                }
                //如果设备是晾衣架,则一端点,其他端点(2~5)过滤,
                //因为其他端点只有控制作用,(2:控制照明,3:控制风干,4:控制烘干,5:控制消毒)
                //产品经理不让显示
                if (device is Airer)
                {
                    if (device.DeviceEpoint == 2 || device.DeviceEpoint == 3 || device.DeviceEpoint == 4 || device.DeviceEpoint == 5)
                        continue;
                }
                //添加缓存
                this.dicAllDevice[mainKey] = device;
@@ -168,7 +160,7 @@
                if (bolSave == true)
                {
                    //删掉这个文件,重新生成
                    HdlAutoBackupLogic.DeleteFile(file);
                    HdlBackupLogic.Current.DeleteAutoBackFileStatu(file);
                    Global.DeleteFilebyHomeId(file);
                }
@@ -178,7 +170,7 @@
                    //不存在的话,重新生成
                    device.IconPath = string.Empty;
                    device.ReSave();
                    HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
                    bolSave = false;
                }
@@ -186,16 +178,14 @@
                if (bolSave == true)
                {
                    device.ReSave();
                    HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
                }
            }
            //成员身份的时候,删除掉非法的网关文件
            this.DeleteGatewayFileByMemberModel();
            //初始化物理设备所属房间的记录
            HdlRoomLogic.Current.InitRealDeviceRoomId();
#if DEBUG
            if (UserCenterResourse.HideOption.CenterHideMenu == 1)
            if (HdlUserCenterResourse.HideOption.CenterHideMenu == 1)
            {
                //检测一些代码配置(debug)
                this.CheckOhtherSettion();
@@ -208,7 +198,7 @@
        /// </summary>
        private void DeleteGatewayFileByMemberModel()
        {
            if (UserCenterResourse.UserInfo.AuthorityNo != 3)
            if (HdlUserCenterResourse.ResidenceOption.AuthorityNo != 3)
            {
                return;
            }
@@ -327,7 +317,7 @@
                    dicExist.Remove(maikey);
                }
                //获取设备的固定属性
                if (HdlDeviceFixedAttributeLogic.Current.SetAllFixedAttributeToDevice(device) == true)
                if (HdlDeviceAttributeLogic.Current.ReadDeviceAllFixedAttribute(device) == true)
                {
                    System.Threading.Thread.Sleep(200);
                }
@@ -403,17 +393,8 @@
                if (exists == false)
                {
                    //添加自动备份
                    HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
                }
                return;
            }
            //如果设备是晾衣架,则一端点,其他端点(2~5)过滤,
            //因为其他端点只有控制作用,(2:控制照明,3:控制风干,4:控制烘干,5:控制消毒)
            //产品经理不让显示
            if (device is Airer)
            {
                if (device.DeviceEpoint == 2 || device.DeviceEpoint == 3 || device.DeviceEpoint == 4 || device.DeviceEpoint == 5)
                    return;
            }
@@ -450,7 +431,7 @@
            if (exists2 == false)
            {
                //添加自动备份
                HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
            }
        }
@@ -465,14 +446,6 @@
            {
                this.dicOTADevice[mainKeys] = (OTADevice)device;
                device.ReSave();
                return;
            }
            //如果设备是晾衣架,则一端点,其他端点(2~5)过滤,
            //因为其他端点只有控制作用,(2:控制照明,3:控制风干,4:控制烘干,5:控制消毒)
            //产品经理不让显示
            if (device is Airer)
            {
                if (device.DeviceEpoint == 2 || device.DeviceEpoint == 3 || device.DeviceEpoint == 4 || device.DeviceEpoint == 5)
                    return;
            }
            this.dicAllDevice[mainKeys] = device;
@@ -516,7 +489,7 @@
            //不再检测名字是否一样
            //成员只能修改自己本地的名字
            if (UserCenterResourse.UserInfo.AuthorityNo != 3)
            if (HdlUserCenterResourse.ResidenceOption.AuthorityNo != 3)
            {
                var result = this.RenameDeviceNameAsync(device, newName);
                if (result == null || result.deviceRenameData == null || result.deviceRenameData.Result == 1)
@@ -524,7 +497,7 @@
                    //设备名称修改失败
                    string msg = Language.StringByID(R.MyInternationalizationString.uDeviceReNameFail);
                    //拼接上【网关回复超时】的Msg
                    msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                    msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result);
                    if (mode == ShowErrorMode.YES)
                    {
@@ -569,7 +542,7 @@
            CommonDevice device = listDevice[0];
            //不再检测名字是否一样
            //成员只能修改自己本地的名字
            if (UserCenterResourse.UserInfo.AuthorityNo != 3)
            if (HdlUserCenterResourse.ResidenceOption.AuthorityNo != 3)
            {
                //修改物理名字
                var result = this.RenameDeviceMacNameAsync(device, newMacName);
@@ -578,7 +551,7 @@
                    //设备名称修改失败
                    string msg = Language.StringByID(R.MyInternationalizationString.uDeviceReNameFail);
                    //拼接上【网关回复超时】的Msg
                    msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                    msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result);
                    if (mode == ShowErrorMode.YES)
                    {
                        this.ShowErrorMsg(msg);
@@ -658,7 +631,7 @@
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return Phone.TemplateData.TemplateDeviceDataLogic.Current.ReDeviceMacName(device, macName);
                return Phone.HdlTemplateDeviceDataLogic.Current.ReDeviceMacName(device, macName);
            }
            //获取编辑设备Mac名字的命令字符
@@ -669,7 +642,7 @@
                return null;
            }
            //加缓存
            Phone.TemplateData.TemplateDeviceDataLogic.Current.ReDeviceMacName(device, macName);
            Phone.HdlTemplateDeviceDataLogic.Current.ReDeviceMacName(device, macName);
            var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.RenameDeviceMacNameData>(result.ReceiptData);
            return new CommonDevice.RenameDeviceMacNameAllData { renameDeviceMacNameData = tempData };
@@ -686,7 +659,7 @@
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return Phone.TemplateData.TemplateDeviceDataLogic.Current.ReDeviceEpointName(device, deviceName);
                return Phone.HdlTemplateDeviceDataLogic.Current.ReDeviceEpointName(device, deviceName);
            }
            //获取编辑设备端点名字的命令字符
            var sendData = this.GetReDeviceEpointNameCommandText(device.DeviceAddr, device.DeviceEpoint, deviceName);
@@ -696,7 +669,7 @@
                return null;
            }
            //加缓存
            Phone.TemplateData.TemplateDeviceDataLogic.Current.ReDeviceEpointName(device, deviceName);
            Phone.HdlTemplateDeviceDataLogic.Current.ReDeviceEpointName(device, deviceName);
            var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.DeviceRenameResponseData>(result.ReceiptData);
            return new CommonDevice.DeviceRenameAllData { deviceRenameData = tempData };
@@ -759,7 +732,7 @@
                    device.ReSave();
                    //添加自动备份
                    HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
                }
                else if (this.dicOTADevice.ContainsKey(mainKeys) == true)
                {
@@ -768,7 +741,7 @@
                    device.ReSave();
                    //添加自动备份
                    HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
                }
            }
@@ -799,7 +772,7 @@
                    //设备删除失败
                    string msg = Language.StringByID(R.MyInternationalizationString.uDeviceDeleteFail);
                    //拼接上【网关回复超时】的Msg
                    msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                    msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result);
                    this.ShowErrorMsg(msg);
                    return false;
@@ -852,13 +825,13 @@
                }
            }
            //删除模板数据
            Phone.TemplateData.TemplateCommonLogic.Current.DeleteDevice(device);
            Phone.HdlTemplateCommonLogic.Current.DeleteDevice(device);
            //删除设备文件
            string filePath = device.FilePath;
            if (Global.IsExistsByHomeId(filePath) == true)
            {
                if (UserCenterResourse.UserInfo.AuthorityNo == 3)
                if (HdlUserCenterResourse.ResidenceOption.AuthorityNo == 3)
                {
                    //成员的话,直接删除,没有商量的余地
                    Global.DeleteFilebyHomeId(filePath);
@@ -868,7 +841,7 @@
                    //变更:搞掉它,不留了
                    Global.DeleteFilebyHomeId(filePath);
                    //删除自动备份
                    HdlAutoBackupLogic.DeleteFile(device.FilePath);
                    HdlBackupLogic.Current.DeleteAutoBackFileStatu(device.FilePath);
                }
            }
        }
@@ -887,7 +860,7 @@
                string otaFile = this.dicOTADevice[otaKeys].FilePath;
                if (Global.IsExistsByHomeId(otaFile) == true)
                {
                    if (UserCenterResourse.UserInfo.AuthorityNo == 3)
                    if (HdlUserCenterResourse.ResidenceOption.AuthorityNo == 3)
                    {
                        //成员的话,直接删除,没有商量的余地
                        Global.DeleteFilebyHomeId(otaFile);
@@ -897,7 +870,7 @@
                        //变更:搞掉它,不留了
                        Global.DeleteFilebyHomeId(otaFile);
                        //删除自动备份
                        HdlAutoBackupLogic.DeleteFile(otaFile);
                        HdlBackupLogic.Current.DeleteAutoBackFileStatu(otaFile);
                    }
                }
                this.dicOTADevice.Remove(otaKeys);
@@ -914,7 +887,7 @@
        public async Task<bool> SynchronizationDevice(List<CommonDevice> listdevice)
        {
            //虚拟住宅的话,不需要删除网关的设备
            if (Config.Instance.Home.IsVirtually == false)
            if (Common.Config.Instance.Home.IsVirtually == false)
            {
                //同步
                var result = await listdevice[0].SyncMsgToBindSource(listdevice[0].DeviceAddr, listdevice[0].DeviceEpoint);
@@ -923,7 +896,7 @@
                    //同步删除失败
                    string msg = Language.StringByID(R.MyInternationalizationString.SynchronizationFailed);
                    //拼接上【网关回复超时】的Msg
                    msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                    msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result);
                    this.ShowErrorMsg(msg);
                    return false;
@@ -967,9 +940,9 @@
        /// <returns></returns>
        public bool DeviceIsCanFixedPosition(CommonDevice device)
        {
            if (device.Type == DeviceType.DoorLock || device.Type == DeviceType.Airer || device.Type == DeviceType.PMSensor)
            if (device.Type == DeviceType.DoorLock || device.Type == DeviceType.PMSensor)
            {
                //门锁和晾衣架没有定位功能;
                //门锁没有定位功能
                return false;
            }
            var myTypeInfo = this.GetMyDeviceEnumInfo(new List<CommonDevice>() { device });
@@ -1012,7 +985,7 @@
        public bool DeviceIsCanSynchronization(CommonDevice device)
        {
            //获取设备类型的
            var deviceEnumInfo = Common.LocalDevice.Current.GetMyDeviceEnumInfo(new List<CommonDevice>() { device });
            var deviceEnumInfo = this.GetMyDeviceEnumInfo(new List<CommonDevice>() { device });
            if (deviceEnumInfo.ConcreteType == DeviceConcreteType.ButtonPanel_SimpleMultifunction)
            {
                return true;
@@ -1495,7 +1468,7 @@
                        {
                            //重新生成缓存
                            tempDevice.ReSave();
                            HdlAutoBackupLogic.AddOrEditorFile(tempDevice.FilePath);
                            HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(tempDevice.FilePath);
                            //全部主页菜单需要刷新
                            Phone.UserView.UserPage.Instance.RefreshAllForm = true;
                        }
@@ -1747,7 +1720,7 @@
            device.IsCustomizeImage = true;
            device.ReSave();
            HdlAutoBackupLogic.AddOrEditorFile(device.FilePath);
            HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(device.FilePath);
        }
        /// <summary>
@@ -2399,22 +2372,6 @@
                info.ConcreteType = DeviceConcreteType.ColorLight_Temperature;
                info.ObjectTypeName = this.dicDeviceModelIdEnum["A420"].A类型名字;//调光模块
            }
            //17晾衣架
            else if (dicType.ContainsKey(DeviceType.Airer) == true)
            {
                info.ConcreteText = this.dicDeviceModelIdEnum["A421"].A官方名字;
                info.BeloneType = DeviceBeloneType.A晾衣架;
                info.ConcreteType = DeviceConcreteType.Airer;
                info.ObjectTypeName = this.dicDeviceModelIdEnum["A421"].A类型名字;
            }
            //18空气质量传感器
            else if (dicType.ContainsKey(DeviceType.AirQualitySensor) == true)
            {
                info.ConcreteText = this.dicDeviceModelIdEnum["A422"].A官方名字;
                info.BeloneType = DeviceBeloneType.A空气质量;
                info.ConcreteType = DeviceConcreteType.AirQualitySensor;
                info.ObjectTypeName = this.dicDeviceModelIdEnum["A422"].A类型名字;
            }
            //设备所属类型的翻译名字
            info.BeloneText = info.ConcreteText;
@@ -2561,73 +2518,346 @@
        #endregion
        #region ■ 晾衣架设备时间配置___________________________
        #region ■ 获取主页设备状态的翻译文本_________
        /// <summary>
        ///  设置晾衣架风干,烘干和消毒时间(设置失败时,会显示信息)
        ///  time:设置的分钟
        /// 获取主页设备状态的翻译文本
        /// </summary>
        /// <param name="litdevice">设备对象(MAC地址必须要相同)</param>
        public async Task<bool> SetAirerTimeDevice(List<CommonDevice> listdevice, Airer airer, int time, int controlEpoint)
        /// <returns></returns>
        public string GetMainPageDeviceStatuText(CommonDevice device)
        {
            //虚拟住宅的话,不需要
            if (Config.Instance.Home.IsVirtually == false)
            if (device.Type == DeviceType.OnOffOutput)
            {
                foreach (var dev in listdevice)
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    //设置属性信息
                    CommonDevice.SetWritableValueData dataT = new CommonDevice.SetWritableValueData();
                    dataT.Undivided = 0;
                    dataT.AttributeId = 16385;
                    dataT.AttributeDataType = 33;
                    dataT.AttributeData = time;
                    dev.DeviceEpoint = controlEpoint;//暂时换成晾衣架对应的控制端点
                    var result = await dev.SetWritableValueAsync(6, dataT);
                    if (result == null || result.setWritableValueResponData == null || result.setWritableValueResponData.Status != 0)
                    {
                        //设置失败
                        if (dev.DeviceEpoint == 3)
                        {
                            if (airer.WindTime != 0)
                            {
                                airer.WindTime = 0;
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                            }
                            string msg = Language.StringByID(R.MyInternationalizationString.AirerWindTimeFailed);
                            //拼接上【网关回复超时】的Msg
                            msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                            dev.DeviceEpoint = 1;//将晾衣架对应的控制端点还原成1端点
                            this.ShowErrorMsg(msg);
                            return false;
                        }
                        if (dev.DeviceEpoint == 4)
                if ((device as ToggleLight).OnOffStatus == 1)
                        {
                            if (airer.DryTime != 0)
                            {
                                airer.DryTime = 0;
                    return Language.StringByID(R.MyInternationalizationString.uOpen1);
                            }
                            string msg = Language.StringByID(R.MyInternationalizationString.AirerDryTimeFailed);
                            //拼接上【网关回复超时】的Msg
                            msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                            dev.DeviceEpoint = 1;//将晾衣架对应的控制端点还原成1端点
                            this.ShowErrorMsg(msg);
                            return false;
                return Language.StringByID(R.MyInternationalizationString.Close);
                        }
                        if (dev.DeviceEpoint == 5)
            else if (device.Type == DeviceType.AirSwitch)
                        {
                            if (airer.DisinfectTime != 0)
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                            {
                                airer.DisinfectTime = 0;
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                            }
                            string msg = Language.StringByID(R.MyInternationalizationString.AirerDisinfectTimeFailed);
                            //拼接上【网关回复超时】的Msg
                            msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                            this.ShowErrorMsg(msg);
                            dev.DeviceEpoint = 1;//将晾衣架对应的控制端点还原成1端点
                            return false;
                if ((device as AirSwitch).OnOffStatus == 1)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOpen1);
                }
                return Language.StringByID(R.MyInternationalizationString.Close);
            }
            else if (device.Type == DeviceType.DimmableLight)
            {
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                }
                if ((device as DimmableLight).OnOffStatus == 0)
                {
                    return Language.StringByID(R.MyInternationalizationString.Close);
                }
                return $"{(int)((device as DimmableLight).Level * 1.0 / 254 * 100)}%";
            }
            else if (device.Type == DeviceType.ColorTemperatureLight)
            {
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                }
                if ((device as ColorTemperatureLight).OnOffStatus == 0)
                {
                    return Language.StringByID(R.MyInternationalizationString.Close);
                }
                return $"{(int)((device as ColorTemperatureLight).Level * 1.0 / 254 * 100)}%";
            }
            else if (device.Type == DeviceType.WindowCoveringDevice)
            {
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                }
                if ((device as Rollershade).WcdCurrentPositionLiftPercentage == 0)
                {
                    return Language.StringByID(R.MyInternationalizationString.Close);
                }
                return $"{(device as Rollershade).WcdCurrentPositionLiftPercentage}%";
            }
            else if (device.Type == DeviceType.FreshAir)
            {
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                }
                //模式
                string wind = string.Empty;
                var freshAir = device as FreshAir;
                if (freshAir.currentFanStatus == 0)
                {
                    return Language.StringByID(R.MyInternationalizationString.Close);
                }
                if (freshAir.currentFanSpeed == 1)
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Low);
                }
                else if (freshAir.currentFanSpeed == 2)
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Middle);
                }
                else if (freshAir.currentFanSpeed == 3)
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Height);
                }
                return $"{wind}";
            }
            else if (device.Type == DeviceType.PMSensor)
            {
                //空气质量
                string curQuality = "";
                //温度
                string temperature = string.Empty;
                //湿度
                string humidity = string.Empty;
                //PM2.5
                string pm = string.Empty;
                var pMSensor = device as PMSensor;
                if (pMSensor.currentPmData <= 35 && pMSensor.currentPmData >= 0)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else if (pMSensor.currentPmData <= 75 && pMSensor.currentPmData > 35)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else if (pMSensor.currentPmData <= 115 && pMSensor.currentPmData > 75)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else if (pMSensor.currentPmData <= 150 && pMSensor.currentPmData > 115)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else if (pMSensor.currentPmData <= 250 && pMSensor.currentPmData > 150)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else if (pMSensor.currentPmData > 250)
                {
                    curQuality = Language.StringByID(R.MyInternationalizationString.ExcellentAirQuality);
                }
                else
                {
                    curQuality = "--";
                }
                humidity = $"{pMSensor.currentHumidity}%";
                temperature = $"{pMSensor.currentTemperature}℃";
                pm = $"{pMSensor.currentPmData}μg/m³";
                return $"{curQuality},{pm},{temperature},{humidity}";
            }
            else if (device.Type == DeviceType.Thermostat)
            {
                //在网关没有回复之前,默认离线
                if (device.HadReadDeviceStatu == false)
                {
                    return Language.StringByID(R.MyInternationalizationString.uOffLine);
                }
                //温度,模式,风速
                string tempareture = string.Empty;
                string model = string.Empty;
                string wind = string.Empty;
                var ac = device as AC;
                if (ac.currentSystemMode == 0)
                {
                    return Language.StringByID(R.MyInternationalizationString.Close);
                }
                else if (ac.currentSystemMode == 1)
                {
                    model = Language.StringByID(R.MyInternationalizationString.Mode_Auto);
                    tempareture = $"{ac.currentAutoSetpoint} ℃";
                }
                else if (ac.currentSystemMode == 3)
                {
                    model = Language.StringByID(R.MyInternationalizationString.Mode_Cool);
                    tempareture = $"{ac.currentCoolingSetpoint} ℃";
                }
                else if (ac.currentSystemMode == 4)
                {
                    model = Language.StringByID(R.MyInternationalizationString.Mode_Heat);
                    tempareture = $"{ac.currentHeatingSetpoint} ℃";
                }
                else if (ac.currentSystemMode == 7)
                {
                    model = Language.StringByID(R.MyInternationalizationString.Mode_FanOnly);
                }
                else if (ac.currentSystemMode == 8)
                {
                    model = Language.StringByID(R.MyInternationalizationString.Mode_Dry);
                    tempareture = $"{ac.currentCoolingSetpoint} ℃";
                }
                if (ac.currentFanMode == 1)
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Low);
                }
                else if (ac.currentFanMode == 2)
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Middle);
                }
                else
                {
                    wind = Language.StringByID(R.MyInternationalizationString.Fan_Height);
                }
                if (string.IsNullOrEmpty(tempareture))
                {
                    return $"{model},{wind}";
                }
                return $"{model},{wind},{tempareture}";
            }
            else if (device.Type == DeviceType.IASZone)
            {
                var ias = device as IASZone;
                //区分传感器具体类型
                var info = HdlDeviceCommonLogic.Current.GetNotHdlMyDeviceEnumInfo(new List<CommonDevice> { device });
                if (info.ConcreteType == DeviceConcreteType.Sensor_Infrared)
                {
                    //红外
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_HavePerson);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_NoPerson);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_Water)
                {
                    //水浸
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_HaveWater);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Normal);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_DoorWindow)
                {
                    //门窗
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Open);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Close);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_CarbonMonoxide)
                {
                    //燃气
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.uGasLeakage);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Normal);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_Fire)
                {
                    //烟雾
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.uSmogAlarm);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Safe);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_Pir)
                {
                    //pir
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_HavePerson);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_NoPerson);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_Keyfob)
                {
                    //钥匙扣
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Alarm);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Normal);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_Motion)
                {
                    //运动传感器
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_HavePerson);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_NoPerson);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_EmergencyButton)
                {
                    //紧急按钮
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Alarm);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Normal);
                }
                else if (info.ConcreteType == DeviceConcreteType.Sensor_SphericalMotion)
                {
                    //球型移动传感器
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_HavePerson);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_NoPerson);
                }
                else
                {
                    //其他传感器
                    if (ias.iASInfo?.Alarm1 == 1)
                    {
                        return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Alarm);
                    }
                    return Language.StringByID(R.MyInternationalizationString.IASZone_Statu_Normal);
                        }
                    }
            else if (device.Type == DeviceType.TemperatureSensor)
            {
                var tempera = device as TemperatureSensor;
                if (tempera.SensorDiv == 1)
                {
                    if (tempera.currentTemperature == 0)
                    {
                        return "0.0℃";
                }
                    return $"{tempera.currentTemperature}℃";
            }
            return true;
                else if (tempera.SensorDiv == 2)
                {
                    if (tempera.currentHumidity == 0)
                    {
                        return "--%";
                    }
                    return $"{tempera.currentHumidity}%";
                }
                return null;
            }
            else
            {
                return null;
            }
        }
        #endregion
@@ -2684,7 +2914,7 @@
            //2020.03.30追加式样:如果是面板的温度探头,不显示
            else if (i_device.Type == DeviceType.TemperatureSensor && ((TemperatureSensor)i_device).SensorDiv == 1)
            {
                var myInfoType = LocalDevice.Current.GetMyDeviceEnumInfo(new List<CommonDevice>() { i_device });
                var myInfoType = HdlDeviceCommonLogic.Current.GetMyDeviceEnumInfo(new List<CommonDevice>() { i_device });
                if (myInfoType.BeloneType == DeviceBeloneType.A按键面板)
                {
                    return false;
@@ -2702,7 +2932,7 @@
            }
            //如果是新风面板或环境面板,则都不显示任何回路
            var myInfoTypeTemp = LocalDevice.Current.GetMyDeviceEnumInfo(new List<CommonDevice>() { i_device });
            var myInfoTypeTemp = HdlDeviceCommonLogic.Current.GetMyDeviceEnumInfo(new List<CommonDevice>() { i_device });
            if (myInfoTypeTemp.ConcreteType == DeviceConcreteType.ButtonPanel_FangyueFreshAir || myInfoTypeTemp.ConcreteType == DeviceConcreteType.ButtonPanel_SimpleEnvironment)
            {
                return false;
@@ -2940,7 +3170,7 @@
                                {
                                    //重新生成缓存
                                    tempDevice.ReSave();
                                    HdlAutoBackupLogic.AddOrEditorFile(tempDevice.FilePath);
                                    HdlBackupLogic.Current.AddOrEditorAutoBackFileStatu(tempDevice.FilePath);
                                    //全部主页菜单需要刷新
                                    Phone.UserView.UserPage.Instance.RefreshAllForm = true;
                                }
@@ -2992,7 +3222,7 @@
                        {
                            msg += "\r\n[" + HdlGatewayLogic.Current.GetGatewayName(localGw).ToString() + "]";
                        }
                        msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时", false);
                        msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, null, "回复超时", false);
                        this.ShowTipMsg(msg);
                    }
                    statu = -1;
@@ -3081,7 +3311,7 @@
        private bool ReNewDeviceOnTypeIsChanged(CommonDevice oldLocalDevice, DeviceType newDeviceType)
        {
            //先获取本地这个旧设备对象的json
            string oldFile = System.IO.Path.Combine(Config.Instance.FullPath, oldLocalDevice.FilePath);
            string oldFile = System.IO.Path.Combine(Common.Config.Instance.FullPath, oldLocalDevice.FilePath);
            var deviceData = HdlFileLogic.Current.ReadFileTextContent(oldFile);
            if (deviceData == null)
            {
@@ -3097,7 +3327,7 @@
            }
            //删除本地文件
            HdlFileLogic.Current.DeleteFile(oldFile);
            HdlAutoBackupLogic.DeleteFile(oldLocalDevice.FilePath);
            HdlBackupLogic.Current.DeleteAutoBackFileStatu(oldLocalDevice.FilePath);
            //重新生成文件
            if (newDevice.IsCustomizeImage == false)
@@ -3431,7 +3661,7 @@
            }
            this.dicDeviceModelIdEnum = new Dictionary<string, DeviceNameContent>();
            var listText = this.GetDeviceNameFileContent();
            var listText = HdlCommonLogic.Current.GetInitFileContent("DeviceName.ini");
            foreach (var dataText in listText)
            {
                if (dataText == string.Empty || dataText.StartsWith(";") == true)
@@ -3478,63 +3708,279 @@
            this.dicPictrueShard["ButtonPanel_SimpleFour"] = "ButtonPanel_Four";//简约4按键面板 沿用 4按键的图标
            this.dicPictrueShard["ButtonPanel_SimpleThree"] = "ButtonPanel_Three";//简约3按键面板 沿用 3按键的图标
            this.dicPictrueShard["ButtonPanel_SimpleTwo"] = "ButtonPanel_Two";//简约2按键面板 沿用 2按键的图标
            this.dicPictrueShard["IntelligentLocks_Sone"] = "IntelligentLocks_H06C";//S-One Pro的门锁图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_AT1TF"] = "IntelligentLocks_H06C";//全自动智能门锁 AT-1TF图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_AT1F"] = "IntelligentLocks_H06C";//全自动智能门锁 AT-1F图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_AT1T"] = "IntelligentLocks_H06C";//全自动智能门锁 AT-1T图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_HAT1B"] = "IntelligentLocks_H06C";//智能门锁 HAT-1B图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_HAT1T"] = "IntelligentLocks_H06C";//智能门锁 HAT-1T图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_ATFT"] = "IntelligentLocks_H06C";//智能门锁 HAT-1T图片 沿用 H06C的图标
            this.dicPictrueShard["IntelligentLocks_Sone"] = "IntelligentLocks_H06C";//S-one的门锁图片 沿用 H06C的图标
            this.dicPictrueShard["Relay_FangyueFreshAirModul"] = "Relay_ThreeLoad";//方悦新风小模块图片 沿用 3路继电器的图标
            this.dicPictrueShard["ButtonPanel_FourButtonScene"] = "ButtonPanel_Four";//简约4按键场景面板 沿用 4按键面板的图标
        }
        #endregion
        #region ■ 发送数据___________________________
        /// <summary>
        /// 获取设备名字文件的内容
        /// 发送数据到网关,并接受网关返回的数据(非透传,ReceiptData为返回值)
        /// </summary>
        /// <returns></returns>
        private List<string> GetDeviceNameFileContent()
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptTopic">指定接收哪个主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, string receiptTopic, int waitTime = 5)
        {
            System.IO.StreamReader streamReader = null;
            var listText = new List<string>();
            try
            {
#if iOS
                string textFile = Foundation.NSBundle.MainBundle.PathForResource("DeviceName.ini", null);
                streamReader = new System.IO.StreamReader(textFile, Encoding.UTF8);
                string text;
                while ((text = streamReader.ReadLine()) != null)
                {
                    listText.Add(text.Trim());
            //发送数据到网关,并接受网关返回的数据
            return this.SendJobjectDataToGateway(device, sendTopic, sendData, new List<string>() { receiptTopic }, waitTime);
                }
                return listText;
#endif
#if Android
                var stream = Application.Activity.Assets.Open("DeviceName.ini");
                streamReader = new System.IO.StreamReader(stream, Encoding.UTF8);
                string text;
                while ((text = streamReader.ReadLine()) != null)
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(非透传),listReceiptData为返回值(全部主题全部接收得到,才会返回,不然会返回超时)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="listReceiptTopic">指定接收哪些主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, List<string> listReceiptTopic, int waitTime = 5)
                {
                    listText.Add(text.Trim());
            var reResult = new ReceiptGatewayResult();
            reResult.listReceiptData = new string[listReceiptTopic.Count];
            reResult.JsonData = new string[listReceiptTopic.Count];
            var myGateway = device.Gateway;
            if (myGateway == null)
            {
                //获取网关对象失败
                reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
                reResult.ErrorMsgDiv = -1;
                return reResult;
                }
                stream.Close();
                return listText;
#endif
            //网关ID
            string gatewayID = device.Gateway.GwId;
            //错误主题
            string errorTopic = gatewayID + "/" + "Error_Respon";
            //检测对象的主题
            for (int i = 0; i < listReceiptTopic.Count; i++)
            {
                listReceiptTopic[i] = gatewayID + "/" + listReceiptTopic[i];
            }
            catch
            //蓝才刚整了个同一个主题可能会推送多个过来的机能
            var listCheckTopic = new HashSet<string>();
            Action<string, string> receiptAction = (topic, message) =>
            {
                return listText;
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                    reResult.ErrorMsg = HdlCheckLogic.Current.CheckGatewayErrorCode(temp.Error);
            }
            finally
                //如果是指定的主题
                for (int i = 0; i < listReceiptTopic.Count; i++)
            {
                try
                    if (topic == listReceiptTopic[i])
                {
                    streamReader?.Close();
                        if (listCheckTopic.Contains(topic) == true)
                        {
                            //这里写这个东西是有点用处的
                            continue;
                }
                catch
                        string deviceMac = jobject["DeviceAddr"].ToString();
                        int deviceEpoint = 200;
                        if (jobject.Property("Epoint") != null)
                {
                            //拥有此键值
                            deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
                        }
                        if (device.DeviceAddr != deviceMac)
                        {
                            //不是同一个东西Mac
                            return;
                        }
                        if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
                        {
                            //不是同一个东西,这里应该需要特殊处理200端点
                            return;
                        }
                        reResult.listReceiptData[i] = jobject["Data"].ToString();
                        if (jobject.Property("Time") != null)
                        {
                            //需要移除time这个字段
                            jobject.Remove("Time");
                        }
                        reResult.JsonData[i] = jobject.ToString();
                        if (listCheckTopic.Contains(topic) == false)
                        {
                            //加到检测主题对象中
                            listCheckTopic.Add(topic);
                }
            }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send(sendTopic, sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (listCheckTopic.Count != listReceiptTopic.Count && TimeOut < waitTime)
            {
                //全部接收才退出
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            int receveCount = listCheckTopic.Count;
            if (receveCount > 1)
            {
                //看看里面有没有重复的
                var listTemp = new HashSet<string>();
                foreach (var value in listCheckTopic)
                {
                    if (listTemp.Contains(value) == false)
                    {
                        listTemp.Add(value);
                    }
                }
                receveCount = listTemp.Count;
            }
            if (receveCount != listReceiptTopic.Count)
            {
                reResult.ErrorMsgDiv = 0;
            }
            else
            {
                //正常接收到网关返回的数据
                if (reResult.listReceiptData.Length == 1)
                {
                    //如果只有一个主题,则替换变量
                    reResult.ReceiptData = reResult.listReceiptData[0];
                }
            }
            return reResult;
        }
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(透传专用)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptCommand">指定接收命令符</param>
        /// <param name="receiptDataLength">指定接收数据的长度</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <param name="listReceiptLength">附加检测数据接收长度,当接收的长度在这列表里面时,代表接收成功(旨在对应新旧设备,透传回复的长度可能不同)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway2(CommonDevice device, string sendData, string receiptCommand, int receiptDataLength,
            int waitTime = 5, List<int> listReceiptLength = null)
        {
            var reResult = new ReceiptGatewayResult();
            var myGateway = device.Gateway;
            if (myGateway == null)
            {
                //获取网关对象失败
                reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
                reResult.ErrorMsgDiv = -1;
                return reResult;
            }
            //网关ID
            string gatewayID = device.Gateway.GwId;
            //错误主题
            string errorTopic = gatewayID + "/" + "Error_Respon";
            //检测对象的主题
            string checkTopic = gatewayID + "/ZbDataPassthrough";
            Action<string, string> receiptAction = (topic, message) =>
            {
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                    reResult.ErrorMsg = HdlCheckLogic.Current.CheckGatewayErrorCode(temp.Error);
                }
                //如果是指定的主题
                if (topic == checkTopic)
                {
                    string deviceMac = jobject["DeviceAddr"].ToString();
                    int deviceEpoint = 200;
                    if (jobject.Property("Epoint") != null)
                    {
                        //拥有此键值
                        deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
                    }
                    if (device.DeviceAddr != deviceMac)
                    {
                        //不是同一个东西Mac
                        return;
                    }
                    if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
                    {
                        //不是同一个东西,这里应该需要特殊处理200端点
                        return;
                    }
                    var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                    //长度不一致
                    if (responseData.PassData.Length != receiptDataLength)
                    {
                        if (listReceiptLength == null)
                        {
                            //如果没有附加检测长度,则直接返回
                            return;
                        }
                        if (listReceiptLength.Contains(responseData.PassData.Length) == false)
                        {
                            //如果附加的检测长度里面,还不存在的话,直接返回
                            return;
                        }
                    }
                    var command = responseData.PassData[4].ToString()
                        + responseData.PassData[5].ToString()
                        + responseData.PassData[2].ToString()
                        + responseData.PassData[3].ToString();
                    //并且是这个命令
                    if (command == receiptCommand)
                    {
                        reResult.ReceiptData = responseData.PassData;
                        reResult.JsonData = new string[1];
                        if (jobject.Property("Time") != null)
                        {
                            //需要移除time这个字段
                            jobject.Remove("Time");
                        }
                        reResult.JsonData[0] = jobject.ToString();
                    }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send("ClientDataPassthrough", sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (reResult.ReceiptData == null && TimeOut < waitTime)
            {
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            if (reResult.ReceiptData == null)
            {
                //超时
                reResult.ErrorMsgDiv = 0;
            }
            return reResult;
        }
        #endregion
@@ -3759,33 +4205,9 @@
        /// </summary>
        IntelligentLocks_H06C = 2800,
        /// <summary>
        /// S-One Pro
        /// S-one
        /// </summary>
        IntelligentLocks_Sone = 2802,
        /// <summary>
        /// AT-1TF
        /// </summary>
        IntelligentLocks_AT1TF = 2803,
        /// <summary>
        /// AT-1F
        /// </summary>
        IntelligentLocks_AT1F = 2804,
        /// <summary>
        /// AT-1T
        /// </summary>
        IntelligentLocks_AT1T = 2805,
        /// <summary>
        /// HAT-1B
        /// </summary>
        IntelligentLocks_HAT1B = 2806,
        /// <summary>
        /// HAT-1T
        /// </summary>
        IntelligentLocks_HAT1T = 2807,
        /// <summary>
        /// AT-FT
        /// </summary>
        IntelligentLocks_ATFT = 2808,
        //=========★★彩灯类(????-????)★★=========
        /// <summary>
@@ -3840,18 +4262,6 @@
        /// zigbee转buspro协议转换器
        /// </summary>
        Converter_ZbBuspro = 4201,
        //=========★★晾衣架类(5000-5199)★★=========
        /// <summary>
        /// 晾衣架
        /// </summary>
        Airer = 5000,
        //=========★★空气质量传感器类(5200-5399)★★=========
        /// <summary>
        /// 空气质量传感器
        /// </summary>
        AirQualitySensor = 5200,
        //=========★★其他类(????-????)★★=========
        /// <summary>
@@ -3929,14 +4339,6 @@
        /// 转换器(4200-4699)
        /// </summary>
        A转换器 = 4200,
        /// <summary>
        /// 晾衣架(4200-4699)
        /// </summary>
        A晾衣架 = 5000,
        /// <summary>
        /// 空气质量传感器(5200-5399)
        /// </summary>
        A空气质量 = 5200,
        /// <summary>
        /// 彩灯
        /// </summary>