HDL Home App 第二版本 旧平台金堂用 正在使用
ZigbeeApp/Shared/Phone/ZigBee/Device/DoorLock.cs
old mode 100755 new mode 100644
@@ -11,2939 +11,2871 @@
namespace ZigBee.Device
{
    public class DoorLock : Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo
  public class DoorLock : Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo
  {
    public DoorLock()
    {
        public DoorLock()
        {
            this.Type = DeviceType.DoorLock;
        }
        #region 门锁本地变量
        /// <summary>
        /// 本地门锁用户和账户列表
        /// key:门锁用户ID
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, LocaDoorLockObj> localDoorLockUserList = new Dictionary<int, LocaDoorLockObj>();
        /// <summary>
        /// 本地门账户列表
        /// key:账户ID(主账户是GUID,子账户是分享过来的账户ID)
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, LocaDoorLockObj> localDoorLockAccountList = new Dictionary<string, LocaDoorLockObj>();
        public string currentUserDisplayMethod = string.Empty;//当前用户显示方式
        //本地所有账户列表
        public List<Shared.Phone.UserCenter.MemberInfoRes> localAllAccountList = new List<Shared.Phone.UserCenter.MemberInfoRes> { };
        /// <summary>
        /// 是否常开模式[当数据获取失败,返回空]
        /// </summary>
        public Dictionary<string, bool> IsDoorLockNormallyMode = new Dictionary<string, bool> { };//是否冻结子账户
        public string LocalTempPassword = string.Empty;//本地生成的临时密码
        public Dictionary<string, bool> IsFreezeAccount = new Dictionary<string, bool> { };//是否冻结子账户
        public Dictionary<string, bool> HasRemoteUnlockAccess = new Dictionary<string, bool> { };//是否给子账户拥有远程开锁的条件
        public Dictionary<string, bool> IsFailedToGetDoorLockInfo = new Dictionary<string, bool> { };//是否获取门锁数据失败
        public string RemoteUnlockPassword = string.Empty;//远程开锁密码
        public static int RemoteUnlockCount = 5;//远程开锁次数限制
        public static int failedCount = 3;//远程开锁失败次数
        public static DateTime maxValue = DateTime.MaxValue;
        public static DateTime minValue = DateTime.MinValue;
        #region 临时密码信息
        /// <summary>
        /// 用户管理发送数据回复
        /// </summary>
        public TempPasswordObject tempPasswordObject;
        /// <summary>
        /// 临时密码本地对象
        /// </summary>
        [System.Serializable]
        public class TempPasswordObject
        {
            /// <summary>
            ///  临时密码ID
            /// </summary>
            public int UserId;
            /// <summary>
            /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
            /// </summary>
            //public string PrimaryId;
            /// <summary>
            ///  6位有动态临时密码
            /// </summary>
            public string TempPassword;
            /// <summary>
            /// 门锁有效时间
            /// </summary>
            public DateTime ValidTime;
            /// <summary>
            /// 门锁失效时间
            /// </summary>
            public DateTime InValidTime;
        }
        #endregion
        #endregion
        #region 与云端通讯接口
        #region 门锁服务器发送基本信息
        /// <summary>
        ///  添加门锁
        /// </summary>
        public class BaseDoorLockServerData
        {
            /// <summary>
            /// RequestVersion
            /// </summary>
            public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
            /// <summary>
            /// LoginAccessToken
            /// </summary>
            public string LoginAccessToken = Shared.Common.Config.Instance.Token;
            /// <summary>
            /// 住宅Id -->键名 : HomeId
            /// </summary>
            public string HomeId = Shared.Common.Config.Instance.HomeId;
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId
            /// </summary>
            public string DoorLockId = "";
            /// <summary>
            /// 门锁本地用户Id -->键名 : DoorLockLocalUserId
            /// </summary>
            public string DoorLockLocalUserId = "";
            /// <summary>
            /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
            /// </summary>
            public bool IsOtherAccountCtrl = false;
        }
        #endregion
        #region 添加门锁
        /// <summary>
        ///  添加门锁
        /// </summary>
        public class AddDoorLockData : BaseDoorLockServerData
        {
            /// <summary>
            /// 云端帐号Id -->键名 : CloudAccountId
            /// </summary>
            public string CloudAccountId = "";
            /// <summary>
            /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选)
            /// </summary>
            public int OpenLockMode = 0;
            /// <summary>
            /// Data 相关内容(如:密码、指纹、IC卡 的二进制) -->键名 : Data (可选)
            public byte[] Data = null;
            /// <summary>
            /// 用户Id备注 -->键名 : UserIdRemarks
            /// </summary>
            public string UserIdRemarks = "";
            /// <summary>
            /// IsFreezeUser 是否冻结用户 -->键名 : IsFreezeUser (可选)
            /// </summary>
            public bool IsFreezeUser = false;
            /// <summary>
            /// IsTempUnlockAuthority 是否临时开锁权限 -->键名 : IsTempUnlockAuthority(可选)
            /// </summary>
            public bool IsTempUnlockAuthority = false;
            /// <summary>
            /// EntryTime 录入时间 -->键名 : EntryTime(可选)
            /// </summary>
            public DateTime EntryTime = System.DateTime.Now;
        }
        /// <summary>
        /// 添加门锁结果
        /// </summary>
        public class AddDoorLockDataRes
        {
            /// <summary>
            /// 响应的版本号,一般请求什么版本号,这里与之请求相同
            /// </summary>
            public string ResponseVersion = string.Empty;
            /// <summary>
            /// 响应状态码:
            ///<para>(1)Success 则[调用此接口操作成功], ResponseData则为null</para>
            ///<para>(2)ParameterOrEmpty,则响应字段中[ErrorInfo] 为错误信息, ResponseData则为null</para>
            ///(<para>3)NoLogin,则响应字段中[ErrorInfo] 为错误信息为[无效登录Token!]</para>
            ///<para>(4)NoRecord,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId值在云端不存在,请确认值是否正确!]</para>
            ///<para>(5)DoorLockIdNoIsYou,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId并不属于你当前帐号的,请确认值是否正确!]</para>
            /// </summary>
            public string StateCode = string.Empty;
        }
        #endregion
        #region 更新门锁
        /// <summary>
        ///   更新门锁
        /// </summary>
        public class RefreshDoorLockData : BaseDoorLockServerData
        {
            /// <summary>
            /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
            /// </summary>
            public string PrimaryId = "";
            /// <summary>
            /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选)
            /// </summary>
            public int OpenLockMode = 0;
            /// <summary>
            /// 住宅Id (可选)
            /// </summary>
            public byte[] Data;
            /// <summary>
            /// 用户Id备注
            /// </summary>
            public string UserIdRemarks = "";
            /// <summary>
            /// 是否为管理员门锁
            /// </summary>
            public bool IsFreezeUser;
            /// <summary>
            /// 是否为管理员门锁
            /// </summary>
            public bool IsTempUnlockAuthority;
        }
        #endregion
        #region 删除门锁
        /// <summary>
        /// 删除门锁
        /// </summary>
        public class DeleteDoorLockData : BaseDoorLockServerData
        {
            /// <summary>
            /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
            /// </summary>
            public string PrimaryId = "";
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId (可选)
            /// DelDoorLockDelType 门锁删除类型(0: 根椐门锁主键(云端主键)删除(单条删除)、1:根椐门锁Id批量删除(凡是与门锁Id相同都会删除)、2:根椐门锁Id及门锁本地用户Id批量删除(这个门锁Id这个门锁本地用户Id均会被删除)) -->键名 : DelDoorLockDelType 默认值: 0
            /// </summary>
            public int DelDoorLockDelType;
        }
        #endregion
        #region 添加门锁临时密码
        /// <summary>
        ///  添加门锁
        /// </summary>
        public class AddDoorLockTempPasswordData
        {
            /// <summary>
            /// RequestVersion
            /// </summary>
            public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
            /// <summary>
            /// LoginAccessToken
            /// </summary>
            public string LoginAccessToken = Shared.Common.Config.Instance.Token;
            /// <summary>
            /// 住宅Id -->键名 : HomeId
            /// </summary>
            public string HomeId = Shared.Common.Config.Instance.HomeId;
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId
            /// </summary>
            public string LocalDoorLockId = "";
            /// <summary>
            /// 临时密码Id -->键名 : TempPwdId
            /// </summary>
            public string TempPwdId = "";
            /// <summary>
            /// 临时密码 -->键名 : TempPwd
            /// </summary>
            public string TempPwd = "";
            /// <summary>
            /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
            /// </summary>
            public DateTime ValidBeginTime;
            /// <summary>
            /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
            /// </summary>
            public DateTime ValidEndTime;
            /// <summary>
            /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
            /// </summary>
            public bool IsOtherAccountCtrl = false;
        }
        /// <summary>
        /// 添加门锁结果
        /// </summary>
        public class AddDoorLockTempPasswordDataRes : AddDoorLockDataRes
        {
        }
        #endregion
        #region 删除门锁临时密码
        /// <summary>
        ///  删除门锁
        /// </summary>
        public class DelDoorLockTempPasswordData
        {
            /// <summary>
            /// RequestVersion
            /// </summary>
            public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
            /// <summary>
            /// LoginAccessToken
            /// </summary>
            public string LoginAccessToken = Shared.Common.Config.Instance.Token;
            /// <summary>
            /// 住宅Id -->键名 : HomeId
            /// </summary>
            public string HomeId = Shared.Common.Config.Instance.HomeId;
            /// <summary>
            /// LocalDoorLockId 搜索本地门锁Id -->键名 : LocalDoorLockId  默认值: null
            /// </summary>
            public string LocalDoorLockId = "";
            /// <summary>
            /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
            /// </summary>
            public bool IsOtherAccountCtrl = false;
        }
        /// <summary>
        /// 删除门锁结果
        /// </summary>
        public class DelDoorLockTempPasswordDataRes : AddDoorLockDataRes
        {
        }
        #endregion
        #region 更新门锁临时密码
        /// <summary>
        ///  更新门锁
        /// </summary>
        public class ModifyDoorLockTempPasswordData
        {
            /// <summary>
            /// RequestVersion
            /// </summary>
            public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
            /// <summary>
            /// LoginAccessToken
            /// </summary>
            public string LoginAccessToken = Shared.Common.Config.Instance.Token;
            /// <summary>
            /// 住宅Id -->键名 : HomeId
            /// </summary>
            public string HomeId = Shared.Common.Config.Instance.HomeId;
            /// <summary>
            /// 门锁密码主键(获取门锁密码分页中的Id) -->键名 : DoorLockPwdId
            /// </summary>
            public string DoorLockPwdId = "";
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId
            /// </summary>
            public string LocalDoorLockId = "";
            /// <summary>
            /// 临时密码Id -->键名 : TempPwdId
            /// </summary>
            public string TempPwdId = "";
            /// <summary>
            /// 临时密码 -->键名 : TempPwd
            /// </summary>
            public string TempPwd = "";
            /// <summary>
            /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
            /// </summary>
            public DateTime ValidBeginTime;
            /// <summary>
            /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
            /// </summary>
            public DateTime ValidEndTime;
            /// <summary>
            /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
            /// </summary>
            public bool IsOtherAccountCtrl = false;
        }
        /// <summary>
        /// 添加门锁结果
        /// </summary>
        public class ModigDoorLockTempPasswordDataRes : AddDoorLockDataRes
        {
        }
        #endregion
        #region 获取门锁临时密码
        /// <summary>
        ///  获取门锁
        /// </summary>
        public class GetDoorLockTempPasswordData
        {
            /// <summary>
            /// RequestVersion
            /// </summary>
            public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
            /// <summary>
            /// LoginAccessToken
            /// </summary>
            public string LoginAccessToken = Shared.Common.Config.Instance.Token;
            /// <summary>
            /// 住宅Id -->键名 : HomeId
            /// </summary>
            public string HomeId = Shared.Common.Config.Instance.HomeId;
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId
            /// </summary>
            public string LocalDoorLockId = "";
            /// <summary>
            /// 临时密码Id -->键名 : TempPwdId
            /// </summary>
            public string TempPwdId = "";
            /// <summary>
            /// 临时密码 -->键名 : TempPwd
            /// </summary>
            public string TempPwd = "";
            /// <summary>
            /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
            /// </summary>
            public DateTime? ValidBeginTime;
            /// <summary>
            /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
            /// </summary>
            public DateTime? ValidEndTime;
            /// <summary>
            /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
            /// </summary>
            public bool IsOtherAccountCtrl = false;
        }
        /// <summary>
        /// 获取门锁临时密码结果
        /// </summary>
        [Serializable]
        public class GetDoorLockTempPasswordDataRes
        {
            public List<CloudDoorLockTempPasswordObj> PageData = new List<CloudDoorLockTempPasswordObj>();
            public int PageIndex;
            public int PageSize;
            public int TotalCount;
            public int TotalPages;
            public bool HasPreviousPage;
            public bool HasNextPage;
        }
        [Serializable]
        public class CloudDoorLockTempPasswordObj
        {
            /// <summary>
            /// 门锁Id -->键名 : DoorLockId
            /// </summary>
            public string LocalDoorLockId = "";
            /// <summary>
            /// 临时密码Id -->键名 : TempPwdId
            /// </summary>
            public string TempPwdId = "";
            /// <summary>
            /// 临时密码 -->键名 : TempPwd
            /// </summary>
            public string TempPwd = "";
            /// <summary>
            /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
            /// </summary>
            public DateTime ValidBeginTime;
            /// <summary>
            /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
            /// </summary>
            public DateTime ValidEndTime;
            /// <summary>
            /// 【门锁云端主键】,用于【添加门锁历史】接口中的DoorLockId参数及【删除门锁】接口中的PrimaryId参数,注意不是网关中的【门锁Id
            /// </summary>
            public string Id;
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime CreatedOnUtc;
        }
        /// <summary>
        /// 从云服务器中获取门锁临时密码
        /// </summary>
        public static async System.Threading.Tasks.Task<GetDoorLockTempPasswordDataRes> GetDoorLockTempPasswordFromServer(string RequestName, GetDoorLockTempPasswordData getDoorLockTempPasswordData)
        {
            return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<GetDoorLockTempPasswordDataRes>>)(async () =>
            {
                GetDoorLockTempPasswordDataRes listInfo = null;
                var revertObj = await SendDoorLockToServer(RequestName, getDoorLockTempPasswordData);
                if (revertObj != null && revertObj.ResponseData != null)
                {
                    var result = revertObj.ResponseData.ToString();
                    if (result != null)
                    {
                        listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<GetDoorLockTempPasswordDataRes>(result);
                    }
                }
                return listInfo;
            }));
        }
        #endregion
        #region 获取门锁
        /// <summary>
        ///  获取门锁
        /// </summary>
        public class GetDoorLockData : BaseDoorLockServerData
        {
            /// <summary>
            /// 云端帐号Id -->键名 : CloudAccountId (可选)
            /// </summary>
            public string CloudAccountId = "";
            /// <summary>
            /// 第几页
            /// </summary>
            public PageSetting pageSetting = new PageSetting();
        }
        /// <summary>
        ///  获取门锁
        /// </summary>
        public class PageSetting
        {
            /// <summary>
            /// 第几页
            /// </summary>
            public int Page = 1;
            /// <summary>
            /// 第几页
            /// </summary>
            public int PageSize = 10;
        }
        [Serializable]
        public class GetDoorLockDataRes
        {
            public List<CloudDoorLockObj> PageData = new List<CloudDoorLockObj>();
            public int PageIndex;
            public int PageSize;
            public int TotalCount;
            public int TotalPages;
            public bool HasPreviousPage;
            public bool HasNextPage;
        }
        [Serializable]
        public class CloudDoorLockObj
        {
            /// <summary>
            /// 门锁Id
            /// </summary>
            public string DoorLockId;
            /// <summary>
            /// 云端帐号Id
            /// </summary>
            public string CloudAccountId;
            /// <summary>
            /// OpenLockMode 开锁方式(密码、指纹、IC卡)
            /// </summary>
            public int OpenLockMode;
            /// <summary>
            /// 门锁本地用户Id
            /// </summary>
            public string DoorLockLocalUserId;
            /// <summary>
            /// 住宅Id
            /// </summary>
            public byte[] Data;
            /// <summary>
            /// 用户Id备注
            /// </summary>
            public string UserIdRemarks;
            /// <summary>
            /// 是否为管理员门锁
            /// </summary>
            public bool IsAdminDoorLock;
            /// <summary>
            /// 是否为管理员门锁
            /// </summary>
            public bool IsFreezeUser;
            /// <summary>
            /// 是否为管理员门锁
            /// </summary>
            public bool IsTempUnlockAuthority;
            /// <summary>
            /// 录入时间
            /// </summary>
            public DateTime EntryTime;
            /// <summary>
            /// 最后更新时间
            /// </summary>
            public string LastChangeTime;
            /// <summary>
            /// 【门锁云端主键】,用于【添加门锁历史】接口中的DoorLockId参数及【删除门锁】接口中的PrimaryId参数,注意不是网关中的【门锁Id
            /// </summary>
            public string Id;
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime CreatedOnUtc;
        }
        /// <summary>
        /// 获取门锁云服务器
        /// </summary>
        public static async System.Threading.Tasks.Task<GetDoorLockDataRes> GetDoorLockInfoFromServer(string RequestName, GetDoorLockData getDoorLockData)
        {
            return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<GetDoorLockDataRes>>)(async () =>
            {
                GetDoorLockDataRes listInfo = null;
                var revertObj = await SendDoorLockToServer(RequestName, getDoorLockData);
                if (revertObj != null && revertObj.ResponseData != null)
                {
                    var result = revertObj.ResponseData.ToString();
                    if (result != null)
                    {
                        listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<GetDoorLockDataRes>(result);
                    }
                }
                return listInfo;
            }));
        }
        #endregion
        /// <summary>
        /// 发送门锁数据到服务器,只回复状态,没有数据处理
        /// </summary>
        /// <returns>获取从接口那里取到的ResponsePack</returns>
        /// <param name="RequestName">访问地址</param>
        /// <param name="obj">一个类</param>
        public static async Task<ResponsePack> SendDoorLockToServer(string RequestName, object obj)
        {
            try
            {
                //序列化对象
                var requestJson = JsonConvert.SerializeObject(obj);
                var byteData = System.Text.Encoding.UTF8.GetBytes(requestJson);
                byte[] result1 = null;
                //访问接口
                if (UserCenterResourse.UserInfo.AuthorityNo == 1)
                {
                    result1 = await CommonPage.Instance.RequestHttpsZigbeeBytesResultAsync(RequestName, byteData);
                }
                else
                {
                    result1 = await CommonPage.Instance.RequestZigbeeHttpsByAdmin(RequestName, byteData);
                }
                if (result1 != null)
                {
                    var result2 = Encoding.UTF8.GetString(result1);
                    if (result2 != null)
                    {
                        var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Shared.Common.ResponseEntity.ResponsePack>(result2);
                        return result;
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
        /// <summary>
        /// 获取子账户信息
        /// </summary>
        static List<Shared.Phone.UserCenter.MemberInfoRes> DoorLockAccountList = new List<Shared.Phone.UserCenter.MemberInfoRes> { };
        public static async System.Threading.Tasks.Task<List<Shared.Phone.UserCenter.MemberInfoRes>> GetSubAccountByDistributedMark()
        {
            DoorLockAccountList.Clear();
            return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<List<Shared.Phone.UserCenter.MemberInfoRes>>>)(async () =>
           {
               var pra = new Shared.Phone.UserCenter.MemberListInfoPra();
               string result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeUsers/GetSubAccountByDistributedMark", false, pra);
               var listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Shared.Phone.UserCenter.MemberInfoRes>>(result);
               return listInfo;
           }));
        }
        /// <summary>
        /// 服务器获取数据失败提示
        /// </summary>
        public void FailureToServer()
        {
            Application.RunOnMainThread(() =>
            {
                var alert = new Alert(Language.StringByID(Shared.R.MyInternationalizationString.TIP), Language.StringByID(Shared.R.MyInternationalizationString.RequestServerFailed), Language.StringByID(Shared.R.MyInternationalizationString.Confrim));
                alert.Show();
            });
        }
        #endregion
        #region  与网关通讯接口
        #region 门锁操作事件通知
        /// <summary>
        /// 门锁操作事件通知
        /// </summary>
        public DoorLockOperatingEventNotificationCommand doorLockOperatingEventNotificationCommand;
        /// <summary>
        /// 门锁操作事件通知
        /// </summary>
        [System.Serializable]
        public class DoorLockOperatingEventNotificationCommand
        {
            /// <summary>
            /// 用户id
            ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id
            /// </summary>
            public int UserID;
            /// <summary>
            /// 事件触发源
            /// 常用:
            /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹
            ///不常用:
            /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定)
            /// </summary>
            public int OperationEventSoure;
            /// <summary>
            /// 事件码
            /// 常用:
            /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件
            ///不常用:
            /// 请查看枚举
            /// </summary>
            public int OperationEventCode;
            /// <summary>
            /// 保留,默认0
            /// </summary>
            public int PIN;
            /// <summary>
            /// 门锁本地当前时间的时间戳
            /// </summary>
            public int ZigbeeLocalTime;
        }
        public class AccountsObj
        {
            /// <summary>
            /// 关联app账号
            /// </summary>
            public string Account;
            /// <summary>
            /// 保留
            /// </summary>
            public int Type;
            /// <summary>
            ///  保留
            /// </summary>
            public int Status;
        }
        /// <summary>
        /// “OperationEventSoure”列表
        /// </summary>
        public enum OperationEventSoure
        {
            /// <summary>
            /// 键盘/密码
            /// </summary>
            Keypad = 0,
            /// <summary>
            /// Zigbee无线
            /// </summary>
            RF = 1,
            /// <summary>
            /// 手动
            /// </summary>
            Manual = 2,
            /// <summary>
            /// 射频卡
            /// </summary>
            RFID = 3,
            /// <summary>
            /// 指纹
            /// </summary>
            Fingerprint = 15,
            /// <summary>
            /// Indeterminate(不确定)
            /// </summary>
            Indeterminate = 255,
        }
        /// <summary>
        /// “OperationEventSoure”类型为“Keypad”即密码 的“OperationEventCode”事件
        /// </summary>
        public enum KeypadEventDescription
        {
            /// <summary>
            /// 未知事件
            /// </summary>
            UnknownEvent = 0,
            /// <summary>
            /// Lock命令成功事件
            /// </summary>
            LockSuccessEvent = 1,
            /// <summary>
            /// Unlock命令成功事件
            /// </summary>
            UnlockSuccessEvent = 2,
            /// <summary>
            /// Lock命令:error,invalid PIN事件
            /// </summary>
            LockInvalidPinEvent = 3,
            /// <summary>
            /// Lock命令:error,invalid schedule事件
            /// </summary>
            LockInvalidScheduleEvent = 4,
            /// <summary>
            /// Unlock命令:error,invalid PIN事件
            /// </summary>
            UnlockInvalidPinEvent = 5,
            /// <summary>
            /// Unlock命令:error,invalid schedule事件Unlock命令:error,invalid schedule事件
            /// </summary>
            UnlockInvalidScheduleEvent = 6,
            /// <summary>
            /// 非访问用户操作事件
            /// </summary>
            NonAccess = 15,
        }
        /// <summary>
        /// “OperationEventSoure”类型为“RF” 的“OperationEventCode”事件
        /// </summary>
        public enum RfEventDescription
        {
            /// <summary>
            /// 未知事件
            /// </summary>
            UnknownEvent = 0,
            /// <summary>
            /// Lock命令成功事件
            /// </summary>
            LockSuccessEvent = 1,
            /// <summary>
            /// Unlock命令成功事件
            /// </summary>
            UnlockSuccessEvent = 2,
            /// <summary>
            /// Lock命令:error,invalid code事件
            /// </summary>
            LockInvalidPinEvent = 3,
            /// <summary>
            /// Lock命令:error,invalid schedule事件
            /// </summary>
            LockInvalidScheduleEvent = 4,
            /// <summary>
            /// Unlock命令:error,invalid code事件
            /// </summary>
            UnlockInvalidPinEvent = 5,
            /// <summary>
            /// Unlock命令:error,invalid schedule事件
            /// </summary>
            UnlockInvalidScheduleEvent = 6,
        }
        /// <summary>
        /// “OperationEventSoure”类型为“Manual” 的“OperationEventCode”事件
        /// </summary>
        public enum ManualEventDescription
        {
            /// <summary>
            /// 未知事件
            /// </summary>
            UnknownEvent = 0,
            /// <summary>
            /// Thumbturn Lock;手动转动上锁
            /// </summary>
            ThumbturnLockEvent = 1,
            /// <summary>
            /// Thumbturn Unlock;手动转动解锁
            /// </summary>
            UnlockSuccessEvent = 2,
            /// <summary>
            /// One touch Lock;一键上锁
            /// </summary>
            LockInvalidPinEvent = 7,
            /// <summary>
            ///Key Lock;按键上锁
            /// </summary>
            LockInvalidScheduleEvent = 8,
            /// <summary>
            /// Key Unlock;按键解锁
            /// </summary>
            UnlockInvalidPinEvent = 9,
            /// <summary>
            /// Auto lock;自动上锁
            /// </summary>
            UnlockInvalidScheduleEvent = 10,
            /// <summary>
            /// Schedule Lock;时间表上锁
            /// </summary>
            ScheduleLockEvent = 11,
            /// <summary>
            /// Schedule Unlock;时间表解锁
            /// </summary>
            ScheduleUnlockEvent = 12,
            /// <summary>
            /// Manual Lock(Key or Thumbturn);手动上锁
            /// </summary>
            ManualLockEvent = 13,
            /// <summary>
            ///anual Unlock(Key or Thumbturn);手动解锁
            /// </summary>
            ManualUnlockEvent = 14,
        }
        /// <summary>
        /// “OperationEventSoure”类型为“RFID” 的“OperationEventCode”事件
        /// </summary>
        public enum RfidEventDescription
        {
            /// <summary>
            /// 未知事件
            /// </summary>
            UnknownEvent = 0,
            /// <summary>
            /// Lock命令成功事件
            /// </summary>
            LockSuccessEvent = 1,
            /// <summary>
            /// Unlock命令成功事件
            /// </summary>
            UnlockSuccessEvent = 2,
            /// <summary>
            /// Lock命令:error,invalid RFID ID事件
            /// </summary>
            LockInvalidRfidIdEvent = 3,
            /// <summary>
            /// Lock命令:error,invalid schedule事件
            /// </summary>
            LockInvalidScheduleEvent = 4,
            /// <summary>
            /// Unlock命令:error,invalid RFID ID事件
            /// </summary>
            UnlockInvalidRfidIdEvent = 5,
            /// <summary>
            /// Unlock命令:error,invalid schedule事件
            /// </summary>
            UnlockInvalidScheduleEvent = 6,
        }
        #endregion
        #region 门锁编程事件通知
        /// <summary>
        /// 门锁编程事件通知
        /// </summary>
        public DoorLockProgrammingEventNotificationCommand doorLockProgrammingEventNotificationCommand;
        /// <summary>
        /// 门锁编程事件通知
        /// </summary>
        [System.Serializable]
        public class DoorLockProgrammingEventNotificationCommand
        {
            /// <summary>
            /// 用户id
            ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id
            /// </summary>
            public int UserID;
            /// <summary>
            /// 保留
            /// </summary>
            public int UserType;
            /// <summary>
            ///  保留
            /// </summary>
            public int UserStatus;
            /// <summary>
            /// 编程事件触发源
            /// 常用:
            /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹
            ///不常用:
            /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定)
            /// </summary>
            public int ProgramEventSoure;
            /// <summary>
            /// 编程事件码
            /// 常用:
            /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件
            ///不常用:
            /// 请查看枚举
            /// </summary>
            public int ProgramEventCode;
            /// <summary>
            /// 保留,默认0
            /// </summary>
            public int PIN;
            /// <summary>
            /// 门锁本地当前时间的时间戳
            /// </summary>
            public int ZigbeeLocalTime;
        }
        #endregion
        #region 矫正门锁时间
        /// <summary>
        /// 矫正门锁时间
        /// </summary>
        /// <param name="timestamp"></param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task<SetWritableValueResponAllData> RectifyDoorLockTimeAsync(int timestamp)
        {
            if (Gateway == null)
            {
                return null;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                SetWritableValueResponAllData d = null;
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            d = new SetWritableValueResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            d = new SetWritableValueResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "SetWritableValue_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { DeviceID = jobject.Value<int>("Device_ID"), DeviceAddr = jobject.Value<string>("DeviceAddr"), DeviceEpoint = jobject.Value<int>("Epoint"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<SetWritableValueResponData>(jobject["Data"].ToString());
                        if (tempData == null)
                        {
                            d = new SetWritableValueResponAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            d = new SetWritableValueResponAllData { setWritableValueResponData = tempData };
                            DebugPrintLog($"UI收到通知后的主题_{ topic}");
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("SetWritableValue_Actions 启动" + "_" + System.DateTime.Now.ToString());
                try
                {
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 10 }, { "Command", 120 } };
                    var data = new JObject { { "Undivided", 0 }, { "AttributeId", 0 }, { "AttributeDataType", 226 }, { "AttributeData", timestamp } };
                    jObject.Add("Data", data);
                    Gateway.Send("SetWritableValue", jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (d != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    d = new SetWritableValueResponAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("SetWritableValue_Actions 退出" + System.DateTime.Now.ToString());
                return d;
            });
        }
        /// <summary>
        /// 网关版本信息,网关反馈信息
        /// </summary>
        public SetWritableValueResponAllData setWritableValueResponAllData;
        /// <summary>
        /// 网关版本信息,网关反馈信息
        /// </summary>
        [System.Serializable]
        public class SetWritableValueResponAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 网关版本信息
            /// </summary>
            public SetWritableValueResponData setWritableValueResponData;
        }
        /// <summary>
        /// 设置可写属性的值的数据
        /// </summary>
        [System.Serializable]
        public class SetWritableValueResponData
        {
            /// <summary>
            /// 配置属性所在的cluster
            /// </summary>
            public int Cluster;
            /// <summary>
            /// 0:配置成功(若配置成功,下面的AttributeId字段不存在)
            ///<para>134:不支持该属性</para>
            ///<para>135:无效的属性值</para>
            ///<para>141:无效的数据类型</para>
            /// </summary>
            public int Status;
        }
        #endregion
        #endregion
        #region 与设备通讯接口(私有命令)
        #region 用户管理控制
        ///<summary >
        ///用户管理控制
        /// <para>passData:透传数据</para>
        /// </summary>
        public async System.Threading.Tasks.Task<DefaultControlResponseAllData> DefaultControlAsync(string passData)
        {
            DefaultControlResponseAllData result = null;
            if (Gateway == null)
            {
                result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 16)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0002")
                                    {
                                        var tempD = new DefaultControlResponseData();
                                        tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        if (tempD.command == "0450")
                                        {
                                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                                            DebugPrintLog($"UI收到通知后的主题_command:0450_{ topic}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new DefaultControlResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 用户管理发送数据
        /// userIdList:个数不能超过10个
        /// </summary>
        public string FreezeAccountData(List<int> userIdList, AccessType accessType)
        {
            string data = "";
            string dataLength = "";
            string dataComand1 = "50";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "";
            string delUserTypeStr = "";
            string userIdStr = "";
            try
            {
                if (userIdList.Count == 0)
                {
                    return null;
                }
                if (userIdList.Count > 9)
                {
                    return null;
                }
                var tempLength = 5 + userIdList.Count * 2;
                string tempLength1 = Convert.ToString(tempLength, 16);
                switch (tempLength1.Length)
                {
                    case 1:
                        dataLength = "0" + tempLength1.ToUpper();
                        break;
                    case 2:
                        dataLength = tempLength1.ToUpper();
                        break;
                }
                var tempAddDataLength = 1 + userIdList.Count * 2;
                string tempAddDataLength1 = Convert.ToString(tempAddDataLength, 16);
                switch (tempAddDataLength1.Length)
                {
                    case 1:
                        addDataLength = "0" + tempAddDataLength1.ToUpper();
                        break;
                    case 2:
                        addDataLength = tempAddDataLength1.ToUpper();
                        break;
                }
                switch ((int)accessType)
                {
                    case 0:
                        delUserTypeStr = "00";
                        break;
                    case 1:
                        delUserTypeStr = "01";
                        break;
                    case 2:
                        delUserTypeStr = "20";
                        break;
                    case 3:
                        delUserTypeStr = "21";
                        break;
                    case 4:
                        delUserTypeStr = "10";
                        break;
                    case 5:
                        delUserTypeStr = "30";
                        break;
                    case 6:
                        delUserTypeStr = "31";
                        break;
                }
                var sbString = new System.Text.StringBuilder();
                foreach (var userId in userIdList)
                {
                    string temp = Convert.ToString(userId, 16);
                    switch (temp.Length)
                    {
                        case 1:
                            userIdStr = "0" + temp + "00";
                            break;
                        case 2:
                            userIdStr = temp + "00";
                            break;
                        case 3:
                            var thirdBit = temp.Substring(temp.Length - 2, 1);
                            userIdStr = temp + "0" + thirdBit;
                            break;
                        case 4:
                            userIdStr = temp;
                            break;
                    }
                    sbString.Append(userIdStr.ToString().ToUpper());
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   delUserTypeStr + sbString;
            }
            catch { };
            return data;
        }
        /// <summary>
        /// 用户管理发送数据
        /// </summary>
        public string SetUserAccessData(int userId, AccessType accessType)
        {
            string data = "";
            string dataLength = "07";
            string dataComand1 = "50";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "03";
            string delUserTypeStr = "";
            string userIdStr = "";
            try
            {
                switch ((int)accessType)
                {
                    case 0:
                        delUserTypeStr = "00";
                        break;
                    case 1:
                        delUserTypeStr = "01";
                        break;
                    case 2:
                        delUserTypeStr = "20";
                        break;
                    case 3:
                        delUserTypeStr = "21";
                        break;
                }
                var sbString = new System.Text.StringBuilder();
                string temp = Convert.ToString(userId, 16);
                switch (temp.Length)
                {
                    case 1:
                        userIdStr = "0" + temp + "00";
                        break;
                    case 2:
                        userIdStr = temp + "00";
                        break;
                    case 3:
                        var thirdBit = temp.Substring(temp.Length - 2, 1);
                        userIdStr = temp + "0" + thirdBit;
                        break;
                    case 4:
                        userIdStr = temp;
                        break;
                }
                sbString.Append(userIdStr.ToString().ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   delUserTypeStr + sbString;
            }
            catch { };
            return data;
        }
        /// <summary>
        /// 用户管理发送数据回复
        /// </summary>
        public DefaultControlResponseAllData defaultControlResponseAllData;
        [System.Serializable]
        public class DefaultControlResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 用户管理数据回复
            /// </summary>
            public DefaultControlResponseData defaultControlResponseData;
        }
        /// <summary>
        /// 用户管理数据回复
        /// </summary>
        [System.Serializable]
        public class DefaultControlResponseData
        {
            /// <summary>
            ///响应操作码(0-ffff)
            /// </summary>
            public string command = "";
            /// <summary>
            /// 状态值
            /// <para>默认响应结果:
            ///<para>0 成功</para>
            ///<para>1 失败</para>
            ///<para>2 用户不存在</para>
            ///<para>32 冻结成功</para>
            ///<para>34 冻结失败</para>
            ///<para>33 解冻成功</para>
            ///<para>35 解冻失败</para>
            /// </summary>
            public int status = -1;
        }
        public enum AccessType
        {
            /// <summary>
            /// 0x00 删除全部临时用户
            /// </summary>
            DelAllUsers = 0,
            /// <summary>
            /// 0x01 删除指定用户(按编号)
            /// </summary>
            DelCurrentUser = 1,
            /// <summary>
            /// 0x20 冻结指定用户
            /// </summary>
            DisEnable = 2,
            /// <summary>
            /// 0x21 解冻指定用户
            /// </summary>
            Enable = 3,
            /// <summary>
            /// 0x10 多个指定用户删除
            /// </summary>
            DelMoreUsers = 4,
            /// <summary>
            /// 0x30 多个指定用户冻结
            /// </summary>
            DisEnableMoreUsers = 5,
            /// <summary>
            /// 0x31 多个指定用户解冻
            /// </summary>
            EnableMoreUsers = 6,
        }
        #endregion
        #region 验证门锁密码
        ///<summary >
        ///验证门锁密码
        ///<para>inputPassword:输入的门锁密码</para>
        /// </summary>
        public async System.Threading.Tasks.Task<VerifyPasswordResponseAllData> VerifyPasswordAsync(string inputPassword)
        {
            VerifyPasswordResponseAllData result = null;
            if (Gateway == null)
            {
                result = new VerifyPasswordResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new VerifyPasswordResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new VerifyPasswordResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new VerifyPasswordResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 12)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0454")
                                    {
                                        var result1 = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                                        result = new VerifyPasswordResponseAllData { result = result1 };
                                        DebugPrintLog($"UI收到通知后的主题_command:0454_{ topic}");
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var getPw = await GetkeyPassword();
                    var passData = VerifyPasswordData(inputPassword, getPw);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null && result.result == 0)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    result = new VerifyPasswordResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 验证门锁密码
        /// </summary>
        public string VerifyPasswordData(string keyPassword, int password, int fixedPassword = 0x190605)
        {
            string data = "";
            string dataLength = "08";
            string dataComand1 = "53";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "04";
            string passwordStr = "";
            try
            {
                int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
                var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + fixedPassword, 16);
                pawStr = pawStr.PadLeft(8, '0');
                for (int i = 6; i >= 0; i = i - 2)
                {
                    passwordStr += pawStr.Substring(i, 2);
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                 passwordStr;
            }
            catch { };
            return data;
        }
        /// <summary>
        /// 用户管理发送数据回复
        /// </summary>
        public VerifyPasswordResponseAllData verifyPasswordResponseAllData;
        [System.Serializable]
        public class VerifyPasswordResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 用户管理数据回复
            /// <para>0:成功</para>
            ///<para>1:失败</para>
            /// </summary>
            public int result = -1;
        }
        #endregion
        #region 远程开锁
        ///<summary >
        ///远程开锁
        ///<para>inputPassword: 输入密码/para>
        /// </summary>
        public async System.Threading.Tasks.Task<RemoteResponseAllData> RemoteControlAsync(string inputPassword)
        {
            RemoteResponseAllData result = null;
            if (Gateway == null)
            {
                result = new RemoteResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new RemoteResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new RemoteResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    else if (topic == $"{gatewayID}/DoorLock/DoorLockOperatingEventNotificationCommand")
                    {
                        var OperatingEventNotificationDatad = Newtonsoft.Json.JsonConvert.DeserializeObject<ZigBee.Device.DoorLock.DoorLockOperatingEventNotificationCommand>(jobject["Data"].ToString());
                        if (OperatingEventNotificationDatad != null)
                        {
                            if (OperatingEventNotificationDatad.OperationEventSoure == 1 && OperatingEventNotificationDatad.OperationEventCode == 5)
                            {
                                result = new RemoteResponseAllData { IsPawDispear = true };
                            }
                        }
                    }
                    else if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new RemoteResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 16)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0002")
                                    {
                                        var tempD = new RemoteResponseData();
                                        tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        if (tempD.command == "0462")
                                        {
                                            result = new RemoteResponseAllData { responseData = tempD };
                                            DebugPrintLog($"UI收到通知后的主题_command:0462_{ topic}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var getPw = await GetkeyPassword();
                    var passData = RemoteData(inputPassword, getPw);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 5000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result == null)
                    {
                        continue;
                    }
                    if (result.responseData != null && result.responseData.command == "0462")
                    {
                        break;
                    }
                    if (result.IsPawDispear == true)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    result = new RemoteResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 远程发送数据
        /// </summary>
        string RemoteData(string keyPassword, int password, int fixedPassword = 0x190605)
        {
            string data = "";
            string dataLength = "08";
            string dataComand1 = "62";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "04";
            string passwordStr = "";
            try
            {
                int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
                var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + fixedPassword, 16);
                pawStr = pawStr.PadLeft(8, '0');
                for (int i = 6; i >= 0; i = i - 2)
                {
                    passwordStr += pawStr.Substring(i, 2);
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                 passwordStr;
            }
            catch { };
            return data;
        }
        /// <summary>
        ///  远程回复数据
        /// </summary>
        public RemoteResponseAllData remoteResponseAllData;
        [System.Serializable]
        public class RemoteResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 临时密码回复数据
            /// </summary>
            public RemoteResponseData responseData;
            /// <summary>
            /// 是否密码被删除
            /// </summary>
            public bool IsPawDispear = false;
        }
        /// <summary>
        /// 用户管理数据回复
        /// </summary>
        [System.Serializable]
        public class RemoteResponseData
        {
            /// <summary>
            ///响应操作码(0-ffff)
            /// </summary>
            public string command = "";
            /// <summary>
            /// 状态值
            /// <para>默认响应结果:
            ///<para>0 成功</para>
            ///<para>1 失败</para>
            /// </summary>
            public int status = -1;
        }
        #endregion
        #region 临时密码发送数据
        ///<summary >
        ///临时密码
        ///<para>inputPassword: 输入密码/para>
        /// </summary>
        public async System.Threading.Tasks.Task<TempPasswordResponseAllData> TempPasswordAsync(string inputPassword, System.DateTime startTime, System.DateTime endTime, string fixedPassword = "190605")
        {
            TempPasswordResponseAllData result = null;
            if (Gateway == null)
            {
                result = new TempPasswordResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new TempPasswordResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new TempPasswordResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new TempPasswordResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 16)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0002")
                                    {
                                        var tempD = new TempPasswordResponseData();
                                        tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        if (tempD.command == "0463")
                                        {
                                            result = new TempPasswordResponseAllData { responseData = tempD };
                                            DebugPrintLog($"UI收到通知后的主题_command:0463_{ topic}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var getPw = await GetkeyPassword();
                    var passData = TempPasswordData(inputPassword, getPw, startTime, endTime);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null && result.responseData != null && result.responseData.command == "0463")
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new TempPasswordResponseAllData
                    { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 临时密码发送数据
        /// </summary>
        public string TempPasswordData(string keyPassword, int password, System.DateTime startTime, System.DateTime endTime)
        {
            string data = "";
            string dataLength = "10";
            string dataComand1 = "63";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "0c";
            string passwordStr = "";
            string vaildTimeStr = "";
            string invalidTimeStr = "";
            try
            {
                int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
                var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + 0x190605, 16);
                pawStr = pawStr.PadLeft(8, '0');
                for (int i = 6; i >= 0; i = i - 2)
                {
                    passwordStr += pawStr.Substring(i, 2);
                }
                var startTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(startTime);
                var endTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(endTime);
                startTimeStr = string.Format("{0:X}", System.Convert.ToInt64(startTimeStr));
                endTimeStr = string.Format("{0:X}", System.Convert.ToInt64(endTimeStr));
                for (int i = 6; i >= 0; i = i - 2)
                {
                    vaildTimeStr += startTimeStr.Substring(i, 2);
                    invalidTimeStr += endTimeStr.Substring(i, 2);
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   passwordStr + vaildTimeStr + invalidTimeStr;
            }
            catch (Exception ex)
            {
                var mess = ex.Message;
            };
            return data;
        }
        /// <summary>
        /// 临时密码回复数据
        /// </summary>
        public TempPasswordResponseAllData tempPasswordResponseAllData;
        [System.Serializable]
        public class TempPasswordResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 临时密码回复数据
            /// </summary>
            public TempPasswordResponseData responseData;
        }
        /// <summary>
        /// 临时密码回复数据
        /// </summary>
        [System.Serializable]
        public class TempPasswordResponseData
        {
            /// <summary>
            ///响应操作码(0-ffff)
            /// </summary>
            public string command = "";
            /// <summary>
            /// 状态值
            /// <para>0--注册成功</para>
            /// <para>1--注册失败</para>
            /// <para>2--用户已存在(重复密码)</para>
            /// <para>3-- 用户已满(+已满类型回复)</para>
            /// <para>4--有效时间重叠</para>
            /// </summary>
            public int status = -1;
        }
        #endregion
        #region 获取门锁密钥
        /// <summary>
        /// 门锁随机密码
        /// <para>获取加密的随机密钥,返回的密钥经过一个简单的加法加密加上0x190605,因此获取的密钥需要减上0x190605</para>
        /// </summary>
        /// <returns></returns>
        async System.Threading.Tasks.Task<int> GetkeyPassword()
        {
            string passwordStr = "";
            var result = await GetKeyPassworAsync();
            //返回小端
            if (result == null || result.keyPassword == null)
            {
                return 0;
            }
            for (int i = 6; i >= 0; i = i - 2)
            {
                passwordStr += result.keyPassword.Substring(i, 2);
            }
            var keyPasswordInt = System.Convert.ToInt32(passwordStr, 16);
            return keyPasswordInt - 0x190605;
        }
        ///<summary >
        ///获取门锁密钥
        /// </summary>
        async System.Threading.Tasks.Task<KeyPasswordInfo> GetKeyPassworAsync(int keyType = 0)
        {
            KeyPasswordInfo result = null;
            if (Gateway == null)
            {
                result = new KeyPasswordInfo { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new KeyPasswordInfo { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new KeyPasswordInfo { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new KeyPasswordInfo { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 20)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0461")
                                    {
                                        var kType = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                                        var keyPassword = data[12].ToString() + data[13].ToString() + data[14].ToString() + data[15].ToString() + data[16].ToString() + data[17].ToString() + data[18].ToString() + data[19].ToString();
                                        result = new KeyPasswordInfo { keyType = kType, keyPassword = keyPassword };
                                        DebugPrintLog($"UI收到通知后的主题_command:0460_{ topic}");
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = KeyPasswordData(keyType);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)//WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    result = new KeyPasswordInfo { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 获取门锁密钥
        /// </summary>
        string KeyPasswordData(int keyType)
        {
            string data = "";
            string dataLength = "05";
            string dataComand1 = "60";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "01";
            string keyTypeData = "";
            try
            {
                var tempTypeString = new System.Text.StringBuilder();
                var temp = Convert.ToString(keyType, 16);
                switch (temp.Length)
                {
                    case 1:
                        keyTypeData = "0" + temp;
                        break;
                    case 2:
                        keyTypeData = temp;
                        break;
                }
                tempTypeString.Append(keyTypeData.ToString().ToUpper());
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
            tempTypeString;
            }
            catch { };
            return data;
        }
        /// <summary>
        /// 获取门锁密钥回复
        /// </summary>
        [System.Serializable]
        public class KeyPasswordInfo
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            ///密钥类型
            ///<apra></apra>
            /// </summary>
            public int keyType = -1;
            /// <summary>
            /// 密钥
            /// </summary>
            public string keyPassword;
        }
        #endregion
        #region 读取锁上信息
        ///<summary >
        ///读取锁上信息
        /// </summary>
        public async System.Threading.Tasks.Task<DoorlockUserInfo> GetDoorlockUserInfoAsync()
        {
            DoorlockUserInfo result = null;
            int totalNum = 0;
            int currentNum = -1;
            DoorLockUserDetailData doorLockUserDetailData = new DoorLockUserDetailData { };
            if (Gateway == null)
            {
                result = new DoorlockUserInfo { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                var dateTime = DateTime.Now;
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (clientDataPassthroughResponseData != null)
                        {
                            if (clientDataPassthroughResponseData.PassData != null)
                            {
                                var data = clientDataPassthroughResponseData.PassData;
                                var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                if (command == "0452")
                                {
                                    dateTime = DateTime.Now;
                                    int returnAllLength = 2 + 2 * Convert.ToInt32(data[0].ToString() + data[1].ToString(), 16);
                                    int usefulLength = (returnAllLength - 16);
                                    int tempCount = 0;
                                    var listData = new List<string>();
                                    while (tempCount < usefulLength)
                                    {
                                        listData.Add(data[16 + tempCount].ToString());
                                        tempCount++;
                                    }
                                    for (int j = 0; j < listData.Count / 4; j++)
                                    {
                                        int curIndex = 4 * j;
                                        var userInfo = new UserObj();
                                        userInfo.UserType = Convert.ToInt32(listData[curIndex + 2].ToString(), 16);
                                        userInfo.UserId = Convert.ToInt32(listData[curIndex + 3].ToString() + listData[curIndex].ToString() + listData[curIndex + 1].ToString(), 16);
                                        doorLockUserDetailData.UserObjList.Add(userInfo);
                                    }
                                    doorLockUserDetailData.userType = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                                    doorLockUserDetailData.totalNum = Convert.ToInt32(data[12].ToString() + data[13].ToString(), 16);
                                    doorLockUserDetailData.currentNum = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                    totalNum = doorLockUserDetailData.totalNum;
                                    currentNum = doorLockUserDetailData.currentNum;
                                    result = new DoorlockUserInfo { doorLockUserDetailData = doorLockUserDetailData };
                                    DebugPrintLog($"UI收到通知后的主题_command:0451_{ topic}");
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = DoorlockUserData();
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                //接收一个包最多等3秒,没有收到就退出,单次数据包不超过30个用户
                while ((DateTime.Now - dateTime).TotalMilliseconds < 3000)
                {
                    await System.Threading.Tasks.Task.Delay(100);
                    if (totalNum == currentNum)
                    {
                        break;
                    }
                }
                //if ((DateTime.Now - dateTime).TotalMilliseconds > 3000)
                //{
                //    result = new DoorlockUserInfo { errorMessageBase = " 回复超时,请重新操作" };
                //}
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 读取锁上信息
        /// </summary>
        string DoorlockUserData()
        {
            string data = "";
            string dataLength = "05";
            string dataComand1 = "51";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "01";
            string keyTypeData = "01";
            try
            {
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + keyTypeData;
            }
            catch { };
            return data;
        }
        /// <summary>
        /// 读取锁上信息回复
        /// </summary>
        [System.Serializable]
        public class DoorlockUserInfo
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 门锁设备返回信息
            /// </summary>
            public DoorLockUserDetailData doorLockUserDetailData;
        }
        /// <summary>
        /// 门锁设备返回信息
        /// </summary>
        public class DoorLockUserDetailData
        {
            /// <summary>
            /// 类型(读取锁上已有用户)
            /// </summary>
            public int userType;
            /// <summary>
            /// 数据包总数
            /// </summary>
            public int totalNum;
            /// <summary>
            /// 数据包序号
            /// </summary>
            public int currentNum;
            /// <summary>
            /// 虚拟驱动信息
            /// </summary>
            public List<UserObj> UserObjList = new List<UserObj>();
        }
        public class UserObj
        {
            /// <summary>
            /// 门锁用户类型
            /// </summary>
            public int UserType;
            /// <summary>
            /// 门锁用户Id号
            /// </summary>
            public int UserId;
        }
        #endregion
        #region 音量
        ///<summary >
        ///获取音量
        /// </summary>
        public async System.Threading.Tasks.Task<VolumeResponseAllData> GetVolumeAsync()
        {
            VolumeResponseAllData result = null;
            if (Gateway == null)
            {
                result = new VolumeResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new VolumeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new VolumeResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new VolumeResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 14)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0456")
                                    {
                                        var tempD = new VolumeResponseData();
                                        tempD.command = data[10].ToString() + data[11].ToString();
                                        tempD.value = Convert.ToInt32(data[13].ToString(), 16);
                                        result = new VolumeResponseAllData { volumeResponseData = tempD };
                                        DebugPrintLog($"UI收到通知后的主题_command:0456_{ topic}");
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = VolumeData(-1);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null && result.volumeResponseData != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new VolumeResponseAllData
                    { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        ///<summary >
        ///音量
        ///<para>命令值: comandValue</para>
        ///<para>comandValue: 0 静音</para>
        ///<para>comandValue:1 最小音量</para>
        ///<para>comandValue:2~13 音量 </para>
        ///<para>comandValue:14 最大音量</para>
        /// </summary>
        public async System.Threading.Tasks.Task<DefaultControlResponseAllData> SetVolumeAsync(int comandValue)
        {
            DefaultControlResponseAllData result = null;
            if (Gateway == null)
            {
                result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 16)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0002")
                                    {
                                        var tempD = new DefaultControlResponseData();
                                        tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        if (tempD.command == "0455")
                                        {
                                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                                            DebugPrintLog($"UI收到通知后的主题_command:0455_{ topic}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = VolumeData(comandValue);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null && result.defaultControlResponseData != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new DefaultControlResponseAllData
                    { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 音量发送数据
        ///<para>comandValue: 0 静音</para>
        ///<para>comandValue:1 最小音量</para>
        ///<para>comandValue:2~13 音量 </para>
        ///<para>comandValue:14 最大音量</para>
        /// </summary>
        public string VolumeData(int comandValue)
        {
            string data = "";
            string dataLength = "05";
            string dataComand1 = "55";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "01";
            string cValue = "";
            try
            {
                if (comandValue >= 1)
                {
                    //comandValue = comandValue * 100;
                    //float v = (float)100 / 15;
                    //int vv = Convert.ToInt32(v * 100);
                    //var comandValueTemp = comandValue / vv;
                    //if (comandValueTemp == 0)
                    //{
                    //    comandValueTemp = 1;
                    //}
                    cValue = Convert.ToString(comandValue, 16).ToUpper();
                    cValue = "F" + cValue;
                }
                else
                {
                    switch (comandValue)
                    {
                        case -1:
                            cValue = "AA";
                            break;
                        case 0:
                            cValue = "EB";
                            break;
                    }
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   cValue;
            }
            catch (Exception ex)
            {
                var mess = ex.Message;
            };
            return data;
        }
        /// <summary>
        /// 音量回复数据
        /// </summary>
        public VolumeResponseAllData volumeResponseAllData;
        [System.Serializable]
        public class VolumeResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 音量回复数据
            /// </summary>
            public VolumeResponseData volumeResponseData;
        }
        /// <summary>
        /// 音量回复数据
        /// </summary>
        [System.Serializable]
        public class VolumeResponseData
        {
            /// <summary>
            ///命令
            ///<para>0x00 接收成功</para>
            ///<para>0xea 语音模式</para>
            ///<para>0xeb 静音模式</para>
            /// </summary>
            public string command = "";
            /// <summary>
            /// 音量值
            /// <para>0xf1~0xfe  1-14音量</para>
            /// <para>0 无音量值</para>
            /// </summary>
            public int value = -1;
        }
        #endregion
        #region 常开模式         
        /// <summary>
        /// 读取常开模式
        /// </summary>
        /// <returns></returns>
        public async System.Threading.Tasks.Task<OpenModeResponseAllData> ReadNormallyOpenModeFuncAsync()
        {
            OpenModeResponseAllData result = null;
            if (Gateway == null)
            {
                result = new OpenModeResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new OpenModeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new OpenModeResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new OpenModeResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 12)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0458")
                                    {
                                        result = new OpenModeResponseAllData();
                                        result.command = data[10].ToString() + data[11].ToString();
                                        DebugPrintLog($"UI收到通知后的主题_command:0457_{ topic}");
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = OpenModeData(SwitchMode.Obtain);
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new OpenModeResponseAllData
                    { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 设置常开模式
        /// </summary>
        /// <param name="IsNormallyOpenMode">是否打开常开模式:true:打开 false:关闭</param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task<DefaultControlResponseAllData> SetNormallyOpenModeFuncAsync(bool IsNormallyOpenMode)
        {
            DefaultControlResponseAllData result = null;
            if (Gateway == null)
            {
                result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.clientDataPassthroughResponseData.PassData;
                                if (data.Length == 16)
                                {
                                    var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                                    if (command == "0002")
                                    {
                                        var tempD = new DefaultControlResponseData();
                                        tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        if (tempD.command == "0457")
                                        {
                                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                                            DebugPrintLog($"UI收到通知后的主题_command:0457_{ topic}");
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
                try
                {
                    var passData = "";
                    if (IsNormallyOpenMode)
                    {
                        passData = OpenModeData(SwitchMode.NormallyOpen);
                    }
                    else
                    {
                        passData = OpenModeData(SwitchMode.NormallyClose);
                    }
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
                    var data = new JObject { { "PassData", passData } };
                    jObject.Add("Data", data);
                    Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (result != null && result.defaultControlResponseData != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
                {
                    result = new DefaultControlResponseAllData
                    { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 常开模式 发送数据
        /// </summary>
        public string OpenModeData(SwitchMode switchMode)
        {
            string data = "";
            string dataLength = "05";
            string dataComand1 = "57";
            string dataComand2 = "04";
            string dataSerialNum = "01";
            string addDataLength = "01";
            string cValue = "";
            try
            {
                switch (switchMode)
                {
                    case SwitchMode.Obtain:
                        cValue = "10";
                        break;
                    case SwitchMode.NormallyOpen:
                        cValue = "12";
                        break;
                    case SwitchMode.NormallyClose:
                        cValue = "13";
                        break;
                }
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   cValue;
            }
            catch (Exception ex)
            {
                var mess = ex.Message;
            };
            return data;
        }
        /// <summary>
        /// 常开模式 回复数据
        /// </summary>
        public OpenModeResponseAllData openModeResponseAllData;
        [System.Serializable]
        public class OpenModeResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 0x10 常开已开启
            /// <para>0x11 常开已关闭</para>
            /// </summary>
            public string command;
        }
        /// <summary>
        /// 开关模式
        /// </summary>
        public enum SwitchMode
        {
            /// <summary>
            /// 0x10 查询常开状态
            /// </summary>
            Obtain = 0x10,
            /// <summary>
            /// 0x12 开启常开
            /// </summary>
            NormallyOpen = 0x12,
            /// <summary>
            /// 0x13 关闭常开
            /// </summary>
            NormallyClose = 0x13
        }
        #endregion
        #endregion
      this.Type = DeviceType.DoorLock;
    }
    #region 门锁本地变量
    /// <summary>
    /// 本地门锁用户和账户列表
    /// key:门锁用户ID
    /// </summary>
    /// <returns></returns>
    public Dictionary<int, LocaDoorLockObj> localDoorLockUserList = new Dictionary<int, LocaDoorLockObj>();
    /// <summary>
    /// 本地门账户列表
    /// key:账户ID(主账户是GUID,子账户是分享过来的账户ID)
    /// </summary>
    /// <returns></returns>
    public Dictionary<string, LocaDoorLockObj> localDoorLockAccountList = new Dictionary<string, LocaDoorLockObj>();
    public string currentUserDisplayMethod = string.Empty;//当前用户显示方式
                                                          //本地所有账户列表
    public List<Shared.Phone.UserCenter.MemberInfoRes> localAllAccountList = new List<Shared.Phone.UserCenter.MemberInfoRes> { };
    /// <summary>
    /// 是否常开模式
    /// ture:常开; false:关闭
    /// </summary>
    public bool IsDoorLockNormallyMode = false;
    [Newtonsoft.Json.JsonIgnore]
    public string LocalTempPassword = string.Empty;//本地生成的临时密码
    public Dictionary<string, bool> IsFreezeAccount = new Dictionary<string, bool> { };//是否冻结子账户
    public Dictionary<string, bool> HasRemoteUnlockAccess = new Dictionary<string, bool> { };//是否给子账户拥有远程开锁的条件
    public Dictionary<string, bool> IsFailedToGetDoorLockInfo = new Dictionary<string, bool> { };//是否获取门锁数据失败
    [Newtonsoft.Json.JsonIgnore]
    public string RemoteUnlockPassword = string.Empty;//远程开锁密码
    public static int RemoteUnlockCount = 5;//远程开锁次数限制
    public static int failedCount = 3;//远程开锁失败次数
    public static DateTime minValue = DateTime.MinValue;
    #region 临时密码信息
    /// <summary>
    /// 用户管理发送数据回复
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public TempPasswordObject tempPasswordObject;
    /// <summary>
    /// 临时密码本地对象
    /// </summary>
    [System.Serializable]
    public class TempPasswordObject
    {
      /// <summary>
      ///  临时密码ID
      /// </summary>
      public int UserId;
      /// <summary>
      /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
      /// </summary>
      //public string PrimaryId;
      /// <summary>
      ///  6位有动态临时密码
      /// </summary>
      public string TempPassword;
      /// <summary>
      /// 门锁有效时间
      /// </summary>
      public DateTime ValidTime;
      /// <summary>
      /// 门锁失效时间
      /// </summary>
      public DateTime InValidTime;
    }
    #endregion
    #endregion
    #region 与云端通讯接口
    #region 门锁服务器发送基本信息
    /// <summary>
    ///  添加门锁
    /// </summary>
    public class BaseDoorLockServerData
    {
      /// <summary>
      /// RequestVersion
      /// </summary>
      public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
      /// <summary>
      /// LoginAccessToken
      /// </summary>
      public string LoginAccessToken = Shared.Common.Config.Instance.Token;
      /// <summary>
      /// 住宅Id -->键名 : HomeId
      /// </summary>
      public string HomeId = Shared.Common.Config.Instance.HomeId;
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId
      /// </summary>
      public string DoorLockId = "";
      /// <summary>
      /// 门锁本地用户Id -->键名 : DoorLockLocalUserId
      /// </summary>
      public string DoorLockLocalUserId = "";
      /// <summary>
      /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
      /// </summary>
      public bool IsOtherAccountCtrl = false;
    }
    #endregion
    #region 添加门锁
    /// <summary>
    ///  添加门锁
    /// </summary>
    public class AddDoorLockData : BaseDoorLockServerData
    {
      /// <summary>
      /// 云端帐号Id -->键名 : CloudAccountId
      /// </summary>
      public string CloudAccountId = "";
      /// <summary>
      /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选)
      /// </summary>
      public int OpenLockMode = 0;
      /// <summary>
      /// Data 相关内容(如:密码、指纹、IC卡 的二进制) -->键名 : Data (可选)
      public byte[] Data = null;
      /// <summary>
      /// 用户Id备注 -->键名 : UserIdRemarks
      /// </summary>
      public string UserIdRemarks = "";
      /// <summary>
      /// IsFreezeUser 是否冻结用户 -->键名 : IsFreezeUser (可选)
      /// </summary>
      public bool IsFreezeUser = false;
      /// <summary>
      /// IsTempUnlockAuthority 是否临时开锁权限 -->键名 : IsTempUnlockAuthority(可选)
      /// </summary>
      public bool IsTempUnlockAuthority = false;
      /// <summary>
      /// EntryTime 录入时间 -->键名 : EntryTime(可选)
      /// </summary>
      public DateTime EntryTime = System.DateTime.Now;
    }
    /// <summary>
    /// 添加门锁结果
    /// </summary>
    public class AddDoorLockDataRes
    {
      /// <summary>
      /// 响应的版本号,一般请求什么版本号,这里与之请求相同
      /// </summary>
      public string ResponseVersion = string.Empty;
      /// <summary>
      /// 响应状态码:
      ///<para>(1)Success 则[调用此接口操作成功], ResponseData则为null</para>
      ///<para>(2)ParameterOrEmpty,则响应字段中[ErrorInfo] 为错误信息, ResponseData则为null</para>
      ///(<para>3)NoLogin,则响应字段中[ErrorInfo] 为错误信息为[无效登录Token!]</para>
      ///<para>(4)NoRecord,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId值在云端不存在,请确认值是否正确!]</para>
      ///<para>(5)DoorLockIdNoIsYou,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId并不属于你当前帐号的,请确认值是否正确!]</para>
      /// </summary>
      public string StateCode = string.Empty;
    }
    #endregion
    #region 更新门锁
    /// <summary>
    ///   更新门锁
    /// </summary>
    public class RefreshDoorLockData : BaseDoorLockServerData
    {
      /// <summary>
      /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
      /// </summary>
      public string PrimaryId = "";
      /// <summary>
      /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选)
      /// </summary>
      public int OpenLockMode = 0;
      /// <summary>
      /// 住宅Id (可选)
      /// </summary>
      public byte[] Data;
      /// <summary>
      /// 用户Id备注
      /// </summary>
      public string UserIdRemarks = "";
      /// <summary>
      /// 是否为管理员门锁
      /// </summary>
      public bool IsFreezeUser;
      /// <summary>
      /// 是否为管理员门锁
      /// </summary>
      public bool IsTempUnlockAuthority;
    }
    #endregion
    #region 删除门锁
    /// <summary>
    /// 删除门锁
    /// </summary>
    public class DeleteDoorLockData : BaseDoorLockServerData
    {
      /// <summary>
      /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null
      /// </summary>
      public string PrimaryId = "";
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId (可选)
      /// DelDoorLockDelType 门锁删除类型(0: 根椐门锁主键(云端主键)删除(单条删除)、1:根椐门锁Id批量删除(凡是与门锁Id相同都会删除)、2:根椐门锁Id及门锁本地用户Id批量删除(这个门锁Id这个门锁本地用户Id均会被删除)) -->键名 : DelDoorLockDelType 默认值: 0
      /// </summary>
      public int DelDoorLockDelType;
    }
    #endregion
    #region 添加门锁临时密码
    /// <summary>
    ///  添加门锁
    /// </summary>
    public class AddDoorLockTempPasswordData
    {
      /// <summary>
      /// RequestVersion
      /// </summary>
      public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
      /// <summary>
      /// LoginAccessToken
      /// </summary>
      public string LoginAccessToken = Shared.Common.Config.Instance.Token;
      /// <summary>
      /// 住宅Id -->键名 : HomeId
      /// </summary>
      public string HomeId = Shared.Common.Config.Instance.HomeId;
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId
      /// </summary>
      public string LocalDoorLockId = "";
      /// <summary>
      /// 临时密码Id -->键名 : TempPwdId
      /// </summary>
      public string TempPwdId = "";
      /// <summary>
      /// 临时密码 -->键名 : TempPwd
      /// </summary>
      public string TempPwd = "";
      /// <summary>
      /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
      /// </summary>
      public DateTime ValidBeginTime;
      /// <summary>
      /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
      /// </summary>
      public DateTime ValidEndTime;
      /// <summary>
      /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
      /// </summary>
      public bool IsOtherAccountCtrl = false;
    }
    /// <summary>
    /// 添加门锁结果
    /// </summary>
    public class AddDoorLockTempPasswordDataRes : AddDoorLockDataRes
    {
    }
    #endregion
    #region 删除门锁临时密码
    /// <summary>
    ///  删除门锁
    /// </summary>
    public class DelDoorLockTempPasswordData
    {
      /// <summary>
      /// RequestVersion
      /// </summary>
      public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
      /// <summary>
      /// LoginAccessToken
      /// </summary>
      public string LoginAccessToken = Shared.Common.Config.Instance.Token;
      /// <summary>
      /// 住宅Id -->键名 : HomeId
      /// </summary>
      public string HomeId = Shared.Common.Config.Instance.HomeId;
      /// <summary>
      /// LocalDoorLockId 搜索本地门锁Id -->键名 : LocalDoorLockId  默认值: null
      /// </summary>
      public string LocalDoorLockId = "";
      /// <summary>
      /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
      /// </summary>
      public bool IsOtherAccountCtrl = false;
    }
    /// <summary>
    /// 删除门锁结果
    /// </summary>
    public class DelDoorLockTempPasswordDataRes : AddDoorLockDataRes
    {
    }
    #endregion
    #region 更新门锁临时密码
    /// <summary>
    ///  更新门锁
    /// </summary>
    public class ModifyDoorLockTempPasswordData
    {
      /// <summary>
      /// RequestVersion
      /// </summary>
      public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
      /// <summary>
      /// LoginAccessToken
      /// </summary>
      public string LoginAccessToken = Shared.Common.Config.Instance.Token;
      /// <summary>
      /// 住宅Id -->键名 : HomeId
      /// </summary>
      public string HomeId = Shared.Common.Config.Instance.HomeId;
      /// <summary>
      /// 门锁密码主键(获取门锁密码分页中的Id) -->键名 : DoorLockPwdId
      /// </summary>
      public string DoorLockPwdId = "";
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId
      /// </summary>
      public string LocalDoorLockId = "";
      /// <summary>
      /// 临时密码Id -->键名 : TempPwdId
      /// </summary>
      public string TempPwdId = "";
      /// <summary>
      /// 临时密码 -->键名 : TempPwd
      /// </summary>
      public string TempPwd = "";
      /// <summary>
      /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
      /// </summary>
      public DateTime ValidBeginTime;
      /// <summary>
      /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
      /// </summary>
      public DateTime ValidEndTime;
      /// <summary>
      /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
      /// </summary>
      public bool IsOtherAccountCtrl = false;
    }
    /// <summary>
    /// 添加门锁结果
    /// </summary>
    public class ModigDoorLockTempPasswordDataRes : AddDoorLockDataRes
    {
    }
    #endregion
    #region 获取门锁临时密码
    /// <summary>
    ///  获取门锁
    /// </summary>
    public class GetDoorLockTempPasswordData
    {
      /// <summary>
      /// RequestVersion
      /// </summary>
      public string RequestVersion = Shared.Common.CommonPage.RequestVersion;
      /// <summary>
      /// LoginAccessToken
      /// </summary>
      public string LoginAccessToken = Shared.Common.Config.Instance.Token;
      /// <summary>
      /// 住宅Id -->键名 : HomeId
      /// </summary>
      public string HomeId = Shared.Common.Config.Instance.HomeId;
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId
      /// </summary>
      public string LocalDoorLockId = "";
      /// <summary>
      /// 临时密码Id -->键名 : TempPwdId
      /// </summary>
      public string TempPwdId = "";
      /// <summary>
      /// 临时密码 -->键名 : TempPwd
      /// </summary>
      public string TempPwd = "";
      /// <summary>
      /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
      /// </summary>
      public DateTime? ValidBeginTime;
      /// <summary>
      /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
      /// </summary>
      public DateTime? ValidEndTime;
      /// <summary>
      /// IsOtherAccountCtrl 是否为子帐号控制过来 -->键名 : IsOtherAccountCtrl
      /// </summary>
      public bool IsOtherAccountCtrl = false;
    }
    /// <summary>
    /// 获取门锁临时密码结果
    /// </summary>
    [Serializable]
    public class GetDoorLockTempPasswordDataRes
    {
      public List<CloudDoorLockTempPasswordObj> PageData = new List<CloudDoorLockTempPasswordObj>();
      public int PageIndex;
      public int PageSize;
      public int TotalCount;
      public int TotalPages;
      public bool HasPreviousPage;
      public bool HasNextPage;
    }
    [Serializable]
    public class CloudDoorLockTempPasswordObj
    {
      /// <summary>
      /// 门锁Id -->键名 : DoorLockId
      /// </summary>
      public string LocalDoorLockId = "";
      /// <summary>
      /// 临时密码Id -->键名 : TempPwdId
      /// </summary>
      public string TempPwdId = "";
      /// <summary>
      /// 临时密码 -->键名 : TempPwd
      /// </summary>
      public string TempPwd = "";
      /// <summary>
      /// 0:00:00] ValidBeginTime 有效开始时间 -->键名 : ValidBeginTime  默认值: 0001/1/1
      /// </summary>
      public DateTime ValidBeginTime;
      /// <summary>
      /// 0:00:00] ValidEndTime 有效结束时间 -->键名 : ValidEndTime
      /// </summary>
      public DateTime ValidEndTime;
      /// <summary>
      /// 【门锁云端主键】,用于【添加门锁历史】接口中的DoorLockId参数及【删除门锁】接口中的PrimaryId参数,注意不是网关中的【门锁Id
      /// </summary>
      public string Id;
      /// <summary>
      /// 创建时间
      /// </summary>
      public DateTime CreatedOnUtc;
    }
    /// <summary>
    /// 从云服务器中获取门锁临时密码
    /// </summary>
    public static async System.Threading.Tasks.Task<GetDoorLockTempPasswordDataRes> GetDoorLockTempPasswordFromServer(string RequestName, GetDoorLockTempPasswordData getDoorLockTempPasswordData)
    {
      return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<GetDoorLockTempPasswordDataRes>>)(async () =>
      {
        GetDoorLockTempPasswordDataRes listInfo = null;
        var revertObj = await SendDoorLockToServer(RequestName, getDoorLockTempPasswordData);
        if (revertObj != null && revertObj.ResponseData != null)
        {
          var result = revertObj.ResponseData.ToString();
          if (result != null)
          {
            listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<GetDoorLockTempPasswordDataRes>(result);
          }
        }
        return listInfo;
      }));
    }
    #endregion
    #region 获取门锁
    /// <summary>
    ///  获取门锁
    /// </summary>
    public class GetDoorLockData : BaseDoorLockServerData
    {
      /// <summary>
      /// 云端帐号Id -->键名 : CloudAccountId (可选)
      /// </summary>
      public string CloudAccountId = "";
      /// <summary>
      /// 第几页
      /// </summary>
      public PageSetting pageSetting = new PageSetting();
    }
    /// <summary>
    ///  获取门锁
    /// </summary>
    public class PageSetting
    {
      /// <summary>
      /// 第几页
      /// </summary>
      public int Page = 1;
      /// <summary>
      /// 第几页
      /// </summary>
      public int PageSize = 10;
    }
    [Serializable]
    public class GetDoorLockDataRes
    {
      public List<CloudDoorLockObj> PageData = new List<CloudDoorLockObj>();
      public int PageIndex;
      public int PageSize;
      public int TotalCount;
      public int TotalPages;
      public bool HasPreviousPage;
      public bool HasNextPage;
    }
    [Serializable]
    public class CloudDoorLockObj
    {
      /// <summary>
      /// 门锁Id
      /// </summary>
      public string DoorLockId;
      /// <summary>
      /// 云端帐号Id
      /// </summary>
      public string CloudAccountId;
      /// <summary>
      /// OpenLockMode 开锁方式(密码、指纹、IC卡)
      /// </summary>
      public int OpenLockMode;
      /// <summary>
      /// 门锁本地用户Id
      /// </summary>
      public string DoorLockLocalUserId;
      /// <summary>
      /// 住宅Id
      /// </summary>
      public byte[] Data;
      /// <summary>
      /// 用户Id备注
      /// </summary>
      public string UserIdRemarks;
      /// <summary>
      /// 是否为管理员门锁
      /// </summary>
      public bool IsAdminDoorLock;
      /// <summary>
      /// 是否为管理员门锁
      /// </summary>
      public bool IsFreezeUser;
      /// <summary>
      /// 是否为管理员门锁
      /// </summary>
      public bool IsTempUnlockAuthority;
      /// <summary>
      /// 录入时间
      /// </summary>
      public DateTime EntryTime;
      /// <summary>
      /// 最后更新时间
      /// </summary>
      public string LastChangeTime;
      /// <summary>
      /// 【门锁云端主键】,用于【添加门锁历史】接口中的DoorLockId参数及【删除门锁】接口中的PrimaryId参数,注意不是网关中的【门锁Id
      /// </summary>
      public string Id;
      /// <summary>
      /// 创建时间
      /// </summary>
      public DateTime CreatedOnUtc;
    }
    /// <summary>
    /// 获取门锁云服务器
    /// </summary>
    public static async System.Threading.Tasks.Task<GetDoorLockDataRes> GetDoorLockInfoFromServer(string RequestName, GetDoorLockData getDoorLockData)
    {
      return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<GetDoorLockDataRes>>)(async () =>
      {
        GetDoorLockDataRes listInfo = null;
        var revertObj = await SendDoorLockToServer(RequestName, getDoorLockData);
        if (revertObj != null && revertObj.ResponseData != null)
        {
          var result = revertObj.ResponseData.ToString();
          if (result != null)
          {
            listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<GetDoorLockDataRes>(result);
          }
        }
        return listInfo;
      }));
    }
    #endregion
    /// <summary>
    /// 发送门锁数据到服务器,只回复状态,没有数据处理
    /// </summary>
    /// <returns>获取从接口那里取到的ResponsePack</returns>
    /// <param name="RequestName">访问地址</param>
    /// <param name="obj">一个类</param>
    public static async Task<ResponsePack> SendDoorLockToServer(string RequestName, object obj)
    {
      try
      {
        //序列化对象
        var requestJson = JsonConvert.SerializeObject(obj);
        var byteData = System.Text.Encoding.UTF8.GetBytes(requestJson);
        byte[] result1 = null;
        //访问接口
        if (UserCenterResourse.UserInfo.AuthorityNo == 1)
        {
          result1 = CommonPage.Instance.RequestHttpsZigbeeBytesResultAsync(RequestName, byteData);
        }
        else
        {
          result1 = CommonPage.Instance.RequestZigbeeHttpsByAdmin(RequestName, byteData);
        }
        if (result1 != null)
        {
          var result2 = Encoding.UTF8.GetString(result1);
          if (result2 != null)
          {
            var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Shared.Common.ResponseEntity.ResponsePack>(result2);
            return result;
          }
        }
        return null;
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
        return null;
      }
    }
    /// <summary>
    /// 获取子账户信息
    /// </summary>
    static List<Shared.Phone.UserCenter.MemberInfoRes> DoorLockAccountList = new List<Shared.Phone.UserCenter.MemberInfoRes> { };
    public static async System.Threading.Tasks.Task<List<Shared.Phone.UserCenter.MemberInfoRes>> GetSubAccountByDistributedMark()
    {
      DoorLockAccountList.Clear();
      return await System.Threading.Tasks.Task.Run((Func<System.Threading.Tasks.Task<List<Shared.Phone.UserCenter.MemberInfoRes>>>)(async () =>
     {
       var pra = new Shared.Phone.UserCenter.MemberListInfoPra();
       string result = UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeUsers/GetSubAccountByDistributedMark", false, pra);
       if (result == null)
       {
         return null;
       }
       var listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Shared.Phone.UserCenter.MemberInfoRes>>(result);
       return listInfo;
     }));
    }
    /// <summary>
    /// 服务器获取数据失败提示
    /// </summary>
    public void FailureToServer()
    {
      Application.RunOnMainThread(() =>
      {
        var alert = new Alert(Language.StringByID(Shared.R.MyInternationalizationString.TIP), Language.StringByID(Shared.R.MyInternationalizationString.RequestServerFailed), Language.StringByID(Shared.R.MyInternationalizationString.Confrim));
        alert.Show();
      });
    }
    #endregion
    #region  与网关通讯接口
    #region 门锁操作事件通知
    /// <summary>
    /// 门锁操作事件通知
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public DoorLockOperatingEventNotificationCommand doorLockOperatingEventNotificationCommand;
    /// <summary>
    /// 门锁操作事件通知
    /// </summary>
    [System.Serializable]
    public class DoorLockOperatingEventNotificationCommand
    {
      /// <summary>
      /// 用户id
      ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id
      /// </summary>
      public int UserID;
      /// <summary>
      /// 事件触发源
      /// 常用:
      /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹
      ///不常用:
      /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定)
      /// </summary>
      public int OperationEventSoure;
      /// <summary>
      /// 事件码
      /// 常用:
      /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件
      ///不常用:
      /// 请查看枚举
      /// </summary>
      public int OperationEventCode;
      /// <summary>
      /// 保留,默认0
      /// </summary>
      public int PIN;
      /// <summary>
      /// 门锁本地当前时间的时间戳
      /// </summary>
      public int ZigbeeLocalTime;
    }
    public class AccountsObj
    {
      /// <summary>
      /// 关联app账号
      /// </summary>
      public string Account;
      /// <summary>
      /// 保留
      /// </summary>
      public int Type;
      /// <summary>
      ///  保留
      /// </summary>
      public int Status;
    }
    /// <summary>
    /// “OperationEventSoure”列表
    /// </summary>
    public enum OperationEventSoure
    {
      /// <summary>
      /// 键盘/密码
      /// </summary>
      Keypad = 0,
      /// <summary>
      /// Zigbee无线
      /// </summary>
      RF = 1,
      /// <summary>
      /// 手动
      /// </summary>
      Manual = 2,
      /// <summary>
      /// 射频卡
      /// </summary>
      RFID = 3,
      /// <summary>
      /// 指纹
      /// </summary>
      Fingerprint = 15,
      /// <summary>
      /// Indeterminate(不确定)
      /// </summary>
      Indeterminate = 255,
    }
    /// <summary>
    /// “OperationEventSoure”类型为“Keypad”即密码 的“OperationEventCode”事件
    /// </summary>
    public enum KeypadEventDescription
    {
      /// <summary>
      /// 未知事件
      /// </summary>
      UnknownEvent = 0,
      /// <summary>
      /// Lock命令成功事件
      /// </summary>
      LockSuccessEvent = 1,
      /// <summary>
      /// Unlock命令成功事件
      /// </summary>
      UnlockSuccessEvent = 2,
      /// <summary>
      /// Lock命令:error,invalid PIN事件
      /// </summary>
      LockInvalidPinEvent = 3,
      /// <summary>
      /// Lock命令:error,invalid schedule事件
      /// </summary>
      LockInvalidScheduleEvent = 4,
      /// <summary>
      /// Unlock命令:error,invalid PIN事件
      /// </summary>
      UnlockInvalidPinEvent = 5,
      /// <summary>
      /// Unlock命令:error,invalid schedule事件Unlock命令:error,invalid schedule事件
      /// </summary>
      UnlockInvalidScheduleEvent = 6,
      /// <summary>
      /// 非访问用户操作事件
      /// </summary>
      NonAccess = 15,
    }
    /// <summary>
    /// “OperationEventSoure”类型为“RF” 的“OperationEventCode”事件
    /// </summary>
    public enum RfEventDescription
    {
      /// <summary>
      /// 未知事件
      /// </summary>
      UnknownEvent = 0,
      /// <summary>
      /// Lock命令成功事件
      /// </summary>
      LockSuccessEvent = 1,
      /// <summary>
      /// Unlock命令成功事件
      /// </summary>
      UnlockSuccessEvent = 2,
      /// <summary>
      /// Lock命令:error,invalid code事件
      /// </summary>
      LockInvalidPinEvent = 3,
      /// <summary>
      /// Lock命令:error,invalid schedule事件
      /// </summary>
      LockInvalidScheduleEvent = 4,
      /// <summary>
      /// Unlock命令:error,invalid code事件
      /// </summary>
      UnlockInvalidPinEvent = 5,
      /// <summary>
      /// Unlock命令:error,invalid schedule事件
      /// </summary>
      UnlockInvalidScheduleEvent = 6,
    }
    /// <summary>
    /// “OperationEventSoure”类型为“Manual” 的“OperationEventCode”事件
    /// </summary>
    public enum ManualEventDescription
    {
      /// <summary>
      /// 未知事件
      /// </summary>
      UnknownEvent = 0,
      /// <summary>
      /// Thumbturn Lock;手动转动上锁
      /// </summary>
      ThumbturnLockEvent = 1,
      /// <summary>
      /// Thumbturn Unlock;手动转动解锁
      /// </summary>
      UnlockSuccessEvent = 2,
      /// <summary>
      /// One touch Lock;一键上锁
      /// </summary>
      LockInvalidPinEvent = 7,
      /// <summary>
      ///Key Lock;按键上锁
      /// </summary>
      LockInvalidScheduleEvent = 8,
      /// <summary>
      /// Key Unlock;按键解锁
      /// </summary>
      UnlockInvalidPinEvent = 9,
      /// <summary>
      /// Auto lock;自动上锁
      /// </summary>
      UnlockInvalidScheduleEvent = 10,
      /// <summary>
      /// Schedule Lock;时间表上锁
      /// </summary>
      ScheduleLockEvent = 11,
      /// <summary>
      /// Schedule Unlock;时间表解锁
      /// </summary>
      ScheduleUnlockEvent = 12,
      /// <summary>
      /// Manual Lock(Key or Thumbturn);手动上锁
      /// </summary>
      ManualLockEvent = 13,
      /// <summary>
      ///anual Unlock(Key or Thumbturn);手动解锁
      /// </summary>
      ManualUnlockEvent = 14,
    }
    /// <summary>
    /// “OperationEventSoure”类型为“RFID” 的“OperationEventCode”事件
    /// </summary>
    public enum RfidEventDescription
    {
      /// <summary>
      /// 未知事件
      /// </summary>
      UnknownEvent = 0,
      /// <summary>
      /// Lock命令成功事件
      /// </summary>
      LockSuccessEvent = 1,
      /// <summary>
      /// Unlock命令成功事件
      /// </summary>
      UnlockSuccessEvent = 2,
      /// <summary>
      /// Lock命令:error,invalid RFID ID事件
      /// </summary>
      LockInvalidRfidIdEvent = 3,
      /// <summary>
      /// Lock命令:error,invalid schedule事件
      /// </summary>
      LockInvalidScheduleEvent = 4,
      /// <summary>
      /// Unlock命令:error,invalid RFID ID事件
      /// </summary>
      UnlockInvalidRfidIdEvent = 5,
      /// <summary>
      /// Unlock命令:error,invalid schedule事件
      /// </summary>
      UnlockInvalidScheduleEvent = 6,
    }
    #endregion
    #region 门锁编程事件通知
    /// <summary>
    /// 门锁编程事件通知
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public DoorLockProgrammingEventNotificationCommand doorLockProgrammingEventNotificationCommand;
    /// <summary>
    /// 门锁编程事件通知
    /// </summary>
    [System.Serializable]
    public class DoorLockProgrammingEventNotificationCommand
    {
      /// <summary>
      /// 用户id
      ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id
      /// </summary>
      public int UserID;
      /// <summary>
      /// 保留
      /// </summary>
      public int UserType;
      /// <summary>
      ///  保留
      /// </summary>
      public int UserStatus;
      /// <summary>
      /// 编程事件触发源
      /// 常用:
      /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹 58:face  59:静脉
      ///不常用:
      /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定)
      /// </summary>
      public int ProgramEventSoure;
      /// <summary>
      /// 编程事件码
      /// 常用:
      /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件
      ///不常用:
      /// 请查看枚举
      /// </summary>
      public int ProgramEventCode;
      /// <summary>
      /// 保留,默认0
      /// </summary>
      public int PIN;
      /// <summary>
      /// 门锁本地当前时间的时间戳
      /// </summary>
      public int ZigbeeLocalTime;
    }
    #endregion
    #region 矫正门锁时间
    /// <summary>
    /// 矫正门锁时间
    /// </summary>
    /// <param name="timestamp"></param>
    /// <returns></returns>
    public async System.Threading.Tasks.Task<SetWritableValueResponAllData> RectifyDoorLockTimeAsync(int timestamp)
    {
      if (Gateway == null)
      {
        return null;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        SetWritableValueResponAllData d = null;
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    d = new SetWritableValueResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    d = new SetWritableValueResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "SetWritableValue_Respon")
                {
                  var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<SetWritableValueResponData>(jobject["Data"].ToString());
                  if (tempData == null)
                  {
                    d = new SetWritableValueResponAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    d = new SetWritableValueResponAllData { setWritableValueResponData = tempData };
                    DebugPrintLog($"UI收到通知后的主题_{ topic}");
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("SetWritableValue_Actions 启动" + "_" + System.DateTime.Now.ToString());
        try
        {
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 10 }, { "Command", 120 } };
          var data = new JObject { { "Undivided", 0 }, { "AttributeId", 0 }, { "AttributeDataType", 226 }, { "AttributeData", timestamp } };
          jObject.Add("Data", data);
          Gateway.Send("SetWritableValue", jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (d != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          d = new SetWritableValueResponAllData { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("SetWritableValue_Actions 退出" + System.DateTime.Now.ToString());
        return d;
      });
    }
    #endregion
    #endregion
    #region 与设备通讯接口(私有命令)
    #region 用户管理控制
    ///<summary >
    ///用户管理控制
    /// <para>passData:透传数据</para>
    /// </summary>
    public async System.Threading.Tasks.Task<DefaultControlResponseAllData> DefaultControlAsync(string passData)
    {
      DefaultControlResponseAllData result = null;
      if (Gateway == null)
      {
        result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 16)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0002")
                        {
                          var tempD = new DefaultControlResponseData();
                          tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                          tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                          if (tempD.command == "0450")
                          {
                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                            DebugPrintLog($"UI收到通知后的主题_command:0450_{ topic}");
                          }
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new DefaultControlResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 用户管理发送数据
    /// userIdList:个数不能超过10个
    /// </summary>
    public string FreezeAccountData(List<int> userIdList, AccessType accessType)
    {
      string data = "";
      string dataLength = "";
      string dataComand1 = "50";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "";
      string delUserTypeStr = "";
      string userIdStr = "";
      try
      {
        if (userIdList.Count == 0)
        {
          return null;
        }
        if (userIdList.Count > 9)
        {
          return null;
        }
        var tempLength = 5 + userIdList.Count * 2;
        string tempLength1 = Convert.ToString(tempLength, 16);
        switch (tempLength1.Length)
        {
          case 1:
            dataLength = "0" + tempLength1.ToUpper();
            break;
          case 2:
            dataLength = tempLength1.ToUpper();
            break;
        }
        var tempAddDataLength = 1 + userIdList.Count * 2;
        string tempAddDataLength1 = Convert.ToString(tempAddDataLength, 16);
        switch (tempAddDataLength1.Length)
        {
          case 1:
            addDataLength = "0" + tempAddDataLength1.ToUpper();
            break;
          case 2:
            addDataLength = tempAddDataLength1.ToUpper();
            break;
        }
        switch ((int)accessType)
        {
          case 0:
            delUserTypeStr = "00";
            break;
          case 1:
            delUserTypeStr = "01";
            break;
          case 2:
            delUserTypeStr = "20";
            break;
          case 3:
            delUserTypeStr = "21";
            break;
          case 4:
            delUserTypeStr = "10";
            break;
          case 5:
            delUserTypeStr = "30";
            break;
          case 6:
            delUserTypeStr = "31";
            break;
        }
        var sbString = new System.Text.StringBuilder();
        foreach (var userId in userIdList)
        {
          var tempBytes = new byte[2];
          for (int i = 0; i < 2; i++)
          {
            tempBytes[i] = (byte)(userId >> (i * 8) & 0xff);
          }
          var curV1 = Convert.ToString(tempBytes[0], 16);
          var curV2 = Convert.ToString(tempBytes[1], 16);
          if (curV1.Length == 1)
          {
            curV1 = "0" + curV1;
          }
          if (curV2.Length == 1)
          {
            curV2 = "0" + curV2;
          }
          userIdStr = (curV1 + curV2).ToUpper();
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
           delUserTypeStr + userIdStr;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 用户管理发送数据
    /// </summary>
    public string SetUserAccessData(int userId, AccessType accessType)
    {
      string data = "";
      string dataLength = "07";
      string dataComand1 = "50";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "03";
      string delUserTypeStr = "";
      string userIdStr = "";
      try
      {
        switch ((int)accessType)
        {
          case 0:
            delUserTypeStr = "00";
            break;
          case 1:
            delUserTypeStr = "01";
            break;
          case 2:
            delUserTypeStr = "20";
            break;
          case 3:
            delUserTypeStr = "21";
            break;
        }
        var tempBytes = new byte[2];
        for (int i = 0; i < 2; i++)
        {
          tempBytes[i] = (byte)(userId >> (i * 8) & 0xff);
        }
        var curV1 = Convert.ToString(tempBytes[0], 16);
        var curV2 = Convert.ToString(tempBytes[1], 16);
        if (curV1.Length == 1)
        {
          curV1 = "0" + curV1;
        }
        if (curV2.Length == 1)
        {
          curV2 = "0" + curV2;
        }
        userIdStr = (curV1 + curV2).ToUpper();
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   delUserTypeStr + userIdStr;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 用户管理发送数据回复
    /// </summary>
    [System.Serializable]
    public class DefaultControlResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 用户管理数据回复
      /// </summary>
      public DefaultControlResponseData defaultControlResponseData;
    }
    /// <summary>
    /// 用户管理数据回复
    /// </summary>
    [System.Serializable]
    public class DefaultControlResponseData
    {
      /// <summary>
      ///响应操作码(0-ffff)
      /// </summary>
      public string command = "";
      /// <summary>
      /// 状态值
      /// <para>默认响应结果:
      ///<para>0 成功</para>
      ///<para>1 失败</para>
      ///<para>2 用户不存在</para>
      ///<para>32 冻结成功</para>
      ///<para>34 冻结失败</para>
      ///<para>33 解冻成功</para>
      ///<para>35 解冻失败</para>
      /// </summary>
      public int status = -1;
    }
    public enum AccessType
    {
      /// <summary>
      /// 0x00 删除全部临时用户
      /// </summary>
      DelAllUsers = 0,
      /// <summary>
      /// 0x01 删除指定用户(按编号)
      /// </summary>
      DelCurrentUser = 1,
      /// <summary>
      /// 0x20 冻结指定用户
      /// </summary>
      DisEnable = 2,
      /// <summary>
      /// 0x21 解冻指定用户
      /// </summary>
      Enable = 3,
      /// <summary>
      /// 0x10 多个指定用户删除
      /// </summary>
      DelMoreUsers = 4,
      /// <summary>
      /// 0x30 多个指定用户冻结
      /// </summary>
      DisEnableMoreUsers = 5,
      /// <summary>
      /// 0x31 多个指定用户解冻
      /// </summary>
      EnableMoreUsers = 6,
    }
    #endregion
    #region 验证门锁密码
    ///<summary >
    ///验证门锁密码
    ///<para>inputPassword:输入的门锁密码</para>
    /// </summary>
    public async System.Threading.Tasks.Task<VerifyPasswordResponseAllData> VerifyPasswordAsync(string inputPassword)
    {
      VerifyPasswordResponseAllData result = null;
      if (Gateway == null)
      {
        result = new VerifyPasswordResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new VerifyPasswordResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new VerifyPasswordResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new VerifyPasswordResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 12)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0454")
                        {
                          var result1 = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                          result = new VerifyPasswordResponseAllData { result = result1 };
                          DebugPrintLog($"UI收到通知后的主题_command:0454_{ topic}");
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var getPw = await GetkeyPassword();
          var passData = VerifyPasswordData(inputPassword, getPw);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null && result.result == 0)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          result = new VerifyPasswordResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 验证门锁密码
    /// </summary>
    public string VerifyPasswordData(string keyPassword, int password, int fixedPassword = 0x190605)
    {
      string data = "";
      string dataLength = "08";
      string dataComand1 = "53";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "04";
      string passwordStr = "";
      try
      {
        int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
        var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + fixedPassword, 16);
        pawStr = pawStr.PadLeft(8, '0');
        for (int i = 6; i >= 0; i = i - 2)
        {
          passwordStr += pawStr.Substring(i, 2);
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
         passwordStr;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 用户管理发送数据回复
    /// </summary>
    [System.Serializable]
    public class VerifyPasswordResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 用户管理数据回复
      /// <para>0:成功</para>
      ///<para>1:失败</para>
      /// </summary>
      public int result = -1;
    }
    #endregion
    #region 远程开锁
    ///<summary >
    ///远程开锁
    ///<para>inputPassword: 输入密码/para>
    /// </summary>
    public async System.Threading.Tasks.Task<RemoteResponseAllData> RemoteControlAsync(string inputPassword)
    {
      RemoteResponseAllData result = null;
      if (Gateway == null)
      {
        result = new RemoteResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new RemoteResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new RemoteResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                else if (topic == $"{gatewayID}/DoorLock/DoorLockOperatingEventNotificationCommand")
                {
                  var OperatingEventNotificationDatad = Newtonsoft.Json.JsonConvert.DeserializeObject<ZigBee.Device.DoorLock.DoorLockOperatingEventNotificationCommand>(jobject["Data"].ToString());
                  if (OperatingEventNotificationDatad != null)
                  {
                    if (OperatingEventNotificationDatad.OperationEventSoure == 1 && OperatingEventNotificationDatad.OperationEventCode == 5)
                    {
                      result = new RemoteResponseAllData { IsPawDispear = true };
                    }
                  }
                }
                else if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new RemoteResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 16)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0002")
                        {
                          var tempD = new RemoteResponseData();
                          tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                          tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                          if (tempD.command == "0462")
                          {
                            result = new RemoteResponseAllData { responseData = tempD };
                            DebugPrintLog($"UI收到通知后的主题_command:0462_{ topic}");
                          }
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var getPw = await GetkeyPassword();
          var passData = RemoteData(inputPassword, getPw);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 5000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result == null)
          {
            continue;
          }
          if (result.responseData != null && result.responseData.command == "0462")
          {
            break;
          }
          if (result.IsPawDispear == true)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          result = new RemoteResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 远程发送数据
    /// </summary>
    string RemoteData(string keyPassword, int password, int fixedPassword = 0x190605)
    {
      string data = "";
      string dataLength = "08";
      string dataComand1 = "62";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "04";
      string passwordStr = "";
      try
      {
        int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
        var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + fixedPassword, 16);
        pawStr = pawStr.PadLeft(8, '0');
        for (int i = 6; i >= 0; i = i - 2)
        {
          passwordStr += pawStr.Substring(i, 2);
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
         passwordStr;
      }
      catch { };
      return data;
    }
    /// <summary>
    ///  远程回复数据
    /// </summary>
    [System.Serializable]
    public class RemoteResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 临时密码回复数据
      /// </summary>
      public RemoteResponseData responseData;
      /// <summary>
      /// 是否密码被删除
      /// </summary>
      public bool IsPawDispear = false;
    }
    /// <summary>
    /// 用户管理数据回复
    /// </summary>
    [System.Serializable]
    public class RemoteResponseData
    {
      /// <summary>
      ///响应操作码(0-ffff)
      /// </summary>
      public string command = "";
      /// <summary>
      /// 状态值
      /// <para>默认响应结果:
      ///<para>0 成功</para>
      ///<para>1 失败</para>
      /// </summary>
      public int status = -1;
    }
    #endregion
    #region 临时密码发送数据
    ///<summary >
    ///临时密码
    ///<para>inputPassword: 输入密码/para>
    /// </summary>
    public async System.Threading.Tasks.Task<TempPasswordResponseAllData> TempPasswordAsync(string inputPassword, System.DateTime startTime, System.DateTime endTime, string fixedPassword = "190605")
    {
      TempPasswordResponseAllData result = null;
      if (Gateway == null)
      {
        result = new TempPasswordResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new TempPasswordResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new TempPasswordResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new TempPasswordResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 16)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0002")
                        {
                          var tempD = new TempPasswordResponseData();
                          tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                          tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                          if (tempD.command == "0463")
                          {
                            result = new TempPasswordResponseAllData { responseData = tempD };
                            DebugPrintLog($"UI收到通知后的主题_command:0463_{ topic}");
                          }
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var getPw = await GetkeyPassword();
          var passData = TempPasswordData(inputPassword, getPw, startTime, endTime);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null && result.responseData != null && result.responseData.command == "0463")
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new TempPasswordResponseAllData
          { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 临时密码发送数据
    /// </summary>
    public string TempPasswordData(string keyPassword, int password, System.DateTime startTime, System.DateTime endTime)
    {
      string data = "";
      string dataLength = "10";
      string dataComand1 = "63";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "0c";
      string passwordStr = "";
      string vaildTimeStr = "";
      string invalidTimeStr = "";
      try
      {
        int keyPasswordInt = System.Convert.ToInt32(keyPassword, 16);
        var pawStr = System.Convert.ToString((keyPasswordInt ^ password) + 0x190605, 16);
        pawStr = pawStr.PadLeft(8, '0');
        for (int i = 6; i >= 0; i = i - 2)
        {
          passwordStr += pawStr.Substring(i, 2);
        }
        var startTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(startTime);
        var endTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(endTime);
        startTimeStr = string.Format("{0:X}", System.Convert.ToInt64(startTimeStr));
        endTimeStr = string.Format("{0:X}", System.Convert.ToInt64(endTimeStr));
        for (int i = 6; i >= 0; i = i - 2)
        {
          vaildTimeStr += startTimeStr.Substring(i, 2);
          invalidTimeStr += endTimeStr.Substring(i, 2);
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
           passwordStr + vaildTimeStr + invalidTimeStr;
      }
      catch (Exception ex)
      {
        var mess = ex.Message;
      };
      return data;
    }
    /// <summary>
    /// 临时密码回复数据
    /// </summary>
    [System.Serializable]
    public class TempPasswordResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 临时密码回复数据
      /// </summary>
      public TempPasswordResponseData responseData;
    }
    /// <summary>
    /// 临时密码回复数据
    /// </summary>
    [System.Serializable]
    public class TempPasswordResponseData
    {
      /// <summary>
      ///响应操作码(0-ffff)
      /// </summary>
      public string command = "";
      /// <summary>
      /// 状态值
      /// <para>0--注册成功</para>
      /// <para>1--注册失败</para>
      /// <para>2--用户已存在(重复密码)</para>
      /// <para>3-- 用户已满(+已满类型回复)</para>
      /// <para>4--有效时间重叠</para>
      /// </summary>
      public int status = -1;
    }
    #endregion
    #region 获取门锁密钥
    /// <summary>
    /// 门锁随机密码
    /// <para>获取加密的随机密钥,返回的密钥经过一个简单的加法加密加上0x190605,因此获取的密钥需要减上0x190605</para>
    /// </summary>
    /// <returns></returns>
    async System.Threading.Tasks.Task<int> GetkeyPassword()
    {
      string passwordStr = "";
      var result = await GetKeyPassworAsync();
      //返回小端
      if (result == null || result.keyPassword == null)
      {
        return 0;
      }
      for (int i = 6; i >= 0; i = i - 2)
      {
        passwordStr += result.keyPassword.Substring(i, 2);
      }
      var keyPasswordInt = System.Convert.ToInt32(passwordStr, 16);
      return keyPasswordInt - 0x190605;
    }
    ///<summary >
    ///获取门锁密钥
    /// </summary>
    async System.Threading.Tasks.Task<KeyPasswordInfo> GetKeyPassworAsync(int keyType = 0)
    {
      KeyPasswordInfo result = null;
      if (Gateway == null)
      {
        result = new KeyPasswordInfo { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new KeyPasswordInfo { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new KeyPasswordInfo { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new KeyPasswordInfo { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 20)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0461")
                        {
                          var kType = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                          var keyPassword = data[12].ToString() + data[13].ToString() + data[14].ToString() + data[15].ToString() + data[16].ToString() + data[17].ToString() + data[18].ToString() + data[19].ToString();
                          result = new KeyPasswordInfo { keyType = kType, keyPassword = keyPassword };
                          DebugPrintLog($"UI收到通知后的主题_command:0460_{ topic}");
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = KeyPasswordData(keyType);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)//WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          result = new KeyPasswordInfo { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 获取门锁密钥
    /// </summary>
    string KeyPasswordData(int keyType)
    {
      string data = "";
      string dataLength = "05";
      string dataComand1 = "60";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "01";
      string keyTypeData = "";
      try
      {
        var tempTypeString = new System.Text.StringBuilder();
        var temp = Convert.ToString(keyType, 16);
        switch (temp.Length)
        {
          case 1:
            keyTypeData = "0" + temp;
            break;
          case 2:
            keyTypeData = temp;
            break;
        }
        tempTypeString.Append(keyTypeData.ToString().ToUpper());
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
    tempTypeString;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 获取门锁密钥回复
    /// </summary>
    [System.Serializable]
    public class KeyPasswordInfo
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      ///密钥类型
      ///<apra></apra>
      /// </summary>
      public int keyType = -1;
      /// <summary>
      /// 密钥
      /// </summary>
      public string keyPassword;
    }
    #endregion
    #region 读取锁上信息
    ///<summary >
    ///读取锁上信息
    /// </summary>
    public async System.Threading.Tasks.Task<DoorlockUserInfo> GetDoorlockUserInfoAsync()
    {
      DoorlockUserInfo result = null;
      int totalNum = 0;
      int currentNum = -1;
      DoorLockUserDetailData doorLockUserDetailData = new DoorLockUserDetailData { };
      if (Gateway == null)
      {
        result = new DoorlockUserInfo { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        var dateTime = DateTime.Now;
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData != null)
                  {
                    if (clientDataPassthroughResponseData.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                      if (command == "0452")
                      {
                        dateTime = DateTime.Now;
                        int returnAllLength = 2 + 2 * Convert.ToInt32(data[0].ToString() + data[1].ToString(), 16);
                        int usefulLength = (returnAllLength - 16);
                        int tempCount = 0;
                        var listData = new List<string>();
                        while (tempCount < usefulLength)
                        {
                          listData.Add(data[16 + tempCount].ToString());
                          tempCount++;
                        }
                        for (int j = 0; j < listData.Count / 4; j++)
                        {
                          int curIndex = 4 * j;
                          var userInfo = new UserObj();
                          userInfo.UserType = Convert.ToInt32(listData[curIndex + 2].ToString(), 16);
                          userInfo.UserId = Convert.ToInt32(listData[curIndex + 3].ToString() + listData[curIndex].ToString() + listData[curIndex + 1].ToString(), 16);
                          doorLockUserDetailData.UserObjList.Add(userInfo);
                        }
                        doorLockUserDetailData.userType = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                        doorLockUserDetailData.totalNum = Convert.ToInt32(data[12].ToString() + data[13].ToString(), 16);
                        doorLockUserDetailData.currentNum = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                        totalNum = doorLockUserDetailData.totalNum;
                        currentNum = doorLockUserDetailData.currentNum;
                        result = new DoorlockUserInfo { doorLockUserDetailData = doorLockUserDetailData };
                        DebugPrintLog($"UI收到通知后的主题_command:0451_{ topic}");
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = DoorlockUserData();
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        //接收一个包最多等3秒,没有收到就退出,单次数据包不超过30个用户
        while ((DateTime.Now - dateTime).TotalMilliseconds < 3000)
        {
          await System.Threading.Tasks.Task.Delay(100);
          if (totalNum == currentNum)
          {
            break;
          }
        }
        //if ((DateTime.Now - dateTime).TotalMilliseconds > 3000)
        //{
        //    result = new DoorlockUserInfo { errorMessageBase = " 回复超时,请重新操作" };
        //}
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 读取锁上信息
    /// </summary>
    string DoorlockUserData()
    {
      string data = "";
      string dataLength = "05";
      string dataComand1 = "51";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "01";
      string keyTypeData = "01";
      try
      {
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + keyTypeData;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 读取锁上信息回复
    /// </summary>
    [System.Serializable]
    public class DoorlockUserInfo
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 门锁设备返回信息
      /// </summary>
      public DoorLockUserDetailData doorLockUserDetailData;
    }
    /// <summary>
    /// 门锁设备返回信息
    /// </summary>
    public class DoorLockUserDetailData
    {
      /// <summary>
      /// 类型(读取锁上已有用户)
      /// </summary>
      public int userType;
      /// <summary>
      /// 数据包总数
      /// </summary>
      public int totalNum;
      /// <summary>
      /// 数据包序号
      /// </summary>
      public int currentNum;
      /// <summary>
      /// 虚拟驱动信息
      /// </summary>
      public List<UserObj> UserObjList = new List<UserObj>();
    }
    public class UserObj
    {
      /// <summary>
      /// 门锁用户类型
      /// </summary>
      public int UserType;
      /// <summary>
      /// 门锁用户Id号
      /// </summary>
      public int UserId;
    }
    #endregion
    #region 音量
    ///<summary >
    ///获取音量
    /// </summary>
    public async System.Threading.Tasks.Task<VolumeResponseAllData> GetVolumeAsync()
    {
      VolumeResponseAllData result = null;
      if (Gateway == null)
      {
        result = new VolumeResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new VolumeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new VolumeResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new VolumeResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 14)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0456")
                        {
                          var tempD = new VolumeResponseData();
                          tempD.command = data[10].ToString() + data[11].ToString();
                          tempD.value = Convert.ToInt32(data[12].ToString() + data[13].ToString(), 16);
                          result = new VolumeResponseAllData { volumeResponseData = tempD };
                          DebugPrintLog($"UI收到通知后的主题_command:0456_{ topic}");
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = VolumeData(-1);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null && result.volumeResponseData != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new VolumeResponseAllData
          { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    ///<summary >
    ///音量
    ///<para>命令值: comandValue</para>
    ///<para>comandValue: 0-0x64 音量</para>
    /// </summary>
    public async System.Threading.Tasks.Task<DefaultControlResponseAllData> SetVolumeAsync(int comandValue)
    {
      DefaultControlResponseAllData result = null;
      if (Gateway == null)
      {
        result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 16)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0002")
                        {
                          var tempD = new DefaultControlResponseData();
                          tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                          tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                          if (tempD.command == "0455")
                          {
                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                            DebugPrintLog($"UI收到通知后的主题_command:0455_{ topic}");
                          }
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = VolumeData(comandValue);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null && result.defaultControlResponseData != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new DefaultControlResponseAllData
          { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 音量发送数据
    ///<para>comandValue: 0-100 音量</para>
    /// </summary>
    public string VolumeData(int comandValue)
    {
      string data = "";
      string dataLength = "05";
      string dataComand1 = "55";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "01";
      string cValue = "";
      try
      {
        if (comandValue >= 1)
        {
          cValue = Convert.ToString(comandValue, 16).ToUpper();
          if (cValue.Length == 1)
          {
            cValue = "0" + cValue;
          }
          else
          {
            cValue = cValue;
          }
        }
        else
        {
          switch (comandValue)
          {
            case -1:
              cValue = "AA";
              break;
            case 0:
              cValue = "EB";
              break;
          }
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
           cValue;
      }
      catch (Exception ex)
      {
        var mess = ex.Message;
      };
      return data;
    }
    /// <summary>
    /// 音量回复数据
    /// </summary>
    [System.Serializable]
    public class VolumeResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 音量回复数据
      /// </summary>
      public VolumeResponseData volumeResponseData;
    }
    /// <summary>
    /// 音量回复数据
    /// </summary>
    [System.Serializable]
    public class VolumeResponseData
    {
      /// <summary>
      ///命令
      ///<para>0x00 接收成功</para>
      ///<para>0xea 语音模式</para>
      ///<para>0xeb 静音模式</para>
      /// </summary>
      public string command = "";
      /// <summary>
      /// 音量值
      /// <para>0xf1~0xfe  1-14音量</para>
      /// <para>0 无音量值</para>
      /// </summary>
      public int value = -1;
    }
    #endregion
    #region 常开模式         
    /// <summary>
    /// 读取常开模式
    /// </summary>
    /// <returns></returns>
    public async System.Threading.Tasks.Task<OpenModeResponseAllData> ReadNormallyOpenModeFuncAsync()
    {
      OpenModeResponseAllData result = null;
      if (Gateway == null)
      {
        result = new OpenModeResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new OpenModeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new OpenModeResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new OpenModeResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 12)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0458")
                        {
                          result = new OpenModeResponseAllData();
                          result.command = data[10].ToString() + data[11].ToString();
                          DebugPrintLog($"UI收到通知后的主题_command:0457_{ topic}");
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = OpenModeData(SwitchMode.Obtain);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new OpenModeResponseAllData
          { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 设置常开模式
    /// </summary>
    /// <param name="IsNormallyOpenMode">是否打开常开模式:true:打开 false:关闭</param>
    /// <returns></returns>
    public async System.Threading.Tasks.Task<DefaultControlResponseAllData> SetNormallyOpenModeFuncAsync(bool IsNormallyOpenMode)
    {
      DefaultControlResponseAllData result = null;
      if (Gateway == null)
      {
        result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" };
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
              {
                var gatewayID = topic.Split('/')[0];
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                if (topic == gatewayID + "/" + "Error_Respon")
                {
                  var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                  if (temp == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                  }
                  else
                  {
                    result = new DefaultControlResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                  }
                }
                if (topic == gatewayID + "/" + "ZbDataPassthrough")
                {
                  var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                  if (clientDataPassthroughResponseData == null)
                  {
                    result = new DefaultControlResponseAllData { errorMessageBase = "网关返回的数据为空" };
                  }
                  else
                  {
                    if (clientDataPassthroughResponseData?.PassData != null)
                    {
                      var data = clientDataPassthroughResponseData.PassData;
                      if (data.Length == 16)
                      {
                        var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                        if (command == "0002")
                        {
                          var tempD = new DefaultControlResponseData();
                          tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                          tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                          if (tempD.command == "0457")
                          {
                            result = new DefaultControlResponseAllData { defaultControlResponseData = tempD };
                            DebugPrintLog($"UI收到通知后的主题_command:0457_{ topic}");
                          }
                        }
                      }
                    }
                  }
                }
              };
        Gateway.Actions += action;
        DebugPrintLog("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = "";
          if (IsNormallyOpenMode)
          {
            passData = OpenModeData(SwitchMode.NormallyOpen);
          }
          else
          {
            passData = OpenModeData(SwitchMode.NormallyClose);
          }
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null && result.defaultControlResponseData != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > 9000)
        {
          result = new DefaultControlResponseAllData
          { errorMessageBase = " 回复超时,请重新操作" };
        }
        Gateway.Actions -= action;
        DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 常开模式 发送数据
    /// </summary>
    public string OpenModeData(SwitchMode switchMode)
    {
      string data = "";
      string dataLength = "05";
      string dataComand1 = "57";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "01";
      string cValue = "";
      try
      {
        switch (switchMode)
        {
          case SwitchMode.Obtain:
            cValue = "10";
            break;
          case SwitchMode.NormallyOpen:
            cValue = "12";
            break;
          case SwitchMode.NormallyClose:
            cValue = "13";
            break;
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
           cValue;
      }
      catch (Exception ex)
      {
        var mess = ex.Message;
      };
      return data;
    }
    /// <summary>
    /// 常开模式 回复数据
    /// </summary>
    [System.Serializable]
    public class OpenModeResponseAllData
    {
      /// <summary>
      /// 错误信息
      /// </summary>
      public string errorMessageBase;
      /// <summary>
      /// 网关信息错误反馈
      /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
      /// </summary>
      public ErrorResponData errorResponData;
      /// <summary>
      /// 0x10 常开已开启
      /// <para>0x11 常开已关闭</para>
      /// </summary>
      public string command;
    }
    /// <summary>
    /// 开关模式
    /// </summary>
    public enum SwitchMode
    {
      /// <summary>
      /// 0x10 查询常开状态
      /// </summary>
      Obtain = 0x10,
      /// <summary>
      /// 0x12 开启常开
      /// </summary>
      NormallyOpen = 0x12,
      /// <summary>
      /// 0x13 关闭常开
      /// </summary>
      NormallyClose = 0x13
    }
    #endregion
    #endregion
  }
}