CrabtreeOn,印度客户定制APP,迁移2.0平台版本
陈嘉乐
2021-02-05 502d4ff743c1645adb469ab89c24826c4ec38f28
Crabtree/SmartHome/HDL/Common/HDLLinkUtlis.cs
@@ -1,372 +1,2168 @@
//using System;
//using System.Collections.Generic;
//using Shared;
using System;
using System.Collections.Generic;
using Shared;
using Shared.IO;
//namespace SmartHome
//{
//    /// <summary>
//    /// HDLLink协议 工具类
//    /// </summary>
//    public class HDLLinkUtlis
//    {
//        #region ■ Current___________________________
//        /// <summary>
//        /// 通用方法
//        /// </summary>
//        private static HDLLinkUtlis m_Current = null;
//        /// <summary>
//        /// 通用方法
//        /// </summary>
//        public static HDLLinkUtlis Current {
//            get {
//                if (m_Current == null) {
//                    m_Current = new HDLLinkUtlis ();
//                }
//                return m_Current;
//            }
//        }
//        #endregion
//        /// <summary>
//        /// 将在线设备转换成sid + 属性列表
//        /// </summary>
//        /// <param name="onlineDevices"></param>
//        /// <returns></returns>
//        public List<Sid> ConvertToSidListToIotCloud (string sOid, Common onlineDevice)
//        {
//            List<Sid> tmpResult = new List<Sid> ();
//            try {
//                if (onlineDevice.bytSimpleParam == null || onlineDevice.bytSimpleParam.Length == 0) {
//                    string sSimpleList = DeviceTypeList.GetSimpleFunctionListFromPublicModeGroup (onlineDevice.DeviceType);
//                    #region
//                    string [] ArayStr = sSimpleList.Trim ().Split (new char [] { ' ' });
//                    List<byte> ArayTmp = new List<byte> ();
//                    for (int i = 0; i < ArayStr.Length; i++) {
//                        if (ArayStr [i] != null && ArayStr [i] != "" && ArayStr [i].Trim () != "") {
//                            ArayTmp.Add (Convert.ToByte (ArayStr [i], 16));
//                        }
//                    }
//                    onlineDevice.bytSimpleParam = ArayTmp.ToArray ();
//                    #endregion
//                }
//                if (onlineDevice.bytSimpleParam != null && onlineDevice.bytSimpleParam.Length > 0) {
//                    for (int intI = 0; intI < onlineDevice.bytSimpleParam.Length / 3; intI++) {
//                        Byte BigType = onlineDevice.bytSimpleParam [0 + intI * 3];
//                        Byte SmallType = onlineDevice.bytSimpleParam [1 + intI * 3];
//                        int Count = onlineDevice.bytSimpleParam [2 + intI * 3];
//                        if (Count > 0) {
//                            for (int j = 1; j <= Count; j++) {
//                                Sid tmpSid = new Sid ();
//                                tmpSid.sid = HDLSysPF.FormingNewSid (onlineDevice.DeviceType, sOid, j, false, BigType, SmallType);
//                                tmpSid.oid = sOid;
//                                try {
//                                    tmpSid.name = onlineDevice.myEasyDesignChannelRemark [intI] [j - 1];
//                                } catch (Exception ex) {
//                                    tmpSid.name = "";
//                                }
//                                if (tmpSid.name == null || tmpSid.name == "" || tmpSid.name == "Unread") {
//                                    tmpSid.name = onlineDevice.Remark + CsConst.mstrINIDefault.IniReadValue ("public", "00000", "") + " " + j.Tostring ();
//                                    if (onlineDevice.Remark == "") {
//                                        tmpSid.name = onlineDevice.strDescription + CsConst.mstrINIDefault.IniReadValue ("public", "00000", "") + " " + j.Tostring ();
//                                    }
//                                }
//                                GateWay.sidObject tmp = HDLSysPF.UpdateSidAttributesToDeviceList (onlineDevice, tmpSid.name, sOid, j, BigType, SmallType, true);
//                                tmpSid.attributes = tmp.attributes;//UpdateSidAttributesToDeviceList(onlineDevice.DeviceType, sOid, j, BigType, SmallType, ref spk);
//                                tmpSid.spk = tmp.spk;
//                                tmpResult.Add (tmpSid);
//                            }
//                        }
//                    }
//                }
//                return tmpResult;
//            } catch (Exception) {
//                return tmpResult;
//                //throw;
//            }
//        }
//        /// <summary>
//        ///
//        /// </summary>
//        /// <param name="homeId"></param>
//        /// <param name="onlineDevices"></param>
//        /// <param name="gatewayId"></param>
//        /// <param name="currentProject"></param>
//        public void ConvertOidListToIotStruct (string homeId, List<Common> onlineDevices, string gatewayId, ref IotCloud currentProject)
//        {
//            try {
//                //step 1 ;抓换类型
//                Sids functionList = currentProject.functions;
//                List<Sid> tmpFunction = new List<Sid> ();
//                //step 2 转换类型
//                Oids tmp = ConvertToOidListToIotCloud (onlineDevices, ref tmpFunction);
//                if (currentProject.modules == null || currentProject.modules.devices == null || currentProject.modules.devices.Count == 0) currentProject.modules = tmp;
//                else {
//                    foreach (Oid tmpModule in tmp.devices) {
//                        Oid tmpFind = currentProject.modules.devices.Find (P => P.mac.Equals (tmpModule.mac));
//                        if (tmpFind == null) currentProject.modules.devices.Add (tmpModule);
//                    }
//                }
//                tmp.homeId = homeId;
//                //上传功能列表
//                #region
//                //if (functionList == null)
//                //{
//                functionList = new Sids ();
//                functionList.devices = new List<Sid> ();
//                functionList.devices = tmpFunction;
//                //}
//                functionList.homeId = homeId;
//                functionList.gatewayId = gatewayId;
//                currentProject.modules = tmp;
//                currentProject.functions = functionList;
//                #endregion
//            } catch (Exception ex) {
//                //MessageBox.Show (ex.Tostring ());
//                //throw;
//            }
//        }
//        /// <summary>
//        ///
//        /// </summary>
//        /// <param name="homeId"></param>
//        /// <param name="onlineDevices"></param>
//        /// <param name="gatewayId"></param>
//        /// <param name="currentProject"></param>
//        public void ConvertOidListToIotStruct (string homeId, List<Common> onlineDevices, string gatewayId, ref IotCloud currentProject)
//        {
//            try {
//                //step 1 转换类型
//                Sids functionList = currentProject.functions;
//                List<Sid> tmpFunction = new List<Sid> ();
//                //step 2 转换类型
//                Oids tmp = ConvertToOidListToIotCloud (onlineDevices, ref tmpFunction);
//                if (currentProject.modules == null || currentProject.modules.devices == null || currentProject.modules.devices.Count == 0) currentProject.modules = tmp;
//                else {
//                    foreach (Oid tmpModule in tmp.devices) {
//                        Oid tmpFind = currentProject.modules.devices.Find (P => P.mac.Equals (tmpModule.mac));
//                        if (tmpFind == null) currentProject.modules.devices.Add (tmpModule);
//                    }
//                }
//                tmp.homeId = homeId;
//                //上传功能列表
//                #region
//                //if (functionList == null)
//                //{
//                functionList = new Sids ();
//                functionList.devices = new List<Sid> ();
//                functionList.devices = tmpFunction;
//                //}
//                functionList.homeId = homeId;
//                functionList.gatewayId = gatewayId;
//                currentProject.modules = tmp;
//                currentProject.functions = functionList;
//                #endregion
//            } catch (Exception ex) {
//                //MessageBox.Show (ex.Tostring ());
//                //throw;
//            }
//        }
//        /// <summary>
//        /// 生成设备Oid
//        /// </summary>
//        /// <param name="iDeviceType"></param>
//        /// <returns></returns>
//        public string FormingNewOid (int iDeviceType)
//        {
//            string sOid = "";
//            try {
//                string sOidBeginsWith = "000101";//厂商 + 通讯方式
//                long sTimeSp = HDLSysPF.ConvertDateTimeLong ();
//                string sTimeSpan = "";
//                GateWay.ConvertIntToByteArray (sTimeSp, ref sTimeSpan);
//                if (sTimeSpan.Length != 8) return sOid;
//                HDLUDP.TimeBetwnNext (10);
//                sOid = sOidBeginsWith + sTimeSpan;
//                if (iDeviceType == 00
//                    || DimmerDeviceTypeList.HDLDimmerDeviceTypeList.Contains (iDeviceType)
//                 || DMXDeviceTypeList.HDLDMXDeviceTypeList.Contains (iDeviceType))//调光器 20200730类
//                {
//                    sOid += "01";
//                } else if (RelayDeviceTypeList.HDLRelayDeviceTypeList.Contains (iDeviceType))//继电器类
//                  {
//                    sOid += "02";
//                } else if (CurtainDeviceType.HDLCurtainModuleDeviceType.Contains (iDeviceType))//遮阳类(窗帘)
//                  {
//                    sOid += "03";
//                } else if (HVACModuleDeviceTypeList.HDLHVACModuleDeviceTypeLists.Contains (iDeviceType) || FloorheatingDeviceTypeList.HDLFloorHeatingDeviceType.Contains (iDeviceType))//恒温器(空调)
//                  {
//                    sOid += "12";
//                } else if (AudioDeviceTypeList.AudioBoxDeviceTypeList.Contains (iDeviceType)) {
//                    sOid += "10";
//                } else if (Eightin1DeviceTypeList.HDL8in1DeviceType.Contains (iDeviceType)
//                      || Sevenin1DeviceTypeList.HDL7in1DeviceType.Contains (iDeviceType)
//                      || Twelvein1DeviceTypeList.HDL12in1DeviceType.Contains (iDeviceType))//传感器类
//                  {
//                    sOid += "04";
//                } else {
//                    sOid += "07"; //网关产品
//                }
namespace Shared
{
    /// <summary>
    /// HDLLink协议 工具类
    /// </summary>
    public class HDLLinkUtlis
    {
        #region ■ Current___________________________
        /// <summary>
        /// 通用方法
        /// </summary>
        private static HDLLinkUtlis m_Current = null;
        /// <summary>
        /// 通用方法
        /// </summary>
        public static HDLLinkUtlis Current {
            get {
                if (m_Current == null) {
                    m_Current = new HDLLinkUtlis ();
                }
                return m_Current;
            }
        }
        #endregion
//                return sOid;
//            } catch {
//                return sOid;
//            }
//        }
//        /// <summary>
//        /// 生成功能设备Sid
//        /// </summary>
//        /// <param name="iDeviceType"></param>
//        /// <param name="sOid"></param>
//        /// <param name="iChnId"></param>
//        /// <param name="isUseE548ReturnBigSmallType"></param>
//        /// <param name="BigType"></param>
//        /// <param name="SmallType"></param>
//        /// <returns></returns>
//        public string FormingNewSid (int iDeviceType, string sOid, int iChnId, bool isUseE548ReturnBigSmallType, byte BigType, byte SmallType)
//        {
//            if (sOid == null || sOid == "") return "";
//            try {
//                string sSid = "";
//                if (DimmerDeviceTypeList.HDLDimmerDeviceTypeList.Contains (iDeviceType)) {
//                    if (DimmerDeviceTypeList.DALIDimmerDeviceTypeLists.Contains (iDeviceType)) {
//                        BigType = 1;
//                        SmallType = 7;
//                        sSid += "0203";
//                    } else {
//                        sSid += "0202";
//                    }
//                } else if (RelayDeviceTypeList.HDLRelayDeviceTypeList.Contains (iDeviceType)) {
//                    sSid += "0201";
//                } else if (CurtainDeviceType.HDLCurtainModuleDeviceType.Contains (iDeviceType)) {
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public bool UploadOidAndSidList ()
        {
            var res = false;
            try {
                IotCloud currentProject = new IotCloud ();
                var list = GetAllDeviceList ();
                ConvertOidListToIotStruct (UserConfig.Instance.CurrentRegion.Id, UserConfig.Instance.HomeGateway.gatewayId, list, ref currentProject);
                Utlis.WriteLine ("list: " + list.Count + "currentProject : " + currentProject.functions.devices.Count);
//                    if (CurtainDeviceType.NormalMotorCurtainDeviceType.Contains (iDeviceType) || (iDeviceType == 9700)) //所有开合帘 //0 2020 05 24创明开合帘
//                    {
//                        sSid += "0303";
//                    } else if (CurtainDeviceType.RollerCurtainDeviceType.Contains (iDeviceType)
//                      || (iDeviceType == 9701))//所有 卷帘控制器
//                      {
//                        sSid += "0304";
//                    } else {
//                        sSid += "0301";
//                    }
//                } else if (HVACModuleDeviceTypeList.HDLHVACModuleDeviceTypeLists.Contains (iDeviceType)) {
//                    sSid += "0401";
//                } else if (Eightin1DeviceTypeList.HDL8in1DeviceType.Contains (iDeviceType)
//                      || Sevenin1DeviceTypeList.HDL7in1DeviceType.Contains (iDeviceType)
//                      || HaikeSensorDeviceTypeList.HaikeSensorDeviceType.Contains (iDeviceType)
//                      || Twelvein1DeviceTypeList.HDL12in1DeviceType.Contains (iDeviceType)
//                      || Rs232DeviceTypeList.HDLRs232DeviceType.Contains (iDeviceType)) {
//                    if (BigType == 19 && SmallType == 0) {
//                        sSid += "1301";
//                    } else if (BigType == 5 && SmallType == 0) {
//                        sSid += "0519";
//                    } else {
//                        sSid += BigType.Tostring ("X2") + SmallType.Tostring ("X2");
//                    }
//                } else if (FloorheatingDeviceTypeList.HDLFloorHeatingDeviceType.Contains (iDeviceType)) {
//                    sSid += "0402";
//                } else if (DMXDeviceTypeList.HDLDMXDeviceTypeList.Contains (iDeviceType)) {
//                    sSid += "0204";
//                } else if (DimmerDeviceTypeList.DALIDimmerDeviceTypeLists.Contains (iDeviceType)) {
//                    sSid += "0203";
//                } else if (AudioDeviceTypeList.AudioBoxDeviceTypeList.Contains (iDeviceType)) {
//                    sSid += "0901";
//                }
//                string sTmpWithE548 = sSid;
//                sSid = sOid + sSid + iChnId.Tostring ("X4");
//                if (isUseE548ReturnBigSmallType) {
//                    sSid += BigType.Tostring ("X2") + SmallType.Tostring ("X2");
//                } else {
//                    sSid += sTmpWithE548;
//                }
                var revertObj = HttpServerRequest.Current.UploadDeviceOidList (currentProject.modules);
                if(revertObj.Code == StateCode.SUCCESS) {
                    var revertObj2 = HttpServerRequest.Current.UploadDeviceSidList (currentProject.functions);
                    if (revertObj2.Code == StateCode.SUCCESS) {
                        res = true;
                    } else {
                        IMessageCommon.Current.ShowErrorInfoAlter (revertObj2.Code);
                    }
                } else {
                    IMessageCommon.Current.ShowErrorInfoAlter (revertObj.Code);
                }
            } catch {
//                return sSid;
//            } catch {
//                return "";
//            }
//        }
            }
            return res;
        }
//    }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public List<Common> GetAllDeviceList ()
        {
            List<Common> TargetList = new List<Common> ();
            //找出需要显示的设备
            var filesList = FileUtils.ReadFiles ().FindAll ((obj) => {
                string [] str = obj.Split ('_');
                return obj.StartsWith ("Equipment_") && str.Length == 5;
            });
            var localEquipments = filesList.FindAll ((obj) => {
                string typeString = obj.Split ('_') [1];
                return (
                #region light
                    typeString.ToString () == DeviceType.LightCCT.ToString () ||
                typeString.ToString () == DeviceType.LightRGB.ToString () ||
                typeString.ToString () == DeviceType.LightDALI.ToString () ||
                typeString.ToString () == DeviceType.LightRGBW.ToString () ||
                typeString.ToString () == DeviceType.LightLogic.ToString () ||
                typeString.ToString () == DeviceType.LightSwitch.ToString () ||
                typeString.ToString () == DeviceType.LightDimming.ToString () ||
                typeString.ToString () == DeviceType.LightMixSwitch.ToString () ||
                typeString.ToString () == DeviceType.LightRGBandCCT.ToString () ||
                typeString.ToString () == DeviceType.LightMixDimming.ToString () ||
                typeString.ToString () == DeviceType.LightEnergySwitch.ToString () ||
                typeString.ToString () == DeviceType.LightEnergySocket.ToString () ||
                typeString.ToString () == DeviceType.LightSwitchSocket.ToString ()
                || typeString.ToString () == DeviceType.DMX48.ToString ()
                #endregion
                #region light
                    || typeString.ToString () == DeviceType.SensorCH4.ToString () ||
                typeString.ToString () == DeviceType.SensorCO2.ToString () ||
                typeString.ToString () == DeviceType.SensorLPG.ToString () ||
                typeString.ToString () == DeviceType.SensorCOH2.ToString () ||
                typeString.ToString () == DeviceType.SensorPM25.ToString () ||
                typeString.ToString () == DeviceType.SensorTVOC.ToString () ||
                typeString.ToString () == DeviceType.SensorPower.ToString () ||
                typeString.ToString () == DeviceType.SensorSmoke.ToString () ||
                typeString.ToString () == DeviceType.SensorWater.ToString () ||
                typeString.ToString () == DeviceType.SensorWeight.ToString () ||
                typeString.ToString () == DeviceType.SensorCurrent.ToString () ||
                typeString.ToString () == DeviceType.SensorVoltage.ToString ()
                || typeString.ToString () == DeviceType.SensorRainfall.ToString ()
                || typeString.ToString () == DeviceType.SensorVelocity.ToString ()
                || typeString.ToString () == DeviceType.SensorMenciAndwindowMagnetic.ToString ()
                || typeString.ToString () == DeviceType.SensorMobileDetection.ToString ()
                || typeString.ToString () == DeviceType.SensorLiquidPressure.ToString ()
                || typeString.ToString () == DeviceType.SensorVibration.ToString ()
                || typeString.ToString () == DeviceType.SensorLiquidFlow.ToString ()
                || typeString.ToString () == DeviceType.SensorLiquidDepth.ToString ()
                || typeString.ToString () == DeviceType.SensorTemperature.ToString ()
                || typeString.ToString () == DeviceType.SensorHeightLength.ToString ()
                || typeString.ToString () == DeviceType.SensorIllumination.ToString ()
                || typeString.ToString () == DeviceType.SensorWindPressure.ToString ()
                || typeString.ToString () == DeviceType.SensorHumidity.ToString ()
                #endregion
                #region curtain
                    || typeString.ToString () == DeviceType.CurtainModel.ToString ()
                || typeString.ToString () == DeviceType.CurtainRoller.ToString ()
                || typeString.ToString () == DeviceType.CurtainTrietex.ToString ()
                #endregion
                #region ac
                    || typeString.ToString () == DeviceType.ACPanel.ToString ()
                || typeString.ToString () == DeviceType.ACDevice.ToString ()
                || typeString.ToString () == DeviceType.ACInfrared.ToString ()
                || typeString.ToString () == DeviceType.ACCoolmaster.ToString ()
                || typeString.ToString () == DeviceType.CustomAC.ToString ()
                || typeString.ToString () == DeviceType.HVAC.ToString ()
                #endregion
                #region foolheat
                    || typeString.ToString () == DeviceType.FoolHeat.ToString ()
                || typeString.ToString () == DeviceType.FoolHeatPanel.ToString ()
                #endregion
                #region
                    || typeString.ToString () == DeviceType.InfraredMode.ToString ()
                || typeString.ToString () == DeviceType.DoorLock.ToString ()
                || typeString.ToString () == DeviceType.FanModule.ToString ()
                || typeString.ToString () == DeviceType.FreshAir.ToString ()
                || typeString.ToString () == DeviceType.InfraredTV.ToString ()
                || typeString.ToString () == DeviceType.UniversalDevice.ToString ()
                || typeString.ToString () == DeviceType.MusicModel.ToString ()
                || typeString.ToString () == DeviceType.SecurityModule.ToString ()
                || typeString.ToString () == DeviceType.LogicModule.ToString ()
                || typeString.ToString () == DeviceType.SecurityPanel.ToString ()
                #endregion
                    );
            });
            foreach (string deviceFilePath in localEquipments) {
                try {
                    string [] str = deviceFilePath.Split ('_');
                    var commonBytes = FileUtils.ReadFile (deviceFilePath);
                    if (commonBytes.Length == 0) {
                        Utlis.WriteLine ("length loss");
                        continue;
                    }
                    if (commonBytes.Length == 1) {
                        Utlis.WriteLine ("length loss 1");
                        continue;
                    }
                    Common commonDevice = Newtonsoft.Json.JsonConvert.DeserializeObject<Common> (System.Text.Encoding.UTF8.GetString (commonBytes));
                    if (commonDevice == null) {
                        continue;
                    }
                    TargetList.Add (commonDevice);
                } catch {
                }
            }
            return TargetList;
        }
//    [Serializable]
//    public class Sids : BaseCloudFeedback
//    {
//        public string homeId { get; set; }
//        public string gatewayId { get; set; }
//        public List<Sid> devices { get; set; }
//    }
        /// <summary>
        /// 将在线设备转换成sid + 属性列表
        /// </summary>
        /// <param name="moduleCommon">模块设备</param>
        /// <returns></returns>
        public List<Sid> ConvertToSidListToIotCloud (string sOid, Common loopCommon)
        {
            List<Sid> sidList = new List<Sid> ();
            try {
                Sid tmpSid = new Sid ();
                tmpSid.sid = FormingNewSid (sOid, loopCommon);
                tmpSid.oid = sOid;
                tmpSid.name = loopCommon.Name;
//    [Serializable]
//    public class BaseCloudFeedback
//    {
//        public int code { get; set; }
//        public string timestamp { get; set; }
//        public bool isSuccess { get; set; }
//        public string message { get; set; }
//    }
                SidObject tmp = UpdateSidAttributesToDeviceList (loopCommon, sOid);
                tmpSid.attributes = tmp.attributes;
                //UpdateSidAttributesToDeviceList(onlineDevice.DeviceType, sOid, j, BigType, SmallType, ref spk);
                tmpSid.spk = tmp.spk;
                sidList.Add (tmpSid);
                return sidList;
            } catch (Exception) {
                return sidList;
            }
        }
        /// <summary>
        /// 处理本地数据,转换生成Oid和Sid列表
        /// </summary>
        /// <param name="homeId"></param>
        /// <param name="onlineDevices"></param>
        /// <param name="gatewayId"></param>
        /// <param name="currentProject"></param>
        public void ConvertOidListToIotStruct (string homeId, string gatewayId, List<Common> loopCommonList, ref IotCloud currentProject)
        {
            try {
                //step 1 转换类型
                Sids functionList = new Sids();
                List<Sid> tmpFunction = new List<Sid> ();
                //step 2 转换生成Oids列表和sid 设备列表
                Oids mOidList = ConvertToOidListToIotCloud (loopCommonList, ref tmpFunction);
                mOidList.homeId = homeId;
                //step 3
                functionList.devices = new List<Sid> ();
                functionList.homeId = homeId;
                functionList.gatewayId = gatewayId;
                if (tmpFunction != null) {
                    functionList.devices = tmpFunction;
                }
                currentProject.modules = mOidList;
                currentProject.functions = functionList;
            } catch (Exception ex) {
                //MessageBox.Show (ex.Tostring ());
                //throw;
            }
        }
        /// <summary>
        /// 转换类型在线设备列表转OID列表 只在上传或者下载时使用
        /// </summary>
        /// <param name="onlineDevices"></param>
        /// <returns></returns>
        public Oids ConvertToOidListToIotCloud (List<Common> loopCommonListlolooloopl, ref List<Sid> functionLists)
        {
            Oids mOidsList = new Oids ();
            try {
                mOidsList.devices = new List<Oid> ();
                //HDLSysPF.IniDeviceChannelRemark (); //整理全部设备备注到缓存列表
                foreach (Common tmp in loopCommonListlolooloopl) {
                    //1.deviceType标识 云端是int类型
                    var deviceType = ((int)tmp.Type);
                    //2.addresses标识 子网号、设备号
                    var addresses = string.Format ("{0}{1}", tmp.SubnetID.ToString ("X2"), tmp.DeviceID.ToString ("X2"));
                    //3.判断当前回路设备之前是否生成过相同模块的oid,存在则取之前的oid 没有则创建新增新的oid
                    var deviceOid = mOidsList.devices.Find (o => o.deviceType == deviceType && o.addresses == addresses);
                    if (deviceOid == null) {
                        //3.1没有则创建新增新的oid
                        Oid tmpOid = new Oid ();
                        tmpOid.protocolType = "bus";
                        tmpOid.device_name = tmp.Type.ToString ();
                        tmpOid.oid = FormingNewOid (tmp.Type);
                        tmpOid.addresses = addresses;
                        tmpOid.device_model = tmp.Type.ToString ();
                        tmpOid.fw_version = "";
                        tmpOid.deviceType = deviceType;
                        tmpOid.hw_info = "";
                        tmpOid.mac = tmp.MAC;
                        mOidsList.devices.Add (tmpOid);
                        functionLists.AddRange (ConvertToSidListToIotCloud (tmpOid.oid, tmp));
                        Utlis.WriteLine ("新的模块,新的的OID:" + tmpOid.addresses + " deviceType:" + tmpOid.deviceType);
                    } else {
                        //3.2存在则取之前的oid
                        functionLists.AddRange (ConvertToSidListToIotCloud (deviceOid.oid, tmp));
                        Utlis.WriteLine ("相同的模块,取之前的OID:" + deviceOid.addresses + " deviceType:" + deviceOid.deviceType);
                    }
                }
                return mOidsList;
            } catch (Exception ex) {
                return mOidsList;
            }
        }
        ///// <summary>
        /////
        ///// </summary>
        ///// <param name="homeId"></param>
        ///// <param name="onlineDevices"></param>
        ///// <param name="gatewayId"></param>
        ///// <param name="currentProject"></param>
        //public void ConvertOidListToIotStruct (string homeId, List<Common> onlineDevices, string gatewayId, ref IotCloud currentProject)
        //{
        //    try {
        //        //step 1 转换类型
        //        Sids functionList = currentProject.functions;
        //        List<Sid> tmpFunction = new List<Sid> ();
        //        //step 2 转换类型
        //        Oids tmp = ConvertToOidListToIotCloud (onlineDevices, ref tmpFunction);
        //        if (currentProject.modules == null || currentProject.modules.devices == null || currentProject.modules.devices.Count == 0) currentProject.modules = tmp;
        //        else {
        //            foreach (Oid tmpModule in tmp.devices) {
        //                Oid tmpFind = currentProject.modules.devices.Find (P => P.mac.Equals (tmpModule.mac));
        //                if (tmpFind == null) currentProject.modules.devices.Add (tmpModule);
        //            }
        //        }
        //        tmp.homeId = homeId;
        //        //上传功能列表
        //        #region
        //        //if (functionList == null)
        //        //{
        //        functionList = new Sids ();
        //        functionList.devices = new List<Sid> ();
        //        functionList.devices = tmpFunction;
        //        //}
        //        functionList.homeId = homeId;
        //        functionList.gatewayId = gatewayId;
        //        currentProject.modules = tmp;
        //        currentProject.functions = functionList;
        //        #endregion
        //    } catch (Exception ex) {
        //        //MessageBox.Show (ex.Tostring ());
        //        //throw;
        //    }
        //}
        /// <summary>
        /// 生成设备Oid
        /// </summary>
        /// <param name="iDeviceType"></param>
        /// <returns></returns>
        public string FormingNewOid (DeviceType deviceType)
        {
            string sOid = "";
            try {
                //1.生成 厂商 + 通讯方式
                string sOidBeginsWith = "000101";//厂商 + 通讯方式
                //2.生成产品时间戳
                long sTimeSp = ConvertDateTimeLong (); //以2020年1月1日算出的时间戳0.1s为单位
                string sTimeSpan = "";
                ConvertIntToByteArray (sTimeSp, ref sTimeSpan);
                if (sTimeSpan.Length != 8) return sOid;
                //延迟10ms
                //3.生成产品类别
                var productType = GetProductType (deviceType);
                sOid = sOidBeginsWith + sTimeSpan + productType;
                return sOid;
            } catch {
                return sOid;
            }
        }
        /// <summary>
        /// 获取产品类别
        /// 产品类别目前没有规范的文档,没有确定的标准
        /// 暂时和buspro软件规则一致
        ///
        ///文档规则,但是不是正确的版本
        //产品类别 1byte
        //编号   描述
        //01   调光器
        //02   继电器
        //03   干接点模块
        //04   传感器
        //05   面板
        //06   RCU
        //07   网关
        //08   红外发射
        //09   Android屏
        //10   场景
        //11   音乐播放器
        //12   232/485转换器
        //21   自动化
        //22   安防防区
        //14   窗帘模块
        //15   HVAC
        //16   地热模块
        /// </summary>
        /// <param name="deviceType"></param>
        /// <returns></returns>
        public string GetProductType (DeviceType deviceType)
        {
            string productType = "";
            switch (deviceType) {
            case DeviceType.LightDimming:
            case DeviceType.LightCCT:
            case DeviceType.LightDALI:
            case DeviceType.LightRGB:
            case DeviceType.LightRGBW:
            case DeviceType.LightLogic:
            case DeviceType.LightRGBandCCT:
            case DeviceType.DMX48:
                productType = "01";//01   调光器
                break;
            case DeviceType.LightSwitch:
            case DeviceType.LightEnergySwitch:
            case DeviceType.LightEnergySocket:
            case DeviceType.LightSwitchSocket:
            case DeviceType.LightMixSwitch:
                productType = "02";//02 继电器类
                break;
            case DeviceType.CurtainModel:
            case DeviceType.CurtainRoller:
            case DeviceType.CurtainTrietex:
                productType = "03";//03   遮阳类(窗帘)
                break;
            case DeviceType.SensorWindSpeed:
                productType = "04";//04   传感器)
                break;
            case DeviceType.OnePortWirelessFR:
            case DeviceType.OnePortBus:
            case DeviceType.RCU:
            case DeviceType.SuperWireless:
            case DeviceType.OnePortMqttFR:
                productType = "07";//07   网关类
                break;
            case DeviceType.ACPanel:
            case DeviceType.ACDevice:
            case DeviceType.ACInfrared:
            case DeviceType.ACCoolmaster:
            case DeviceType.CustomAC:
            case DeviceType.HVAC:
            case DeviceType.FoolHeat:
            case DeviceType.FoolHeatPanel:
                productType = "12";//12 恒温器(空调、地热)
                break;
            case DeviceType.MusicModel:
            case DeviceType.MusicPanel:
            case DeviceType.MusicA31:
                productType = "0B";
                break;
            default:
                productType = "00";
                break;
            }
            return productType;
        }
//    [Serializable]
//    public class Oids : BaseCloudFeedback
//    {
//        public string homeId { get; set; }
//        public string gatewayId { get; set; }
//        public List<Oid> devices { get; set; }
//    }
//    [Serializable]
//    public class Oid
//    {
//        public string protocolType { get; set; }
//        public string device_name { get; set; }
//        public string oid { get; set; }
//        public string addresses { get; set; }
//        public string device_model { get; set; }
        /// <summary>
        /// 获取生成物理模型参数
        /// 2021-01-22 目前物模还不完善
        /// </summary>
        /// <param name="deviceType"></param>
        /// <returns></returns>
        public string GetPhysicalModelType (DeviceType deviceType)
        {
            string productType = "";
            switch (deviceType) {
            case DeviceType.LightEnergySwitch:
                productType = "0101";
                break;
            case DeviceType.LightEnergySocket:
            case DeviceType.LightSwitchSocket:
                productType = "0102";
                break;
            case DeviceType.LightSwitch:
            case DeviceType.LightMixSwitch:
                productType = "0201";
                break;
            case DeviceType.LightDimming:
                productType = "0202";
                break;
            case DeviceType.LightCCT:
            case DeviceType.LightDALI:
                productType = "0203";
                break;
            case DeviceType.LightRGB:
            case DeviceType.LightRGBW:
            case DeviceType.LightLogic:
            case DeviceType.LightRGBandCCT:
            case DeviceType.DMX48:
                productType = "0204";
                break;
            //窗帘
            case DeviceType.CurtainModel:
                productType = "0301";
                break;
            case DeviceType.CurtainTrietex:
                productType = "0303";
                break;
            case DeviceType.CurtainRoller:
                productType = "0304";
                break;
            case DeviceType.ACPanel:
            case DeviceType.ACDevice:
            case DeviceType.ACInfrared:
            case DeviceType.ACCoolmaster:
            case DeviceType.CustomAC:
            case DeviceType.HVAC:
                productType = "0701";
                break;
            case DeviceType.FoolHeat:
            case DeviceType.FoolHeatPanel:
                productType = "0801";
                break;
            case DeviceType.MusicModel:
            case DeviceType.MusicPanel:
            case DeviceType.MusicA31:
                productType = "0901";
                break;
            case DeviceType.FanModule:
                productType = "1001";
                break;
            default:
                productType = ((int)deviceType).ToString ("X4");
                break;
            }
//        public string fw_version { get; set; }
//        public string hw_info { get; set; }
//        public string mac { get; set; }
//        public string deviceType { get; set; }
//    }
            return productType;
        }
//    [Serializable]
//    public class Sid
//    {
//        public string sid { get; set; }
//        public string name { get; set; }
//        public string[] uids { get; set; }
//        public string spk { get; set; }
//        public string oid { get; set; }  //设备模块地址
//        public string omodel { get; set; }    //型号
//        public List<Function> attributes { get; set; } //属性列表
//    }
//    [Serializable]
//    public class Function
//    {
//        //public string name { get; set; }
//        public string key { get; set; }
//        public List<string> value { get; set; }
//        public int max { get; set; }
//        public int min { get; set; }
//        public string data_type { get; set; }
//    }
        /// <summary>
        /// 生成功能设备Sid
        /// </summary>
        /// <param name="iDeviceType"></param>
        /// <param name="sOid"></param>
        /// <param name="iChnId"></param>
        /// <param name="isUseE548ReturnBigSmallType"></param>
        /// <param name="BigType"></param>
        /// <param name="SmallType"></param>
        /// <returns></returns>
        public string FormingNewSid (string sOid, Common loopCommon)
        {
            if (sOid == null || sOid == "") return "";
            try {
                //物模型类+通道号+大小类别
                string sSid = "";
                //1.物模型类
                string mPhysicalModelType = GetPhysicalModelType (loopCommon.Type);
                //2.通道号
                string loopIDStr = loopCommon.LoopID.ToString ("X4");
                //3.大小类别
                string bigMinStr = loopCommon.BigClass.ToString ("X2") + loopCommon.MinClass.ToString ("X2");
                //4.拼接
                sSid = sOid + mPhysicalModelType + loopIDStr + bigMinStr;
                return sSid;
            } catch {
                return "";
            }
        }
//}
        /// <summary>
        /// 生成SPK属性
        /// </summary>
        /// <param name="loopCommon"></param>
        /// <param name="iChnRemark"></param>
        /// <param name="sOid"></param>
        /// <param name="iChnId"></param>
        /// <param name="BigType"></param>
        /// <param name="SmallType"></param>
        /// <param name="isUseE548ReturnBigSmallType"></param>
        /// <returns></returns>
        public SidObject UpdateSidAttributesToDeviceList (Common loopCommon, string sOid)
        {
            SidObject tmp = new SidObject ();
            try {
                string sSid = FormingNewSid (sOid, loopCommon);
                tmp.oid = sOid;
                tmp.sid = sSid;
                tmp.name = loopCommon.Name;
                tmp.attributes = new List<FunctionSid> ();
                tmp.omodel = loopCommon.Type.ToString ();
                //继电器开关类
                if (loopCommon.Type == DeviceType.LightSwitch
                    || loopCommon.Type == DeviceType.LightEnergySwitch
                    || loopCommon.Type == DeviceType.LightEnergySocket
                    || loopCommon.Type == DeviceType.LightSwitchSocket
                    || loopCommon.Type == DeviceType.LightMixSwitch) {
                    tmp.spk = "light.switch";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                } else if (loopCommon.Type == DeviceType.LightDimming
                    || loopCommon.Type == DeviceType.LightCCT
                    || loopCommon.Type == DeviceType.LightDALI) {
                    //调光类
                    tmp.spk = "light.dimming";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    #region brightness
                    FunctionSid tempFunction1 = new FunctionSid ();
                    tempFunction1.key = "brightness";
                    tempFunction1.data_type = "integer";
                    tempFunction1.value = new List<string> ();
                    tempFunction1.max = 100;
                    tempFunction1.min = 0;
                    tmp.attributes.Add (tempFunction1);
                    #endregion
                    #region fade_time
                    FunctionSid tempFunction3 = new FunctionSid ();
                    tempFunction3.key = "fade_time";
                    tempFunction3.data_type = "integer";
                    tempFunction3.value = new List<string> ();
                    //tempFunction1.value.Add("percent");
                    //for (int iPercent = 0; iPercent <= 100; iPercent++)
                    //{
                    //    tempFunction1.value.Add(iPercent.ToString());
                    //}
                    tempFunction3.max = 100;
                    tempFunction3.min = 0;
                    tmp.attributes.Add (tempFunction3);
                    #endregion
                    if (loopCommon.Type == DeviceType.LightCCT || loopCommon.Type == DeviceType.LightDALI)//色温类别
                    {
                        tmp.spk = "light.cct";
                        #region cct
                        FunctionSid tempFunction2 = new FunctionSid ();
                        tempFunction2.key = "cct";
                        tempFunction2.data_type = "integer";
                        tempFunction2.value = new List<string> ();
                        //tempFunction2.value.Add("warm light ");
                        //tempFunction2.value.Add("cold light ");
                        tempFunction2.max = 65535;
                        tempFunction2.min = 0;
                        tmp.attributes.Add (tempFunction2);
                        #endregion
                    }
                } else if (loopCommon.Type == DeviceType.LightRGB
                    || loopCommon.Type == DeviceType.LightRGBW
                    || loopCommon.Type == DeviceType.LightLogic
                    || loopCommon.Type == DeviceType.LightRGBandCCT
                    || loopCommon.Type == DeviceType.DMX48) {
                    tmp.spk = "light.rgb";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    #region brightness
                    FunctionSid tempFunction2 = new FunctionSid ();
                    tempFunction2.key = "brightness";
                    tempFunction2.data_type = "integer";
                    tempFunction2.value = new List<string> ();
                    tempFunction2.max = 100;
                    tempFunction2.min = 0;
                    tmp.attributes.Add (tempFunction2);
                    #endregion
                    if (loopCommon.Type == DeviceType.LightRGBW) {
                        tmp.spk = "light.rgbw";
                        #region color
                        FunctionSid tempFunction3 = new FunctionSid ();
                        tempFunction3.key = "rgb";
                        tempFunction3.data_type = "integer";
                        tempFunction3.value = new List<string> ();
                        //tempFunction2.value.Add("red");
                        //tempFunction2.value.Add("green");
                        //tempFunction2.value.Add("blue");
                        tempFunction3.max = 255;
                        tempFunction3.min = 0;
                        tmp.attributes.Add (tempFunction3);
                        #endregion
                    } else {
                        #region color
                        FunctionSid tempFunction3 = new FunctionSid ();
                        tempFunction3.key = "rgb";
                        tempFunction3.data_type = "integer";
                        tempFunction3.value = new List<string> ();
                        tempFunction3.min = 0;
                        tmp.attributes.Add (tempFunction3);
                        #endregion
                    }
                    if (loopCommon.Type == DeviceType.LightRGBandCCT) {
                        #region CCT
                        FunctionSid tempFunctionCCT = new FunctionSid ();
                        tempFunctionCCT.key = "cct";
                        tempFunctionCCT.data_type = "integer";
                        tempFunctionCCT.value = new List<string> ();
                        //tempFunction2.value.Add("red");
                        //tempFunction2.value.Add("green");
                        //tempFunction2.value.Add("blue");
                        tempFunctionCCT.max = 65535;
                        tempFunctionCCT.min = 0;
                        tmp.attributes.Add (tempFunctionCCT);
                        #endregion
                    }
                } else if (loopCommon.Type == DeviceType.CurtainModel || loopCommon.Type == DeviceType.CurtainRoller || loopCommon.Type == DeviceType.CurtainTrietex) {
                    tmp.spk = "curtain.switch";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.value.Add ("stop");
                    tempFunction.max = 2;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    if (loopCommon.Type == DeviceType.CurtainRoller || loopCommon.Type == DeviceType.CurtainTrietex)//所有卷帘控制器
                    {
                        tmp.spk = "curtain.trietex";
                        #region openlevel
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "percent";
                        tempFunction1.data_type = "integer";
                        tempFunction1.value = new List<string> ();
                        //tempFunction1.value.Add("percent");
                        tempFunction1.max = 100;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    }
                } else if (loopCommon.Type == DeviceType.ACPanel
                   || loopCommon.Type == DeviceType.ACDevice
                   || loopCommon.Type == DeviceType.ACInfrared
                   || loopCommon.Type == DeviceType.ACCoolmaster
                   || loopCommon.Type == DeviceType.CustomAC
                   || loopCommon.Type == DeviceType.HVAC) {
                    //空调类
                    tmp.spk = "ac.standard";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    #region mode
                    FunctionSid tempFunction1 = new FunctionSid ();
                    tempFunction1.key = "mode";
                    tempFunction1.data_type = "integer";
                    tempFunction1.value = new List<string> ();
                    tempFunction1.value.Add ("cool");
                    tempFunction1.value.Add ("heat");
                    tempFunction1.value.Add ("fan");
                    tempFunction1.value.Add ("auto");
                    tempFunction1.value.Add ("dry");
                    tempFunction1.max = 4;
                    tempFunction1.min = 0;
                    tmp.attributes.Add (tempFunction1);
                    #endregion
                    #region fan
                    FunctionSid tempFunction2 = new FunctionSid ();
                    tempFunction2.key = "fan";
                    tempFunction2.data_type = "integer";
                    tempFunction2.value = new List<string> ();
                    tempFunction2.value.Add ("high");
                    tempFunction2.value.Add ("medium");
                    tempFunction2.value.Add ("low");
                    tempFunction2.value.Add ("auto");
                    tempFunction2.max = 3;
                    tempFunction2.min = 0;
                    tmp.attributes.Add (tempFunction2);
                    #endregion
                    #region temp
                    FunctionSid tempFunction3 = new FunctionSid ();
                    tempFunction3.key = "set_temp";
                    //2020 08 11  hvac 温度控制 1°-> int 0.5°->float
                    //if (HVACModuleDeviceTypeList.HDLHVACwithAcControlHighPrecision.Contains(DevOnLineTmp.DeviceType))
                    //{
                    //20201224 设置温度数据类型统一float 伟南后续ai+数据类型网关处理
                    tempFunction3.data_type = "float";
                    //}
                    //else
                    //{
                    //    tempFunction3.data_type = "integer";
                    //}
                    tempFunction3.value = new List<string> ();
                    tempFunction3.max = 30;
                    tempFunction3.min = 16;
                    tmp.attributes.Add (tempFunction3);
                    #endregion
                    #region temp_step
                    FunctionSid tempFunction5 = new FunctionSid ();
                    tempFunction5.key = "set_temp_step";
                    tempFunction5.data_type = "string";
                    tempFunction5.value = new List<string> ();
                    tempFunction5.value.Add ("up");
                    tempFunction5.value.Add ("down");
                    tempFunction5.max = 1;
                    tempFunction5.min = 0;
                    tmp.attributes.Add (tempFunction5);
                    #endregion
                    #region room_temp
                    FunctionSid tempFunction6 = new FunctionSid ();
                    tempFunction6.key = "room_temp";
                    tempFunction6.data_type = "float";
                    tempFunction6.value = new List<string> ();
                    tempFunction6.max = 50;
                    tempFunction6.min = -50;
                    tmp.attributes.Add (tempFunction6);
                    #endregion
                    #region swing
                    FunctionSid tempFunction4 = new FunctionSid ();
                    tempFunction4.key = "swing";
                    tempFunction4.data_type = "string";
                    tempFunction4.value = new List<string> ();
                    tempFunction4.value.Add ("up_down");
                    //tempFunction4.value.Add("down");
                    tempFunction4.value.Add ("left_right");
                    //tempFunction4.value.Add("right");
                    tempFunction4.value.Add ("stop");
                    tempFunction4.max = 3;
                    tempFunction4.min = 0;
                    tmp.attributes.Add (tempFunction4);
                    #endregion
                    #region lock
                    #endregion
                } else if (loopCommon.Type == DeviceType.FoolHeat
                    || loopCommon.Type == DeviceType.FoolHeatPanel) {
                    tmp.spk = "floorHeat.standard";
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    #region mode
                    FunctionSid tempFunction1 = new FunctionSid ();
                    tempFunction1.key = "mode";
                    tempFunction1.data_type = "string";
                    tempFunction1.value = new List<string> ();
                    tempFunction1.value.Add ("day");
                    tempFunction1.value.Add ("night");
                    tempFunction1.value.Add ("away");
                    tempFunction1.value.Add ("normal");
                    tempFunction1.value.Add ("timer");
                    tempFunction1.max = 4;
                    tempFunction1.min = 0;
                    tmp.attributes.Add (tempFunction1);
                    #endregion
                    #region temp
                    FunctionSid tempFunction3 = new FunctionSid ();
                    tempFunction3.key = "set_temp";
                    tempFunction3.data_type = "float";
                    tempFunction3.value = new List<string> ();
                    //tempFunction3.value.Add("up");
                    //tempFunction3.value.Add("down");
                    //tempFunction3.value.Add("value");
                    tempFunction3.max = 35;
                    tempFunction3.min = 0;
                    tmp.attributes.Add (tempFunction3);
                    #endregion
                    #region temp
                    FunctionSid tempFunction4 = new FunctionSid ();
                    tempFunction4.key = "set_temp_step";
                    tempFunction4.data_type = "string";
                    tempFunction4.value = new List<string> ();
                    tempFunction4.value.Add ("up");
                    tempFunction4.value.Add ("down");
                    tempFunction4.max = 1;
                    tempFunction4.min = 0;
                    tmp.attributes.Add (tempFunction4);
                    #endregion
                    #region room_temp
                    FunctionSid tempFunction5 = new FunctionSid ();
                    tempFunction5.key = "room_temp";
                    tempFunction5.data_type = "float";
                    tempFunction5.value = new List<string> ();
                    tempFunction5.max = 50;
                    tempFunction5.min = -50;
                    tmp.attributes.Add (tempFunction5);
                    #endregion
                    #region lock
                    #endregion
                } else if (loopCommon.Type == DeviceType.MusicA31
                    || loopCommon.Type == DeviceType.MusicModel
                    || loopCommon.Type == DeviceType.MusicPanel) {
                    tmp.spk = "music.standard";
                    // on_off  volume song_step  audio  list_channel  mode  song_num  special_song  volume_level
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("play");
                    tempFunction.value.Add ("pause");
                    //tempFunction.value.Add("play");
                    //tempFunction.value.Add("stop");
                    //tempFunction.value.Add("pause");
                    //play stop pause
                    tempFunction.max = 2;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                    #region volume
                    FunctionSid tempFunction1 = new FunctionSid ();
                    tempFunction1.key = "volume";
                    tempFunction1.data_type = "integer";
                    tempFunction1.value = new List<string> ();
                    //tempFunction1.value.Add("percent");
                    tempFunction1.max = 100;
                    tempFunction1.min = 0;
                    tmp.attributes.Add (tempFunction1);
                    #endregion
                    #region volume_step
                    FunctionSid tempFunction9 = new FunctionSid ();
                    tempFunction9.key = "volume_step";
                    tempFunction9.data_type = "string";
                    tempFunction9.value = new List<string> ();
                    tempFunction9.value.Add ("up");
                    tempFunction9.value.Add ("down");
                    tempFunction9.max = 1;
                    tempFunction9.min = 0;
                    tmp.attributes.Add (tempFunction9);
                    #endregion
                    #region volume_level
                    FunctionSid tempFunction10 = new FunctionSid ();
                    tempFunction10.key = "volume_level";
                    tempFunction10.data_type = "integer";
                    tempFunction10.value = new List<string> ();
                    //tempFunction1.value.Add("percent");
                    tempFunction10.max = 10;
                    tempFunction10.min = 0;
                    tmp.attributes.Add (tempFunction10);
                    #endregion
                    #region volume_level_step
                    FunctionSid tempFunction11 = new FunctionSid ();
                    tempFunction11.key = "volume_level_step";
                    tempFunction11.data_type = "string";
                    tempFunction11.value = new List<string> ();
                    tempFunction11.value.Add ("up");
                    tempFunction11.value.Add ("down");
                    tempFunction11.max = 1;
                    tempFunction11.min = 0;
                    tmp.attributes.Add (tempFunction11);
                    #endregion
                    #region treble
                    FunctionSid tempFunction14 = new FunctionSid ();
                    tempFunction14.key = "treble";
                    tempFunction14.data_type = "integer";
                    tempFunction14.max = 10;
                    tempFunction14.min = -10;
                    tmp.attributes.Add (tempFunction14);
                    #endregion
                    #region treble_step
                    FunctionSid tempFunction12 = new FunctionSid ();
                    tempFunction12.key = "treble_step";
                    tempFunction12.data_type = "string";
                    tempFunction12.value = new List<string> ();
                    tempFunction12.value.Add ("up");
                    tempFunction12.value.Add ("down");
                    tempFunction12.max = 1;
                    tempFunction12.min = 0;
                    tmp.attributes.Add (tempFunction12);
                    #endregion
                    #region bass
                    FunctionSid tempFunction15 = new FunctionSid ();
                    tempFunction15.key = "bass";
                    tempFunction15.data_type = "integer";
                    tempFunction15.max = 10;
                    tempFunction15.min = -10;
                    tmp.attributes.Add (tempFunction15);
                    #endregion
                    #region bass_step
                    FunctionSid tempFunction13 = new FunctionSid ();
                    tempFunction13.key = "bass_step";
                    tempFunction13.data_type = "string";
                    tempFunction13.value = new List<string> ();
                    tempFunction13.value.Add ("up");
                    tempFunction13.value.Add ("down");
                    tempFunction13.max = 1;
                    tempFunction13.min = 0;
                    tmp.attributes.Add (tempFunction13);
                    #endregion
                    #region mode
                    FunctionSid tempFunction5 = new FunctionSid ();
                    tempFunction5.key = "mode";
                    tempFunction5.data_type = "string";
                    tempFunction5.value = new List<string> ();
                    //singel/single_circle/order/all
                    //single/single_cycle/order/list_cycle/random
                    tempFunction5.value.Add ("single");
                    tempFunction5.value.Add ("single_cycle");
                    tempFunction5.value.Add ("order");
                    tempFunction5.value.Add ("list_cycle");
                    tempFunction5.value.Add ("random");
                    tempFunction5.max = 3;
                    tempFunction5.min = 0;
                    tmp.attributes.Add (tempFunction5);
                    #endregion
                    #region source
                    //1   = SD, 2 = External Input, 3 = FTP, 4 = Radio
                    //sdcard/external_input/ftp/radio
                    FunctionSid tempFunction3 = new FunctionSid ();
                    tempFunction3.key = "source";
                    tempFunction3.data_type = "string";
                    tempFunction3.value = new List<string> ();
                    tempFunction3.value.Add ("sdcard");
                    tempFunction3.value.Add ("audio_in");
                    tempFunction3.value.Add ("ftp");
                    tempFunction3.value.Add ("radio");
                    tempFunction3.value.Add ("bluetooth");
                    tempFunction3.max = 3;
                    tempFunction3.min = 0;
                    tmp.attributes.Add (tempFunction3);
                    #endregion
                    #region song_step
                    FunctionSid tempFunction2 = new FunctionSid ();
                    tempFunction2.key = "song_step";
                    tempFunction2.data_type = "string";
                    tempFunction2.value = new List<string> ();
                    tempFunction2.value.Add ("up");
                    tempFunction2.value.Add ("down");
                    tempFunction2.max = 1;
                    tempFunction2.min = 0;
                    tmp.attributes.Add (tempFunction2);
                    #endregion
                    #region bass
                    FunctionSid tempFunction16 = new FunctionSid ();
                    tempFunction16.key = "playlist_name";
                    tempFunction16.data_type = "string";
                    tmp.attributes.Add (tempFunction16);
                    #endregion
                    #region bass
                    FunctionSid tempFunction17 = new FunctionSid ();
                    tempFunction17.key = "song_name";
                    tempFunction17.data_type = "string";
                    tmp.attributes.Add (tempFunction17);
                    #endregion
                    #region bass
                    FunctionSid tempFunction19 = new FunctionSid ();
                    tempFunction19.key = "song_time";
                    tempFunction19.data_type = "string";
                    tmp.attributes.Add (tempFunction19);
                    #endregion
                    #region bass
                    FunctionSid tempFunction20 = new FunctionSid ();
                    tempFunction20.key = "playing_time";
                    tempFunction20.data_type = "string";
                    tmp.attributes.Add (tempFunction20);
                    #endregion
                } else if (loopCommon.BigClass == 5) {
                    //传感器
                    if (loopCommon.Type == DeviceType.SensorMobileDetection) {
                        tmp.spk = "sensor.pir";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region status
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "status";
                        tempFunction1.data_type = "string";
                        tempFunction1.value = new List<string> ();
                        tempFunction1.value.Add ("true");
                        tempFunction1.value.Add ("false");
                        tempFunction1.max = 1;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                        #region sensitivity
                        FunctionSid tempFunction2 = new FunctionSid ();
                        tempFunction2.key = "sensitivity";
                        tempFunction2.data_type = "integer";
                        tempFunction2.max = 100;
                        tempFunction2.min = 0;
                        tmp.attributes.Add (tempFunction2);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorTemperature) {
                        tmp.spk = "sensor.temperature";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region temp
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";  //2020 12 22
                        tempFunction1.data_type = "float";
                        tempFunction1.max = 50;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                        #region type
                        FunctionSid tempFunction2 = new FunctionSid ();
                        tempFunction2.key = "type";
                        tempFunction2.data_type = "string";
                        tempFunction2.value = new List<string> ();
                        tempFunction2.value.Add ("C");
                        tempFunction2.value.Add ("F");
                        tempFunction2.max = 1;
                        tempFunction2.min = 0;
                        tmp.attributes.Add (tempFunction2);
                        #endregion
                        //#region precision
                        //Function tempFunction3 = new GateWay.Function();
                        //tempFunction3.key = "precision";
                        //tempFunction3.data_type = "string";
                        //tempFunction3.value = new List<string>();
                        //tempFunction3.value.Add("0.01");
                        //tempFunction3.value.Add("0.1");
                        //tempFunction3.value.Add("100");
                        //tempFunction3.max = 2;
                        //tempFunction3.min = 0;
                        //tmp.attributes.Add(tempFunction3);
                        //#endregion
                    }else if (loopCommon.Type == DeviceType.SensorIllumination) {
                        tmp.spk = "sensor.light";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region lux
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";  //2020 12 22
                        tempFunction1.data_type = "integer";
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                        #region error_value
                        FunctionSid tempFunction2 = new FunctionSid ();
                        tempFunction2.key = "error_value";
                        tempFunction2.data_type = "integer";
                        tmp.attributes.Add (tempFunction2);
                        #endregion
                        #region precision
                        FunctionSid tempFunction3 = new FunctionSid ();
                        tempFunction3.key = "precision";
                        tempFunction3.data_type = "string";
                        tempFunction3.value = new List<string> ();
                        tempFunction3.value.Add ("0.01");
                        tempFunction3.value.Add ("0.1");
                        tempFunction3.value.Add ("100");
                        tempFunction3.max = 2;
                        tempFunction3.min = 0;
                        tmp.attributes.Add (tempFunction3);
                        #endregion
                    } else if (loopCommon.Type == DeviceType.SensorPM25) {
                        tmp.spk = "sensor.pm25";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region value
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";
                        tempFunction1.data_type = "integer";
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                        #region error_value
                        FunctionSid tempFunction2 = new FunctionSid ();
                        tempFunction2.key = "error_value";
                        tempFunction2.data_type = "integer";
                        tmp.attributes.Add (tempFunction2);
                        #endregion
                        #region precision
                        FunctionSid tempFunction3 = new FunctionSid ();
                        tempFunction3.key = "precision";
                        tempFunction3.data_type = "string";
                        tempFunction3.value = new List<string> ();
                        tempFunction3.value.Add ("0.01");
                        tempFunction3.value.Add ("0.1");
                        tempFunction3.value.Add ("100");
                        tempFunction3.max = 2;
                        tempFunction3.min = 0;
                        tmp.attributes.Add (tempFunction3);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorHumidity) {
                        tmp.spk = "sensor.humidity";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region value
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";
                        tempFunction1.data_type = "float";
                        tempFunction1.max = 10000;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorTVOC) {
                        tmp.spk = "sensor.tvoc";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region value
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";
                        tempFunction1.data_type = "integer";
                        tempFunction1.max = 10000;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorCO2) {
                        tmp.spk = "sensor.co2";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region value
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";
                        tempFunction1.data_type = "integer";
                        tempFunction1.max = 10000;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.Sensor) {
                        tmp.spk = "dryContact.standard";
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region status
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "status";
                        tempFunction1.data_type = "string";
                        tempFunction1.value = new List<string> ();
                        tempFunction1.value.Add ("on");
                        tempFunction1.value.Add ("off");
                        tempFunction1.max = 1;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    } else {
                        #region on_off
                        FunctionSid tempFunction = new FunctionSid ();
                        tempFunction.key = "enable";
                        tempFunction.data_type = "string";
                        tempFunction.value = new List<string> ();
                        tempFunction.value.Add ("true");
                        tempFunction.value.Add ("false");
                        tempFunction.max = 1;
                        tempFunction.min = 0;
                        tmp.attributes.Add (tempFunction);
                        #endregion
                        #region value
                        FunctionSid tempFunction1 = new FunctionSid ();
                        tempFunction1.key = "value";
                        tempFunction1.data_type = "integer";
                        tempFunction1.max = 10000;
                        tempFunction1.min = 0;
                        tmp.attributes.Add (tempFunction1);
                        #endregion
                    }
                } else {
                    #region on_off
                    FunctionSid tempFunction = new FunctionSid ();
                    tempFunction.key = "on_off";
                    tempFunction.data_type = "string";
                    tempFunction.value = new List<string> ();
                    tempFunction.value.Add ("on");
                    tempFunction.value.Add ("off");
                    tempFunction.max = 1;
                    tempFunction.min = 0;
                    tmp.attributes.Add (tempFunction);
                    #endregion
                }
            } catch { }
            return tmp;
        }
        //#region 判断类型
        ///// <summary>
        ///// 继电器类别
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLRelayDeviceType (DeviceType deviceType)
        //{
        //    return false;
        //}
        ///// <summary>
        ///// 调光器类别
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLDimmerDeviceType (DeviceType deviceType)
        //{
        //    return false;
        //}
        ///// <summary>
        ///// 遮阳类别(窗帘、卷帘、开合帘)
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLCurtainDeviceType (DeviceType deviceType)
        //{
        //    return deviceType == DeviceType.CurtainModel
        //            || deviceType == DeviceType.CurtainRoller
        //            || deviceType == DeviceType.CurtainTrietex;
        //}
        ///// <summary>
        ///// 传感器类别
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLSensorDeviceType (DeviceType deviceType)
        //{
        //    return false;
        //}
        ///// <summary>
        ///// 网关类别
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLGatewayDeviceType (DeviceType deviceType)
        //{
        //    return false;
        //}
        ///// <summary>
        ///// 空调
        ///// </summary>
        ///// <param name="deviceType"></param>
        ///// <returns></returns>
        //public bool IsHDLACDeviceType (DeviceType deviceType)
        //{
        //    return false;
        //}
        //#endregion
        #region 生成4位byte 时间戳
        private long LastTime = 0;
        /// <summary>
        /// DateTime时间格式转换为13位带毫秒的Unix时间戳
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public long ConvertDateTimeLong ()
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime (new System.DateTime (2020, 1, 1));
            long l = (long)(Math.Round ((DateTime.Now - startTime).TotalSeconds, 1) * 10);
            if (l <= LastTime) l = LastTime + 1;
            LastTime = l;
            return l;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="m"></param>
        /// <param name="strTmp"></param>
        /// <returns></returns>
        public bool ConvertIntToByteArray (long m, ref string strTmp)
        {
            strTmp = "00000000";
            byte [] arry = new byte [4];
            arry [0] = (byte)(m & 0xFF);
            arry [1] = (byte)((m & 0xFF00) >> 8);
            arry [2] = (byte)((m & 0xFF0000) >> 16);
            arry [3] = (byte)((m & 0xFF000000) >> 24);
            strTmp = arry [0].ToString ("X2") + arry [1].ToString ("X2") + arry [2].ToString ("X2") + arry [3].ToString ("X2");
            return true;
        }
        #endregion
    }
    [Serializable]
    public class BaseCloudFeedback
    {
        public int code { get; set; }
        public string timestamp { get; set; }
        public bool isSuccess { get; set; }
        public string message { get; set; }
    }
    [Serializable]
    public class Sids
    {
        public string homeId { get; set; }
        public string gatewayId { get; set; }
        public List<Sid> devices { get; set; }
    }
    [Serializable]
    public class Oids
    {
        public string homeId { get; set; }
        public string gatewayId { get; set; }
        public List<Oid> devices { get; set; }
    }
    [Serializable]
    public class Oid
    {
        public string protocolType { get; set; }
        public string device_name { get; set; }
        public string oid { get; set; }
        public string addresses { get; set; }
        public string device_model { get; set; }
        public string fw_version { get; set; }
        public string hw_info { get; set; }
        public string mac { get; set; }
        public int deviceType { get; set; }
    }
    [Serializable]
    public class Sid
    {
        public string sid { get; set; }
        public string name { get; set; }
        public string [] uids { get; set; }
        public string spk { get; set; }
        public string oid { get; set; }  //设备模块地址
        public string omodel { get; set; }    //型号
        public List<FunctionSid> attributes { get; set; } //属性列表
    }
    [Serializable]
    public class FunctionSid
    {
        //public string name { get; set; }
        public string key { get; set; }
        public List<string> value { get; set; }
        public int max { get; set; }
        public int min { get; set; }
        public string data_type { get; set; }
    }
    [Serializable]
    public class SidObject : Sid
    {
    }
    [Serializable]
    public class IotCloud
    {
        public Oids modules { get; set; } //设备列表
        public Sids functions { get; set; } //功能列表
    }
    /// <summary>
    /// 设备列表响应data参数
    /// </summary>
    public class DevcieFunctionRes
    {
        public List<Function> list = new List<Function> ();
        //public string totalCount = "0";
        //public string totalPage = "0";
        //public string pageNo = "0";
        //public string pageSize = "0";
    }
    /// <summary>
    /// 功能类能满足数据使用要求,子类只是为了方便使用属性
    /// </summary>
    public class Function
    {
        public Function ()
        {
        }
        #region base info
        /// <summary>
        /// HDL统一协议格式:14bytes
        /// 举例: 来源   厂商代码 通讯方式  产品时间戳   产品类别 物模型类  通道号   大小类别
        ///       1byte   1byte   1byte     4byte       1byte   2byte   2byte   2byte
        /// 来源:00   默认原生态系统数据 、01   网关或者其他A设备、02   调试软件、03   APP应用程序、04   第三方网关或者平台
        /// 厂商代码:01   HDL
        /// 通讯方式:01   HDL Bus、02   Zigbee、03 KNX、04 Z-Wave
        /// 产品时间戳:4bytes   以2020年1月1日算出的时间戳0.1s为单位
        /// 产品类别:01   调光器、02 继电器、03   干接点模块、04   传感器、05 面板
        /// 物模型类型:
        ///     01   开关类:01 开关、02 插座、03
        ///     02   照明: 01 开关、02   调光、03   色温、04   LED
        ///     03   遮阳: 01   窗帘电机、02 百叶窗、03 开合帘、04 卷帘
        ///     04   恒温器:01 空调、02 地暖、03 毛细空调
        ///     05   新风
        ///     06   影音
        ///     07   音乐
        ///     08   能源
        ///     09   安防
        /// 大类别   1bytes   (预留)
        /// 小类别   1byte   (预留)
        /// </summary>
        public string sid = "0301011234567801012301230123";
        /// <summary>
        ///
        /// </summary>
        public string oid;
        /// <summary>
        /// 备注
        /// </summary>
        public string name;
        /// <summary>
        /// 设备ID
        /// 云端负责生成
        /// </summary>
        public string deviceId = "0";
        /// <summary>
        /// 设备spk
        /// </summary>
        public string spk = "";
        /// <summary>
        ///
        /// </summary>
        string spk_Prefix;
        /// <summary>
        /// spk前缀
        /// 大类
        /// 功能类别
        /// 如:空调类、灯光类、窗帘类
        /// </summary>
        public string Spk_Prefix {
            get {
                if (string.IsNullOrEmpty (spk_Prefix)) {
                    spk_Prefix = spk.Split (".") [0];
                }
                return spk_Prefix;
            }
        }
        string spk_Suffix;
        /// <summary>
        /// A协议功能的特性
        /// 如:是AC功能:特性:on_off,mode,fan,temperature
        /// attri
        /// </summary>
        public List<FunctionAttributes> attributes = new List<FunctionAttributes> ();
        /// <summary>
        /// 房间ID列表
        /// 该功能添加到到房间列表
        /// </summary>
        public List<string> roomIds = new List<string> ();
        /// <summary>
        /// bus协议数据格式
        /// 使用A协议控制时,改属性为空
        /// </summary>
        public BusData bus;
        /// <summary>
        /// 是否收藏
        /// </summary>
        public bool collect = false;
        /// <summary>
        /// 是否在线
        /// </summary>
        public bool online = true;
        /// <summary>
        /// 云端数据创建的时间
        /// </summary>
        public string createTime = "";
        /// <summary>
        /// 云端数据修改的最后时间
        /// </summary>
        public string modifyTime = "";
        /// <summary>
        /// 删除标记
        /// 需要删除数据时,标记为:true
        /// 由云端删除成功之后,返回数据再清除本地数据
        /// </summary>
        public bool DeleteSign = false;
        #endregion
        /// <summary>
        /// 延时
        /// </summary>
        public int delay = 0;
        /// <summary>
        /// 最后控制的一次状态
        /// </summary>
        [Newtonsoft.Json.JsonIgnore]
        public string lastState = "";
        FunctionAttributes _trait_on_off;
        [Newtonsoft.Json.JsonIgnore]
        public FunctionAttributes trait_on_off {
            get {
                if (_trait_on_off == null) {
                    _trait_on_off = attributes.Find ((obj) => obj.key == FunctionAttributeKey.OnOff);
                    //找不到属性需要声明一个,防止报错闪退
                    if (_trait_on_off == null) {
                        _trait_on_off = new FunctionAttributes () {
                            key = "on_off",
                            value = new List<string> { "on", "off" },
                            max = 1,
                            min = 0,
                        };
                        _trait_on_off.curValue = "off";
                    }
                }
                if (_trait_on_off.curValue.ToString () != "on" && _trait_on_off.curValue.ToString () != "off") {
                    _trait_on_off.curValue = "off";
                }
                return _trait_on_off;
            }
            //set
            //{
            //    _trait_on_off = value;
            //}
        }
        /// <summary>
        /// 使用次数
        /// </summary>
        public double controlCounter = 0;
        /// <summary>
        /// 使用频率
        /// </summary>
        public double usageFrequency {
            get {
                return controlCounter / 7;
            }
        }
        /// <summary>
        /// 固定的序号
        /// </summary>
        public int fixedSerialNumber = int.MaxValue;
    }
    /// <summary>
    /// 功能属性
    /// 属性字段解析:attri :属性内容,value 属性的值,max 最大值 min 最小值
    /// </summary>
    [System.Serializable]
    public class FunctionAttributes
    {
        /// <summary>
        /// 属性键名
        /// </summary>
        public string key;
        /// <summary>
        /// 属性的值列表
        /// </summary>
        public List<string> value = new List<string> ();
        /// <summary>
        /// 最大值
        /// </summary>
        public int max = 100;
        /// <summary>
        /// 最小值
        /// </summary>
        public int min = 0;
        /// <summary>
        /// 数据类型
        /// </summary>
        public string data_type = "";
        /// <summary>
        /// 当前值
        /// </summary>
        public object curValue = new object ();
    }
    /// <summary>
    /// 功能属性键名列表
    /// </summary>
    public static class FunctionAttributeKey
    {
        /// <summary>
        /// 开关
        /// </summary>
        public const string OnOff = "on_off";
        /// <summary>
        /// 亮度
        /// </summary>
        public const string Brightness = "brightness";
        /// <summary>
        /// 颜色
        /// </summary>
        public const string RGB = "rgb";
        /// <summary>
        /// 渐变时间
        /// </summary>
        public const string FadeTime = "fade_time";
        /// <summary>
        /// 模式
        /// </summary>
        public const string Mode = "mode";
        /// <summary>
        /// 风速
        /// </summary>
        public const string FanSpeed = "fan";
        /// <summary>
        /// 设置温度
        /// </summary>
        public const string SetTemp = "set_temp";
        /// <summary>
        /// 延时
        /// </summary>
        public const string Delay = "delay";
        /// <summary>
        /// 色温
        /// </summary>
        public const string CCT = "cct";
        /// <summary>
        /// 百分比
        /// </summary>
        public const string Percent = "percent";
        /// <summary>
        /// 室内温度
        /// </summary>
        public const string IndoorTemp = "room_temp";
        /// <summary>
        /// value
        /// </summary>
        public const string Value = "value";
    }
    /// <summary>
    /// 兼容旧协议控制
    /// </summary>
    public class BusData
    {
        public string addresses = "FFFF";
        [Newtonsoft.Json.JsonIgnore]
        public byte SubnetID {
            get {
                return Convert.ToByte (addresses.Substring (0, 2), 16);
            }
        }
        [Newtonsoft.Json.JsonIgnore]
        public byte DeviceID {
            get {
                return Convert.ToByte (addresses.Substring (2, 2), 16);
            }
        }
        public byte LoopId {
            get {
                return Convert.ToByte (loopId, 16);
            }
        }
        public string loopId;
    }
    public static class SPK
    {
        /// <summary>
        /// (开关灯)
        /// </summary>
        public const string LightSwitch = "light.switch";
        /// <summary>
        /// (调光灯)
        /// </summary>
        public const string LightDimming = "light.dimming";
        /// <summary>
        /// (RGB灯)
        /// </summary>
        public const string LightRGB = "light.rgb";
        /// <summary>
        /// (RGBW灯)
        /// </summary>
        public const string LightRGBW = "light.rgbw";
        /// <summary>
        /// (CCT灯)
        /// </summary>
        public const string LightCCT = "light.cct";
        /// <summary>
        /// (开关窗帘)
        /// </summary>
        public const string CurtainSwitch = "curtain.switch";
        /// <summary>
        /// (开合帘)
        /// </summary>
        public const string CurtainTrietex = "curtain.trietex";
        /// <summary>
        /// (百叶帘)
        /// </summary>
        public const string CurtainShades = "curtain.shades";
        /// <summary>
        /// (卷帘)
        /// </summary>
        public const string CurtainRoller = "curtain.roller";
        /// <summary>
        /// (空调)
        /// </summary>
        public const string AcStandard = "ac.standard";
        /// <summary>
        /// (地热)
        /// </summary>
        public const string FloorHeatStandard = "floorHeat.standard";
        /// <summary>
        /// (新风)
        /// </summary>
        public const string AirFreshStandard = "airFresh.standard";
        /// <summary>
        /// (音乐)
        /// </summary>
        public const string MusicStandard = "music.standard";
        /// <summary>
        /// (亮度传感器)
        /// </summary>
        public const string SensorLight = "sensor.light";
        /// <summary>
        /// (温度传感器)
        /// </summary>
        public const string SensorTemperature = "sensor.temperature";
        /// <summary>
        /// (红外移动传感器)
        /// </summary>
        public const string SensorPir = "sensor.pir";
        /// <summary>
        /// (门窗传感器)
        /// </summary>
        public const string SensorDoorWindow = "sensor.doorwindow";
        /// <summary>
        /// (PM2.5传感器)
        /// </summary>
        public const string SensorPm25 = "sensor.pm25";
        /// <summary>
        /// co2传感器
        /// </summary>
        public const string SensorCO2 = "sensor.co2";
        /// <summary>
        /// tvoc传感器
        /// </summary>
        public const string SensorTVOC = "sensor.tvoc";
        /// <summary>
        /// 湿度传感器
        /// </summary>
        public const string SensorHumidity = "sensor.humidity";
        /// <summary>
        /// (干接点)
        /// </summary>
        public const string DryContact = "dryContact.standard";
        /// <summary>
        /// 家电、插座
        /// </summary>
        public const string ElectricSocket = "electrical.socket";
        /// <summary>
        /// 家电、电视
        /// </summary>
        public const string ElectricTV = "electrical.tv";
        /// <summary>
        /// 家电、风扇
        /// </summary>
        public const string ElectricFan = "electrical.fan";
    }
    /// <summary>
    /// 功能类别
    /// </summary>
    public static class FunctionCategory
    {
        /// <summary>
        ///(灯)
        /// </summary>
        public const string Light = "light";
        /// <summary>
        /// (窗帘)
        /// </summary>
        public const string Curtain = "curtain";
        /// <summary>
        /// (空调)
        /// </summary>
        public const string AC = "ac";
        /// <summary>
        /// (地热)
        /// </summary>
        public const string FloorHeat = "floorHeat";
        /// <summary>
        /// (新风)
        /// </summary>
        public const string AirFresh = "airFresh";
        /// <summary>
        /// (音乐)
        /// </summary>
        public const string Music = "music";
        /// <summary>
        /// (传感器)
        /// </summary>
        public const string Sensor = "sensor";
        /// <summary>
        /// (干接点)
        /// </summary>
        public const string DryContact = "dryContact";
        /// <summary>
        /// 家电
        /// </summary>
        public const string Electric = "electrical";
        //Music = 0x09,
    }
    ///// <summary>
    ///// 上传Oid列表
    ///// </summary>
    //[Serializable]
    //public class UploadOids
    //{
    //    public string homeId { get; set; } //住宅ID
    //    public Oids devices { get; set; } //设备列表
    //}
    ///// <summary>
    ///// 上传Sid列表
    ///// </summary>
    //[Serializable]
    //public class UploadSids
    //{
    //    public string homeId { get; set; } //住宅ID
    //    public string gatewayId { get; set; } //网关ID
    //    public Sids devices { get; set; } //设备列表
    //}
}
//sid组成部分:
//sid
//来源   厂商代码   通讯方式   产品时间戳   产品类别   物模型类   通道号   大小类别
//1byte   1byte   1byte   4byte   1byte   2byte   2byte   2byte
//oid组成部分:
//来源   厂商代码   通讯方式   产品时间戳   产品类别
//1byte   1 byte   1 byte   4 byte   1byte
//其中各部分代码列表:
//来源   1byte   编号   描述
//      00   默认原生态系统数据
//      01   网关或者其他A设备
//      02   调试软件
//      03   APP应用程序
//      04   第三方网关或者平台
//厂商代码   1byte   编号   描述
//      01   HDL
//      02
//通讯方式   1byte   编号   描述
//      01   HDL Bus
//      02   Zigbee
//      03   KNX
//      04   Z-Wave
//产品时间戳   4bytes   以2020年1月1日算出的时间戳0.1s为单位
//产品类别   1byte   编号   描述
//      01   调光器
//      02   继电器
//      03   干接点模块
//      04   传感器
//      05   面板
//      06   RCU
//      07   网关
//      08   红外发射
//      09   Android屏
//      10   场景
//      11   音乐播放器
//      12   232/485转换器
//      21   自动化
//      22   安防防区
//      14   窗帘模块
//      15   HVAC
//      16   地热模块
//物模型类型   2bytes   编号   描述
//      01   开关类   01   开关
//            02   插座
//            03
//      02   照明   01   开关
//            02   调光
//            03   色温(CCT)
//            04   RGB
//      03   遮阳   01   窗帘控制器
//            02   百叶窗
//            03   开合帘
//            04   卷帘
//            05    推窗器
//            06    投影幕
//      04   面板   01   按键面板
//      05   传感器   01   移动探测
//            02   温度传感器
//            03   湿度传感器
//            04   照度传感器
//            05   TVOC
//            06   PM2.5
//            07   CO2
//            08   毫米波传感器
//            09
//            10
//            11   烟雾传感器
//            25   干接点
//      07   恒温器   01   空调
//            02   风扇
//            03   毛细空调
//      08   地热   01   地热模块
//      09   背景音乐   01   音乐播放器
//            02   Sonos
//      10   场景   01   场景
//            02   电影场景
//      19   新风   01   新风
//13   能源   01   电表
//            02   水表
//            03   燃气
//      16   电器   01   风扇
//            02   TV
//      20   安防   01   安防
//      21   自动化   01   自动化
//大类别   1bytes   (预留)
//小类别   1byte   (预留)