CrabtreeOn,印度客户定制APP,迁移2.0平台版本
1
wxr
2023-03-31 d53e6af2c5f17838fa79659614b15a2a1f383399
Crabtree/SmartHome/HDL/Common/HDLLinkUtlis.cs
@@ -1,562 +1,2804 @@
//using System;
//using System.Collections.Generic;
//using Shared;
using System;
using System.Collections.Generic;
using Shared;
using Shared.IO;
using Shared.SimpleControl;
//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
namespace Shared
{
    /// <summary>
    /// HDLLink协议 工具类
    /// </summary>
    public class HDLLinkUtlis
    {
        /// <summary>
        /// 生成逻辑sid方法
        /// </summary>
        public static string NewSceneSid ()
        {
            string sceneId = "";
            try {
                string sOidBeginsWith = "000101";//厂商 + 通讯方式
                string sTimeSpan = "00000000";
                long sTimeSp = ConvertDateTimeLong (); //以2020年1月1日算出的时间戳0.1s为单位
                ConvertIntToByteArray (sTimeSp, ref sTimeSpan);
                if (sTimeSpan.Length > 8) {
                    sTimeSpan = sTimeSpan.Substring (0, 8);
                }
                sceneId = sOidBeginsWith + sTimeSpan;
                sceneId += "0A";
                sceneId += "0A01";
                int maxId = 1;
                Random random = new Random (Guid.NewGuid ().GetHashCode ());
                maxId = random.Next (65535);
                sceneId += (maxId).ToString ("X4");
                sceneId += "0000";
            } catch {
                return sceneId;
            }
            return sceneId;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="curtainStatus"></param>
        /// <returns></returns>
        public static string GetCurtainStatusKey (CurtainStatus curtainStatus) {
            if(curtainStatus == CurtainStatus.Open) {
                return "on";
            } else if (curtainStatus == CurtainStatus.Close) {
                return "off";
            } else if (curtainStatus == CurtainStatus.Stop) {
                return "stop";
            } else {
                return "off";
            }
        }
        #region 生成4位byte 时间戳
        private static long LastTime = 0;
        /// <summary>
        /// DateTime时间格式转换为13位带毫秒的Unix时间戳
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public static long ConvertDateTimeLong ()
        {
            System.DateTime startTime = TimeZoneInfo.ConvertTimeToUtc (new System.DateTime (2020, 1, 1));
            long l = (long)(Math.Round ((DateTime.Now - startTime).TotalMilliseconds, 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 static 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
        #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.Type, sOid, j, false, BigType, SmallType);
//                                tmpSid.oid = sOid;
        /// <summary>
        /// 一键将本地回路设备和场景数据转换
        /// 然后上传oid、sid、以及场景列表
        /// </summary>
        /// <returns></returns>
        public void OneclickUpload (bool isMigrate = false)
        {
            if (isMigrate) {
                var res = false;
                res = UploadOidAndSidList ();
                if (res) {
                    res = GetFunctionList ();
                    if (res) {
                        res = UploadSecneList ();
                    }
                }
                return;
            }
            MainPage.Loading.Start ("Uploading...");
            System.Threading.Tasks.Task.Run (() => {
                try {
                    var res = false;
                    res = UploadOidAndSidList ();
                    if (res) {
                        res = GetFunctionList ();
                        if (res) {
                            res = UploadSecneList ();
                        }
                    }
//                                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;
//            }
//        }
                    if (res) {
                        Utlis.ShowAlertOnMainThread (Language.StringByID (SimpleControl.R.MyInternationalizationString.SuccessfullySynchronizedToTheCloud));
                    } else {
                        Utlis.ShowAlertOnMainThread (Language.StringByID (SimpleControl.R.MyInternationalizationString.FailedToSyncToTheCloud));
                    }
//        /// <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> ();
                } catch {
//                //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;
                } finally {
                    Application.RunOnMainThread (() => {
                        MainPage.Loading.Hide ();
                    });
                }
            });
//                //上传功能列表
//                #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>
        /// <returns></returns>
        public bool GetFunctionList ()
        {
            var res = false;
            try {
                var revertObj = HttpServerRequest.Current.GetDeviceList ();
                if (revertObj.Code == StateCode.SUCCESS) {
                    var devcieFunctionRes = Newtonsoft.Json.JsonConvert.DeserializeObject<DevcieFunctionRes> (revertObj.Data.ToString ());
                    if (devcieFunctionRes != null && devcieFunctionRes.list != null && devcieFunctionRes.list.Count > 0) {
                        CommonConfig.Current.FunctionList = devcieFunctionRes.list;
                    } else {
                        CommonConfig.Current.FunctionList = new List<Function> ();
                    }
                    CommonConfig.Current.Save ();
                    res = true;
                } else {
                    //提示错误
                    IMessageCommon.Current.ShowErrorInfoAlter (revertObj.Code);
                }
            } catch {
//        /// <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;
            return res;
        }
//                //上传功能列表
//                #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
        #region ■ 上传场景列表___________________________
        /// <summary>
        /// 上传场景列表
        /// </summary>
        public bool UploadSecneList ()
        {
            var res = false;
            try {
                //1.加载所有场景并转换
                var allSecneList = GetAllSecneList ();
                var hdlLinkSceneList = new List<HDLLinkScene> ();
                foreach (var sence in allSecneList) {
                    var mHDLLinkScene = GetHDLLinkScene (sence);
                    //1.1成功转换的场景才添加到准备上传列表
                    if(mHDLLinkScene != null && mHDLLinkScene.functions != null && mHDLLinkScene.functions.Count > 0) {
                        hdlLinkSceneList.Add (mHDLLinkScene);
                    }
                }
                //全量同步场景
                res = UploadSceneList (hdlLinkSceneList);
//            } catch (Exception ex) {
//                //MessageBox.Show (ex.Tostring ());
//                //throw;
//            }
//        }
            } catch (Exception ex){
                Utlis.WriteLine ("catch :" + ex.ToString ());
            }
            return res;
        }
//        /// <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
        /// <summary>
        /// 获取所有场景列表
        /// </summary>
        /// <returns></returns>
        public List<Scene> GetAllSecneList ()
        {
            List<Scene> targetSceneList = new List<Scene> ();
            //// 找出需要显示的场景
            // 1.全局场景
            var globalSceneFileList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>> (System.Text.Encoding.UTF8.GetString (IO.FileUtils.ReadFile (Scene.GlobalSceneFilePath)));
            if (globalSceneFileList == null) {
                globalSceneFileList = new List<string> ();
            }
            // 2.房间场景
            List<string> RoomsSceneFileList = new List<string> ();
            foreach (var r in Room.Lists) {
                if (string.IsNullOrEmpty (r.Name)) {
                    continue;
                }
                if (r != null) {
                    RoomsSceneFileList.AddRange (r.SceneFilePathList);
                }
            }
//                //3.生成产品类别
//                var productType = GetProductType (deviceType);
//                sOid = sOidBeginsWith + sTimeSpan + productType;
            foreach (var sceneFilePath in globalSceneFileList) {
                var tempScene = Scene.GetSceneByFilePath (sceneFilePath);
                if (tempScene != null) {
                    if (string.IsNullOrEmpty (tempScene.Sid)) {
                        //如果Sid为空,重新生成并保存
                        tempScene.Sid = NewSceneSid ();
                        tempScene.Save (sceneFilePath);
                        Utlis.WriteLine ("生成新的场景id: " + tempScene.Sid);
//                return sOid;
//            } catch {
//                return sOid;
//            }
//        }
                    }
                    targetSceneList.Add (tempScene);
                }
            }
//        /// <summary>
//        /// 获取产品类别
//        //产品类别 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:
//                productType = "01";//01   调光器
//                break;
//            case DeviceType.LightSwitch:
//                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;
//            }
            foreach (var roomSceneFilePath in RoomsSceneFileList) {
                var tempScene = Scene.GetSceneByFilePath (roomSceneFilePath);
                if (tempScene != null) {
                    if (string.IsNullOrEmpty (tempScene.Sid)) {
                        //如果Sid为空,重新生成并保存
                        tempScene.Sid = NewSceneSid ();
                        tempScene.Save (roomSceneFilePath);
                        Utlis.WriteLine ("生成新的场景id: " + tempScene.Sid);
                    }
                    targetSceneList.Add (tempScene);
                }
            }
            // 所有场景
            return targetSceneList;
        }
//            return productType;
//        }
        /// <summary>
        /// 全量同步场景
        /// </summary>
        /// <param name="mScene"></param>
        bool UploadSceneList (List<HDLLinkScene> hdlLinkSceneList)
        {
            var res = false;
            try {
                var revertObj = HttpServerRequest.Current.SecneSyncList (hdlLinkSceneList);
                if (revertObj.Code == StateCode.SUCCESS) {
                    res = true;
                } else {
                    IMessageCommon.Current.ShowErrorInfoAlter (revertObj.Code);
                }
            } catch {
            }
            return res;
        }
//        /// <summary>
//        /// 获取生成物理模型参数
        ///// <summary>
        /////
        ///// </summary>
        ///// <param name="mScene"></param>
        //bool UpdateSceneList (List<HDLLinkScene> updateLinkSceneList)
        //{
        //    var res = false;
        //    try {
        //        var revertObj = HttpServerRequest.Current.EditScene (updateLinkSceneList);
        //        if (revertObj.Code == StateCode.SUCCESS) {
        //            res = true;
        //        } else {
        //            IMessageCommon.Current.ShowErrorInfoAlter (revertObj.Code);
        //        }
        //    } catch {
//        /// </summary>
//        /// <param name="deviceType"></param>
//        /// <returns></returns>
//        public string GetPhysicalModelType (DeviceType deviceType)
//        {
//            string productType = "";
//            switch (deviceType) {
//            case DeviceType.LightDimming:
//                productType = "0101";
//                break;
//            }
        //    }
        //    return res;
        //}
//            return productType;
//        }
        /// <summary>
        /// 原生协议Scene 转换成 HDLLinkScene数据格式
        /// </summary>
        /// <param name="mScene"></param>
        /// <returns></returns>
        HDLLinkScene GetHDLLinkScene (Scene mScene)
        {
            var mHDLLinkScene = new HDLLinkScene ();
            mHDLLinkScene.sid = mScene.Sid;
            mHDLLinkScene.name = mScene.Name;
            if (UserConfig.Instance.CheckWhetherGatewayIdNotNull ()) {
                mHDLLinkScene.gatewayId = UserConfig.Instance.HomeGateway.gatewayId;
            }
            var functions = new List<SceneFunction> ();
            if (!mScene.busScene) {
                foreach (var deviceFilePath in mScene.DeviceFilePathList) {
                    var jsonInfo = System.Text.Encoding.UTF8.GetString (IO.FileUtils.ReadFile (deviceFilePath));
                    var common = Newtonsoft.Json.JsonConvert.DeserializeObject<Common> (jsonInfo);
                    if (common == null) continue;
                    var function = CommonUtlis.Current.CommonToFunction (common, CommonConfig.Current.FunctionList);
                    if (function == null) continue;
                    if (common.Type == DeviceType.LightDimming) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<LightDimming> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.CurrentBrightness > 0 ? "on" : "off",
                        });
                        //2.Brightness
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Brightness,
                            value = commonNew.CurrentBrightness.ToString(),
                        });
                        //3.Delay
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Delay,
                            value = (commonNew.DelayTimeHeight * 256 + commonNew.DelayTimeLow).ToString (),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.LightEnergySocket) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<LightEnergySocket> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.CurrentBrightness > 0 ? "on" : "off",
                        });
                        //2.Delay
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Delay,
                            value = (commonNew.DelayTimeHeight * 256 + commonNew.DelayTimeLow).ToString (),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.LightEnergySwitch) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<LightEnergySwitch> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.CurrentBrightness > 0 ? "on" : "off",
                        });
                        //2.Delay
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Delay,
                            value = (commonNew.DelayTimeHeight * 256 + commonNew.DelayTimeLow).ToString(),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.LightRGB) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<LightLogic> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.CurrentBrightness > 0 ? "on" : "off",
                        });
                        //2.Brightness
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Brightness,
                            value = commonNew.CurrentBrightness.ToString (),
                        });
                        //3.Delay
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Delay,
                            value = (commonNew.DelayTimeHeigh * 256 + commonNew.DelayTimeLow).ToString (),
                        });
                        //4.rgb
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.RGB,
                            value = commonNew.RStatus + "," + commonNew.GStatus + "," + commonNew.BStatus,
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                        //var device = Newtonsoft.Json.JsonConvert.DeserializeObject<LightLogic> (System.Text.Encoding.UTF8.GetString (IO.FileUtils.ReadFile (deviceFilePath)));
                        ////if (device == null) {
                        ////    mSendCount--;
                        ////    continue;
                        ////}
                        //if (device == null) {
                        //    //replyBytes = new byte [] { 0x00 };
                        //} else {
                        //    var mSceneFunction = new SceneFunction ();
                        //    functions.Add (mSceneFunction);
                        //    replyBytes = Control.ControlBytesSendHasReturn (Command.SetLogicLoopColor, device.SubnetID, device.DeviceID, new byte [] { device.LoopID, device.CurrentBrightness, 254, device.DelayTimeHeigh,device.DelayTimeLow,
                        //                            3,device.RStatus,device.GStatus,device.BStatus,0,0});
                        //}
                    } else if (common.Type == DeviceType.LightSwitch) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<LightSwitch> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.OnOff
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.CurrentBrightness > 0 ? "on" : "off",
                        });
                        //2.Delay
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Delay,
                            value = (commonNew.DelayTimeHeight * 256 + commonNew.DelayTimeLow).ToString (),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.CurtainModel) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<CurtainModel> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off stop
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = GetCurtainStatusKey(commonNew.Status),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.CurtainRoller) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<CurtainRoller> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.percent
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Percent,
                            value = commonNew.CurtainProress.ToString(),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.CurtainTrietex) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<CurtainTrietex> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.percent
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Percent,
                            value = commonNew.CurtainProress.ToString (),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                    } else if (common.Type == DeviceType.HVAC || common.Type == DeviceType.ACInfrared) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<HVAC> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.Power > 0 ? "on" : "off",
                        });
                        //2.mode
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Mode,
                            value = commonNew.SetModeAttribute,
                        });
                        //3.fan
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.FanSpeed,
                            value = commonNew.SetFanSpeedAttribute,
                        });
                        //4.SetTemp
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.SetTemp,
                            value = commonNew.SetTemperature.ToString(),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                        //replyBytes = Control.ControlBytesSendHasReturn (Command.SetACMode, device.SubnetID, device.DeviceID, new byte [] {
                        //                    device.LoopID,
                        //                    device.TemperatureMode,
                        //                    device.IndoorTemperature,
                        //                    device.CoolTemperature,
                        //                    device.HeatTemperature,
                        //                    device.AutoTemperature,
                        //                    device.ChuShiTemperature,
                        //                    device.RealModeAndFanSpeed,
                        //                    device.Power,
                        //                    device.SetMode,
                        //                    device.SetFanSpeed,
                        //                    device.SetTemperature,
                        //                    device.ShaoFanMode});
                    } else if (common.Type == DeviceType.FoolHeat) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<FoolHeat> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.Status > 0 ? "on" : "off",
                        });
                        //2.mode
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.Mode,
                            value = commonNew.SetModeAttribute,
                        });
                        //3.SetTemp
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.SetTemp,
                            value = commonNew.WorkingTemperature.ToString (),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                        //var device = Newtonsoft.Json.JsonConvert.DeserializeObject<FoolHeat> (System.Text.Encoding.UTF8.GetString (IO.FileUtils.ReadFile (deviceFilePath)));
                        ////if (device == null) {
                        ////    mSendCount--;
                        ////    continue;
                        ////}
                        //if (device == null) {
                        //    //replyBytes = new byte [] { 0x00 };
                        //} else {
                        //    var mSceneFunction = new SceneFunction ();
                        //    functions.Add (mSceneFunction);
                            //replyBytes = Control.ControlBytesSendHasReturn (Command.SetFoolHeat, device.SubnetID, device.DeviceID,
                            //                                            new byte [] { device.LoopID, (byte)(device.Status + device.WorkingMode * 16), 0,device.WorkingMode,device.NormalTemperature, device.DayTemperature,
                            //   device.NightTemperature, device.AwayTemperature , 0, 0 });
                        //}
                    } else if (common.Type == DeviceType.FanModule) {
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<FanModule> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.WindSpeed > 0 ? "on" : "off",
                        });
                        //2.FanSpeedPercent
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.FanSpeedPercent,
                            value = commonNew.WindSpeed.ToString(),
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                        //replyBytes = Control.ControlBytesSendHasReturn (Command.SetSingleLight, device.SubnetID, device.DeviceID, new byte [] { device.LoopID, (byte)device.WindSpeed });
                    } else if (common.Type == DeviceType.LogicModule) {
                        //replyBytes = Control.ControlBytesSendHasReturn (Command.SetScene, device.SubnetID, device.DeviceID, new byte [] {
                        //device.AreaID,device.AreaSceneID});
                    } else if (common.Type == DeviceType.UniversalDevice) {//2020-09-02 增加通用开关
                        var commonNew = Newtonsoft.Json.JsonConvert.DeserializeObject<UniversalDevice> (jsonInfo);
                        var mSceneFunction = new SceneFunction ();
                        mSceneFunction.sid = function.sid;
                        //1.on_off
                        var status = new List<SceneFunctionStatus> ();
                        status.Add (new SceneFunctionStatus () {
                            key = FunctionAttributeKey.OnOff,
                            value = commonNew.SendBytes [1] > 0 ? "on" : "off",
                        });
                        mSceneFunction.status = status;
                        functions.Add (mSceneFunction);
                        //replyBytes = Control.ControlBytesSendHasReturn (Command.SetCommonSwitch, device.SubnetID, device.DeviceID, new byte [] { device.SendBytes [0], device.SendBytes [1] });
                    }
                }
            } else {
            }
            mHDLLinkScene.functions = functions;
            return mHDLLinkScene;
        }
        #endregion
        #region ■ 上传设备列表___________________________
        /// <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);
                //2022-06-21 13:10:07 mac不能为空,否则云端有问题
                foreach (var bean in currentProject.modules.devices) {
                    if (string.IsNullOrEmpty (bean.mac)) {
                        bean.mac = bean.oid;
                    }
                }
                Utlis.WriteLine ("list: " + list.Count + "currentProject : " + currentProject.functions.devices.Count);
                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(Exception EX) {
                Utlis.WriteLine ("catch: " + EX.ToString());
            }
            return res;
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public List<Common> GetAllDeviceList ()
        {
            List<Common> TargetList = new List<Common> ();
            //找出需要显示的设备
            var localEquipments = CommonUtlis.Current.GetAllLocalEquipments ();
            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;
        }
        /// <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;
                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);
                        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="common"></param>
        /// <returns></returns>
        public string FormingNewOid (Common common)
        {
            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
                //2.方案二:生成产品时间戳(云端不解析)印度APP把当前位置改为(子网号、设备号、大类小类)表示,保证设备在子网号设备号不变的情况下 oid生成也不变
                string sTimeSpan = "";
                sTimeSpan = common.SubnetID.ToString ("X2") + common.DeviceID.ToString ("X2") + common.DeviceTypeString;
                //****************************
                //3.生成产品类别
                var productType = GetProductType (common.Type);
                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;
        }
        /// <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;
            }
            return productType;
        }
        /// <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.DeviceTypeString;
                //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<Attribute> ();
                tmp.omodel = loopCommon.Type.ToString ();
                if (loopCommon.Type == DeviceType.UniversalDevice) {
                    //通用开关
                    tmp.spk = SPK.UniversalDevice;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                }else if (loopCommon.Type == DeviceType.FanModule ) {
                    //风扇
                    tmp.spk = SPK.ElectricFan;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region volume_level
                    Attribute tempSpeedAttribute = new Attribute ();
                    tempSpeedAttribute.key = FunctionAttributeKey.FanSpeedPercent;
                    tempSpeedAttribute.data_type = "integer";
                    tempSpeedAttribute.value = new List<string> ();
                    tempSpeedAttribute.max = 8;
                    tempSpeedAttribute.min = 0;
                    tmp.attributes.Add (tempSpeedAttribute);
                    #endregion
                } else if (loopCommon.Type == DeviceType.LightSwitch
                    || loopCommon.Type == DeviceType.LightEnergySwitch
                    || loopCommon.Type == DeviceType.LightMixSwitch) {
                    //继电器开关类
                    tmp.spk = SPK.LightSwitch;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                }else if (loopCommon.Type == DeviceType.LightEnergySocket
                    || loopCommon.Type == DeviceType.LightSwitchSocket) {
                    //电器 插座
                    tmp.spk = SPK.ElectricSocket;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                } else if (loopCommon.Type == DeviceType.LightDimming
                    || loopCommon.Type == DeviceType.LightCCT
                    || loopCommon.Type == DeviceType.LightDALI) {
                    //调光类
                    //tmp.spk = "light.dimming";
                    tmp.spk = SPK.LightDimming;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region brightness
                    Attribute tempAttribute1 = new Attribute ();
                    tempAttribute1.key = "brightness";
                    tempAttribute1.data_type = "integer";
                    tempAttribute1.value = new List<string> ();
                    tempAttribute1.max = 100;
                    tempAttribute1.min = 0;
                    tmp.attributes.Add (tempAttribute1);
                    #endregion
                    #region fade_time
                    Attribute tempAttribute3 = new Attribute ();
                    tempAttribute3.key = "fade_time";
                    tempAttribute3.data_type = "integer";
                    tempAttribute3.value = new List<string> ();
                    //tempAttribute1.value.Add("percent");
                    //for (int iPercent = 0; iPercent <= 100; iPercent++)
                    //{
                    //    tempAttribute1.value.Add(iPercent.ToString());
                    //}
                    tempAttribute3.max = 100;
                    tempAttribute3.min = 0;
                    tmp.attributes.Add (tempAttribute3);
                    #endregion
                    if (loopCommon.Type == DeviceType.LightCCT || loopCommon.Type == DeviceType.LightDALI)//色温类别
                    {
                        //tmp.spk = "light.cct";
                        tmp.spk = SPK.LightCCT;
                        #region cct
                        Attribute tempAttribute2 = new Attribute ();
                        tempAttribute2.key = "cct";
                        tempAttribute2.data_type = "integer";
                        tempAttribute2.value = new List<string> ();
                        //tempAttribute2.value.Add("warm light ");
                        //tempAttribute2.value.Add("cold light ");
                        tempAttribute2.max = 65535;
                        tempAttribute2.min = 0;
                        tmp.attributes.Add (tempAttribute2);
                        #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 = SPK.LightRGB;
                    //tmp.spk = "light.rgb";
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region brightness
                    Attribute tempAttribute2 = new Attribute ();
                    tempAttribute2.key = "brightness";
                    tempAttribute2.data_type = "integer";
                    tempAttribute2.value = new List<string> ();
                    tempAttribute2.max = 100;
                    tempAttribute2.min = 0;
                    tmp.attributes.Add (tempAttribute2);
                    #endregion
                    if (loopCommon.Type == DeviceType.LightRGBW) {
                        //tmp.spk = "light.rgbw";
                        tmp.spk = SPK.LightRGBW;
                        #region color
                        Attribute tempAttribute3 = new Attribute ();
                        tempAttribute3.key = "rgb";
                        tempAttribute3.data_type = "integer";
                        tempAttribute3.value = new List<string> ();
                        //tempAttribute2.value.Add("red");
                        //tempAttribute2.value.Add("green");
                        //tempAttribute2.value.Add("blue");
                        tempAttribute3.max = 255;
                        tempAttribute3.min = 0;
                        tmp.attributes.Add (tempAttribute3);
                        #endregion
                    } else {
                        #region color
                        Attribute tempAttribute3 = new Attribute ();
                        tempAttribute3.key = "rgb";
                        tempAttribute3.data_type = "integer";
                        tempAttribute3.value = new List<string> ();
                        tempAttribute3.min = 0;
                        tmp.attributes.Add (tempAttribute3);
                        #endregion
                    }
                    if (loopCommon.Type == DeviceType.LightRGBandCCT) {
                        #region CCT
                        Attribute tempAttributeCCT = new Attribute ();
                        tempAttributeCCT.key = "cct";
                        tempAttributeCCT.data_type = "integer";
                        tempAttributeCCT.value = new List<string> ();
                        //tempAttribute2.value.Add("red");
                        //tempAttribute2.value.Add("green");
                        //tempAttribute2.value.Add("blue");
                        tempAttributeCCT.max = 65535;
                        tempAttributeCCT.min = 0;
                        tmp.attributes.Add (tempAttributeCCT);
                        #endregion
                    }
                } else if (loopCommon.Type == DeviceType.CurtainModel || loopCommon.Type == DeviceType.CurtainRoller || loopCommon.Type == DeviceType.CurtainTrietex) {
                    //tmp.spk = "curtain.switch";
                    tmp.spk = SPK.CurtainSwitch;
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.value.Add ("stop");
                    tempAttribute.max = 2;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    if (loopCommon.Type == DeviceType.CurtainRoller || loopCommon.Type == DeviceType.CurtainTrietex)//所有卷帘控制器
                    {
                        tmp.spk = SPK.CurtainTrietex;
                        //tmp.spk = "curtain.trietex";
                        #region openlevel
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "percent";
                        tempAttribute1.data_type = "integer";
                        tempAttribute1.value = new List<string> ();
                        //tempAttribute1.value.Add("percent");
                        tempAttribute1.max = 100;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #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 = SPK.AcStandard;
                    //tmp.spk = "ac.standard";
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region mode
                    Attribute tempAttribute1 = new Attribute ();
                    tempAttribute1.key = "mode";
                    tempAttribute1.data_type = "integer";
                    tempAttribute1.value = new List<string> ();
                    tempAttribute1.value.Add ("cool");
                    tempAttribute1.value.Add ("heat");
                    tempAttribute1.value.Add ("fan");
                    tempAttribute1.value.Add ("auto");
                    tempAttribute1.value.Add ("dry");
                    tempAttribute1.max = 4;
                    tempAttribute1.min = 0;
                    tmp.attributes.Add (tempAttribute1);
                    #endregion
                    #region fan
                    Attribute tempAttribute2 = new Attribute ();
                    tempAttribute2.key = "fan";
                    tempAttribute2.data_type = "integer";
                    tempAttribute2.value = new List<string> ();
                    tempAttribute2.value.Add ("high");
                    tempAttribute2.value.Add ("medium");
                    tempAttribute2.value.Add ("low");
                    tempAttribute2.value.Add ("auto");
                    tempAttribute2.max = 3;
                    tempAttribute2.min = 0;
                    tmp.attributes.Add (tempAttribute2);
                    #endregion
                    #region temp
                    Attribute tempAttribute3 = new Attribute ();
                    tempAttribute3.key = "set_temp";
                    //2020 08 11  hvac 温度控制 1°-> int 0.5°->float
                    //if (HVACModuleDeviceTypeList.HDLHVACwithAcControlHighPrecision.Contains(DevOnLineTmp.DeviceType))
                    //{
                    //20201224 设置温度数据类型统一float 伟南后续ai+数据类型网关处理
                    tempAttribute3.data_type = "float";
                    //}
                    //else
                    //{
                    //    tempAttribute3.data_type = "integer";
                    //}
                    tempAttribute3.value = new List<string> ();
                    tempAttribute3.max = 30;
                    tempAttribute3.min = 16;
                    tmp.attributes.Add (tempAttribute3);
                    #endregion
                    #region temp_step
                    Attribute tempAttribute5 = new Attribute ();
                    tempAttribute5.key = "set_temp_step";
                    tempAttribute5.data_type = "string";
                    tempAttribute5.value = new List<string> ();
                    tempAttribute5.value.Add ("up");
                    tempAttribute5.value.Add ("down");
                    tempAttribute5.max = 1;
                    tempAttribute5.min = 0;
                    tmp.attributes.Add (tempAttribute5);
                    #endregion
                    #region room_temp
                    Attribute tempAttribute6 = new Attribute ();
                    tempAttribute6.key = "room_temp";
                    tempAttribute6.data_type = "float";
                    tempAttribute6.value = new List<string> ();
                    tempAttribute6.max = 50;
                    tempAttribute6.min = -50;
                    tmp.attributes.Add (tempAttribute6);
                    #endregion
                    #region swing
                    Attribute tempAttribute4 = new Attribute ();
                    tempAttribute4.key = "swing";
                    tempAttribute4.data_type = "string";
                    tempAttribute4.value = new List<string> ();
                    tempAttribute4.value.Add ("up_down");
                    //tempAttribute4.value.Add("down");
                    tempAttribute4.value.Add ("left_right");
                    //tempAttribute4.value.Add("right");
                    tempAttribute4.value.Add ("stop");
                    tempAttribute4.max = 3;
                    tempAttribute4.min = 0;
                    tmp.attributes.Add (tempAttribute4);
                    #endregion
                    #region lock
                    #endregion
                } else if (loopCommon.Type == DeviceType.FoolHeat
                    || loopCommon.Type == DeviceType.FoolHeatPanel) {
                    tmp.spk = SPK.FloorHeatStandard;
                    //tmp.spk = "floorHeat.standard";
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region mode
                    Attribute tempAttribute1 = new Attribute ();
                    tempAttribute1.key = "mode";
                    tempAttribute1.data_type = "string";
                    tempAttribute1.value = new List<string> ();
                    tempAttribute1.value.Add ("day");
                    tempAttribute1.value.Add ("night");
                    tempAttribute1.value.Add ("away");
                    tempAttribute1.value.Add ("normal");
                    tempAttribute1.value.Add ("timer");
                    tempAttribute1.max = 4;
                    tempAttribute1.min = 0;
                    tmp.attributes.Add (tempAttribute1);
                    #endregion
                    #region temp
                    Attribute tempAttribute3 = new Attribute ();
                    tempAttribute3.key = "set_temp";
                    tempAttribute3.data_type = "float";
                    tempAttribute3.value = new List<string> ();
                    //tempAttribute3.value.Add("up");
                    //tempAttribute3.value.Add("down");
                    //tempAttribute3.value.Add("value");
                    tempAttribute3.max = 35;
                    tempAttribute3.min = 0;
                    tmp.attributes.Add (tempAttribute3);
                    #endregion
                    #region temp
                    Attribute tempAttribute4 = new Attribute ();
                    tempAttribute4.key = "set_temp_step";
                    tempAttribute4.data_type = "string";
                    tempAttribute4.value = new List<string> ();
                    tempAttribute4.value.Add ("up");
                    tempAttribute4.value.Add ("down");
                    tempAttribute4.max = 1;
                    tempAttribute4.min = 0;
                    tmp.attributes.Add (tempAttribute4);
                    #endregion
                    #region room_temp
                    Attribute tempAttribute5 = new Attribute ();
                    tempAttribute5.key = "room_temp";
                    tempAttribute5.data_type = "float";
                    tempAttribute5.value = new List<string> ();
                    tempAttribute5.max = 50;
                    tempAttribute5.min = -50;
                    tmp.attributes.Add (tempAttribute5);
                    #endregion
                    #region lock
                    #endregion
                } else if (loopCommon.Type == DeviceType.MusicA31
                    || loopCommon.Type == DeviceType.MusicModel
                    || loopCommon.Type == DeviceType.MusicPanel) {
                    tmp.spk = SPK.MusicStandard;
                    //tmp.spk = "music.standard";
                    // on_off  volume song_step  audio  list_channel  mode  song_num  special_song  volume_level
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("play");
                    tempAttribute.value.Add ("pause");
                    //tempAttribute.value.Add("play");
                    //tempAttribute.value.Add("stop");
                    //tempAttribute.value.Add("pause");
                    //play stop pause
                    tempAttribute.max = 2;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                    #region volume
                    Attribute tempAttribute1 = new Attribute ();
                    tempAttribute1.key = "volume";
                    tempAttribute1.data_type = "integer";
                    tempAttribute1.value = new List<string> ();
                    //tempAttribute1.value.Add("percent");
                    tempAttribute1.max = 100;
                    tempAttribute1.min = 0;
                    tmp.attributes.Add (tempAttribute1);
                    #endregion
                    #region volume_step
                    Attribute tempAttribute9 = new Attribute ();
                    tempAttribute9.key = "volume_step";
                    tempAttribute9.data_type = "string";
                    tempAttribute9.value = new List<string> ();
                    tempAttribute9.value.Add ("up");
                    tempAttribute9.value.Add ("down");
                    tempAttribute9.max = 1;
                    tempAttribute9.min = 0;
                    tmp.attributes.Add (tempAttribute9);
                    #endregion
                    #region volume_level
                    Attribute tempAttribute10 = new Attribute ();
                    tempAttribute10.key = "volume_level";
                    tempAttribute10.data_type = "integer";
                    tempAttribute10.value = new List<string> ();
                    //tempAttribute1.value.Add("percent");
                    tempAttribute10.max = 10;
                    tempAttribute10.min = 0;
                    tmp.attributes.Add (tempAttribute10);
                    #endregion
                    #region volume_level_step
                    Attribute tempAttribute11 = new Attribute ();
                    tempAttribute11.key = "volume_level_step";
                    tempAttribute11.data_type = "string";
                    tempAttribute11.value = new List<string> ();
                    tempAttribute11.value.Add ("up");
                    tempAttribute11.value.Add ("down");
                    tempAttribute11.max = 1;
                    tempAttribute11.min = 0;
                    tmp.attributes.Add (tempAttribute11);
                    #endregion
                    #region treble
                    Attribute tempAttribute14 = new Attribute ();
                    tempAttribute14.key = "treble";
                    tempAttribute14.data_type = "integer";
                    tempAttribute14.max = 10;
                    tempAttribute14.min = -10;
                    tmp.attributes.Add (tempAttribute14);
                    #endregion
                    #region treble_step
                    Attribute tempAttribute12 = new Attribute ();
                    tempAttribute12.key = "treble_step";
                    tempAttribute12.data_type = "string";
                    tempAttribute12.value = new List<string> ();
                    tempAttribute12.value.Add ("up");
                    tempAttribute12.value.Add ("down");
                    tempAttribute12.max = 1;
                    tempAttribute12.min = 0;
                    tmp.attributes.Add (tempAttribute12);
                    #endregion
                    #region bass
                    Attribute tempAttribute15 = new Attribute ();
                    tempAttribute15.key = "bass";
                    tempAttribute15.data_type = "integer";
                    tempAttribute15.max = 10;
                    tempAttribute15.min = -10;
                    tmp.attributes.Add (tempAttribute15);
                    #endregion
                    #region bass_step
                    Attribute tempAttribute13 = new Attribute ();
                    tempAttribute13.key = "bass_step";
                    tempAttribute13.data_type = "string";
                    tempAttribute13.value = new List<string> ();
                    tempAttribute13.value.Add ("up");
                    tempAttribute13.value.Add ("down");
                    tempAttribute13.max = 1;
                    tempAttribute13.min = 0;
                    tmp.attributes.Add (tempAttribute13);
                    #endregion
                    #region mode
                    Attribute tempAttribute5 = new Attribute ();
                    tempAttribute5.key = "mode";
                    tempAttribute5.data_type = "string";
                    tempAttribute5.value = new List<string> ();
                    //singel/single_circle/order/all
                    //single/single_cycle/order/list_cycle/random
                    tempAttribute5.value.Add ("single");
                    tempAttribute5.value.Add ("single_cycle");
                    tempAttribute5.value.Add ("order");
                    tempAttribute5.value.Add ("list_cycle");
                    tempAttribute5.value.Add ("random");
                    tempAttribute5.max = 3;
                    tempAttribute5.min = 0;
                    tmp.attributes.Add (tempAttribute5);
                    #endregion
                    #region source
                    //1   = SD, 2 = External Input, 3 = FTP, 4 = Radio
                    //sdcard/external_input/ftp/radio
                    Attribute tempAttribute3 = new Attribute ();
                    tempAttribute3.key = "source";
                    tempAttribute3.data_type = "string";
                    tempAttribute3.value = new List<string> ();
                    tempAttribute3.value.Add ("sdcard");
                    tempAttribute3.value.Add ("audio_in");
                    tempAttribute3.value.Add ("ftp");
                    tempAttribute3.value.Add ("radio");
                    tempAttribute3.value.Add ("bluetooth");
                    tempAttribute3.max = 3;
                    tempAttribute3.min = 0;
                    tmp.attributes.Add (tempAttribute3);
                    #endregion
                    #region song_step
                    Attribute tempAttribute2 = new Attribute ();
                    tempAttribute2.key = "song_step";
                    tempAttribute2.data_type = "string";
                    tempAttribute2.value = new List<string> ();
                    tempAttribute2.value.Add ("up");
                    tempAttribute2.value.Add ("down");
                    tempAttribute2.max = 1;
                    tempAttribute2.min = 0;
                    tmp.attributes.Add (tempAttribute2);
                    #endregion
                    #region bass
                    Attribute tempAttribute16 = new Attribute ();
                    tempAttribute16.key = "playlist_name";
                    tempAttribute16.data_type = "string";
                    tmp.attributes.Add (tempAttribute16);
                    #endregion
                    #region bass
                    Attribute tempAttribute17 = new Attribute ();
                    tempAttribute17.key = "song_name";
                    tempAttribute17.data_type = "string";
                    tmp.attributes.Add (tempAttribute17);
                    #endregion
                    #region bass
                    Attribute tempAttribute19 = new Attribute ();
                    tempAttribute19.key = "song_time";
                    tempAttribute19.data_type = "string";
                    tmp.attributes.Add (tempAttribute19);
                    #endregion
                    #region bass
                    Attribute tempAttribute20 = new Attribute ();
                    tempAttribute20.key = "playing_time";
                    tempAttribute20.data_type = "string";
                    tmp.attributes.Add (tempAttribute20);
                    #endregion
                } else if (loopCommon.BigClass == 5) {
                    //传感器
                    if (loopCommon.Type == DeviceType.SensorMobileDetection) {
                        tmp.spk = SPK.SensorPir;
                        //tmp.spk = "sensor.pir";
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region status
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "status";
                        tempAttribute1.data_type = "string";
                        tempAttribute1.value = new List<string> ();
                        tempAttribute1.value.Add ("true");
                        tempAttribute1.value.Add ("false");
                        tempAttribute1.max = 1;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                        #region sensitivity
                        Attribute tempAttribute2 = new Attribute ();
                        tempAttribute2.key = "sensitivity";
                        tempAttribute2.data_type = "integer";
                        tempAttribute2.max = 100;
                        tempAttribute2.min = 0;
                        tmp.attributes.Add (tempAttribute2);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorTemperature) {
                        tmp.spk = SPK.SensorTemperature;
                        //tmp.spk = "sensor.temperature";
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region temp
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";  //2020 12 22
                        tempAttribute1.data_type = "float";
                        tempAttribute1.max = 50;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                        #region type
                        Attribute tempAttribute2 = new Attribute ();
                        tempAttribute2.key = "type";
                        tempAttribute2.data_type = "string";
                        tempAttribute2.value = new List<string> ();
                        tempAttribute2.value.Add ("C");
                        tempAttribute2.value.Add ("F");
                        tempAttribute2.max = 1;
                        tempAttribute2.min = 0;
                        tmp.attributes.Add (tempAttribute2);
                        #endregion
                        //#region precision
                        //Function tempAttribute3 = new GateWay.Function();
                        //tempAttribute3.key = "precision";
                        //tempAttribute3.data_type = "string";
                        //tempAttribute3.value = new List<string>();
                        //tempAttribute3.value.Add("0.01");
                        //tempAttribute3.value.Add("0.1");
                        //tempAttribute3.value.Add("100");
                        //tempAttribute3.max = 2;
                        //tempAttribute3.min = 0;
                        //tmp.attributes.Add(tempAttribute3);
                        //#endregion
                    }else if (loopCommon.Type == DeviceType.SensorIllumination) {
                        //tmp.spk = "sensor.light";
                        tmp.spk = SPK.SensorLight;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region lux
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";  //2020 12 22
                        tempAttribute1.data_type = "integer";
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                        #region error_value
                        Attribute tempAttribute2 = new Attribute ();
                        tempAttribute2.key = "error_value";
                        tempAttribute2.data_type = "integer";
                        tmp.attributes.Add (tempAttribute2);
                        #endregion
                        #region precision
                        Attribute tempAttribute3 = new Attribute ();
                        tempAttribute3.key = "precision";
                        tempAttribute3.data_type = "string";
                        tempAttribute3.value = new List<string> ();
                        tempAttribute3.value.Add ("0.01");
                        tempAttribute3.value.Add ("0.1");
                        tempAttribute3.value.Add ("100");
                        tempAttribute3.max = 2;
                        tempAttribute3.min = 0;
                        tmp.attributes.Add (tempAttribute3);
                        #endregion
                    } else if (loopCommon.Type == DeviceType.SensorPM25) {
                        //tmp.spk = "sensor.pm25";
                        tmp.spk = SPK.SensorPm25;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region value
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";
                        tempAttribute1.data_type = "integer";
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                        #region error_value
                        Attribute tempAttribute2 = new Attribute ();
                        tempAttribute2.key = "error_value";
                        tempAttribute2.data_type = "integer";
                        tmp.attributes.Add (tempAttribute2);
                        #endregion
                        #region precision
                        Attribute tempAttribute3 = new Attribute ();
                        tempAttribute3.key = "precision";
                        tempAttribute3.data_type = "string";
                        tempAttribute3.value = new List<string> ();
                        tempAttribute3.value.Add ("0.01");
                        tempAttribute3.value.Add ("0.1");
                        tempAttribute3.value.Add ("100");
                        tempAttribute3.max = 2;
                        tempAttribute3.min = 0;
                        tmp.attributes.Add (tempAttribute3);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorHumidity) {
                        //tmp.spk = "sensor.humidity";
                        tmp.spk = SPK.SensorHumidity;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region value
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";
                        tempAttribute1.data_type = "float";
                        tempAttribute1.max = 10000;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorTVOC) {
                        //tmp.spk = "sensor.tvoc";
                        tmp.spk = SPK.SensorTVOC;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region value
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";
                        tempAttribute1.data_type = "integer";
                        tempAttribute1.max = 10000;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.SensorCO2) {
                        //tmp.spk = "sensor.co2";
                        tmp.spk = SPK.SensorCO2;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region value
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";
                        tempAttribute1.data_type = "integer";
                        tempAttribute1.max = 10000;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                    }else if (loopCommon.Type == DeviceType.Sensor) {
                        //tmp.spk = "dryContact.standard";
                        tmp.spk = SPK.DryContact;
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region status
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "status";
                        tempAttribute1.data_type = "string";
                        tempAttribute1.value = new List<string> ();
                        tempAttribute1.value.Add ("on");
                        tempAttribute1.value.Add ("off");
                        tempAttribute1.max = 1;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                    } else {
                        #region on_off
                        Attribute tempAttribute = new Attribute ();
                        tempAttribute.key = "enable";
                        tempAttribute.data_type = "string";
                        tempAttribute.value = new List<string> ();
                        tempAttribute.value.Add ("true");
                        tempAttribute.value.Add ("false");
                        tempAttribute.max = 1;
                        tempAttribute.min = 0;
                        tmp.attributes.Add (tempAttribute);
                        #endregion
                        #region value
                        Attribute tempAttribute1 = new Attribute ();
                        tempAttribute1.key = "value";
                        tempAttribute1.data_type = "integer";
                        tempAttribute1.max = 10000;
                        tempAttribute1.min = 0;
                        tmp.attributes.Add (tempAttribute1);
                        #endregion
                    }
                } else {
                    #region on_off
                    Attribute tempAttribute = new Attribute ();
                    tempAttribute.key = "on_off";
                    tempAttribute.data_type = "string";
                    tempAttribute.value = new List<string> ();
                    tempAttribute.value.Add ("on");
                    tempAttribute.value.Add ("off");
                    tempAttribute.max = 1;
                    tempAttribute.min = 0;
                    tmp.attributes.Add (tempAttribute);
                    #endregion
                }
            } catch { }
            return tmp;
        }
        #endregion
        #region 获取属性
        #endregion
        //#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 ■ 设备列表相关___________________________
    [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<Attribute> attributes { get; set; } //属性列表
    }
    /// <summary>
    /// 属性
    /// </summary>
    [Serializable]
    public class Attribute
    {
        //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>
        /// 大类小类
        /// </summary>
        [Newtonsoft.Json.JsonIgnore]
        public string DeviceTypeString {
            get {
                if (!string.IsNullOrEmpty (sid) && sid.Length >= 28) {
                    return sid.Substring (sid.Length - 4, 4);
                } else {
                    return "0000";
                }
            }
        }
    }
//        /// <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>
    /// 功能属性
    /// 属性字段解析: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 ();
//                    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;
//                }
//                return sSid;
//            } catch {
//                return "";
//            }
//        }
//        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;
//        }
//        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;
//        }
//    }
    }
//    [Serializable]
//    public class Sids : BaseCloudFeedback
//    {
//        public string homeId { get; set; }
//        public string gatewayId { get; set; }
//        public List<Sid> devices { get; set; }
//    }
    /// <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";
//    [Serializable]
//    public class BaseCloudFeedback
//    {
//        public int code { get; set; }
//        public string timestamp { get; set; }
//        public bool isSuccess { get; set; }
//        public string message { get; set; }
//    }
        /// <summary>
        /// 风扇档位
        /// </summary>
        public const string FanSpeedPercent = "fan_speed_percent";
    }
    /// <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 const string UniversalDevice = "other.common";
    }
//    [Serializable]
//    public class Oids : BaseCloudFeedback
//    {
//        public string homeId { get; set; }
//        public string gatewayId { get; set; }
//        public List<Oid> devices { get; set; }
//    }
    /// <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";
//    [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 string 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<Function> attributes { get; set; } //属性列表
//    }
        //Music = 0x09,
    }
//    [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>
    ///// 上传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
    //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   第三方网关或者平台
////产品时间戳   4bytes   以2020年1月1日算出的时间戳0.1s为单位
    //厂商代码   1byte   编号   描述
    //      01   HDL
    //      02
////产品类别   1byte   编号   描述
////      01   调光器
////      02   继电器
////      03   干接点模块
////      04   传感器
////      05   面板
////      06   RCU
////      07   网关
////      08   红外发射
////      09   Android屏
////      10   场景
////      11   音乐播放器
////      12   232/485转换器
////      21   自动化
////      22   安防防区
////      14   窗帘模块
////      15   HVAC
////      16   地热模块
    //通讯方式   1byte   编号   描述
    //      01   HDL Bus
    //      02   Zigbee
    //      03   KNX
    //      04   Z-Wave
////物模型类型   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   新风
    //产品时间戳   4bytes   以2020年1月1日算出的时间戳0.1s为单位
////13   能源   01   电表
////            02   水表
////            03   燃气
////      16   电器   01   风扇
////            02   TV
////      20   安防   01   安防
////      21   自动化   01   自动化
////大类别   1bytes   (预留)
////小类别   1byte   (预留)
    //产品类别   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   (预留)
    #endregion
}