using System; using System.Collections.Generic; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Shared; using Shared.Common; using Shared.Common.ResponseEntity; using Shared.Phone.UserCenter; namespace ZigBee.Device { public class DoorLock : CommonDevice { public DoorLock() { this.Type = DeviceType.DoorLock; } #region 门锁本地变量 /// /// 门锁本地用户列表 /// /// public Dictionary localDoorLockUserList = new Dictionary(); public string currentUserDisplayMethod = string.Empty; public List localAllAccountList = new List { }; public static int RemoteUnlockCount = 3;//远程开锁次数限制 public static string RemoteUnlockPassword = string.Empty;//远程开锁密码 public static DateTime maxValue = DateTime.MaxValue; public static DateTime minValue = DateTime.MinValue; /// /// 门锁编程事件通知 /// [System.Serializable] public class LocaDoorLockObj { /// /// 用户id ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id /// public int UserID; /// /// 开锁类型 /// 常用: /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹 ///不常用: /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定) /// public int UnlockType; /// /// 关联账户的ID /// public string ConnectedAccount = string.Empty; /// /// 门锁用户名 /// public string UserName = string.Empty; /// /// 门锁录入的时 /// public DateTime EntryTime = System.DateTime.MinValue; /// /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null /// public string PrimaryId = ""; } #endregion #region 与云端通讯接口 #region 门锁服务器发送基本信息 /// /// 添加门锁 /// public class BaseDoorLockServerData { /// /// RequestVersion /// public string RequestVersion = Shared.Common.CommonPage.RequestVersion; /// /// LoginAccessToken /// public string LoginAccessToken = Shared.Common.Config.Instance.Token; /// /// 住宅Id -->键名 : HomeId /// public string HomeId = Shared.Common.Config.Instance.HomeId; /// /// 门锁Id -->键名 : DoorLockId /// public string DoorLockId = ""; /// /// 门锁本地用户Id -->键名 : DoorLockLocalUserId /// public string DoorLockLocalUserId = ""; } #endregion #region 添加门锁 /// /// 添加门锁 /// public class AddDoorLockData : BaseDoorLockServerData { /// /// 云端帐号Id -->键名 : CloudAccountId /// public string CloudAccountId = ""; /// /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选) /// public int OpenLockMode = 0; /// /// Data 相关内容(如:密码、指纹、IC卡 的二进制) -->键名 : Data (可选) public byte[] Data = null; /// /// 用户Id备注 -->键名 : UserIdRemarks /// public string UserIdRemarks = ""; /// /// IsFreezeUser 是否冻结用户 -->键名 : IsFreezeUser (可选) /// public bool IsFreezeUser = false; /// /// IsTempUnlockAuthority 是否临时开锁权限 -->键名 : IsTempUnlockAuthority(可选) /// public bool IsTempUnlockAuthority = false; /// /// EntryTime 录入时间 -->键名 : EntryTime(可选) /// public DateTime EntryTime = System.DateTime.Now; } /// /// 添加门锁结果 /// public class AddDoorLockDataRes { /// /// 响应的版本号,一般请求什么版本号,这里与之请求相同 /// public string ResponseVersion = string.Empty; /// /// 响应状态码: ///(1)Success 则[调用此接口操作成功], ResponseData则为null ///(2)ParameterOrEmpty,则响应字段中[ErrorInfo] 为错误信息, ResponseData则为null ///(3)NoLogin,则响应字段中[ErrorInfo] 为错误信息为[无效登录Token!] ///(4)NoRecord,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId值在云端不存在,请确认值是否正确!] ///(5)DoorLockIdNoIsYou,则响应字段中[ErrorInfo] 为错误信息为[当前提交DoorLockId并不属于你当前帐号的,请确认值是否正确!] /// public string StateCode = string.Empty; } #endregion #region 更新门锁 /// /// 更新门锁 /// public class RefreshDoorLockData : BaseDoorLockServerData { /// /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null /// public string PrimaryId = ""; /// /// 云端帐号Id -->键名 : CloudAccountId /// public string CloudAccountId = ""; /// /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选) /// public int OpenLockMode = 0; /// /// 住宅Id (可选) /// public byte[] Data; /// /// 用户Id备注 /// public string UserIdRemarks = ""; /// /// 是否为管理员门锁 /// public bool IsFreezeUser; /// /// 是否为管理员门锁 /// public bool IsTempUnlockAuthority; } #endregion #region 删除门锁 /// /// 删除门锁 /// public class DeleteDoorLockData : BaseDoorLockServerData { /// /// PrimaryId 门锁云端主 键(非更新字段,以下均为更新字段) -->键名 : PrimaryId默认值: null /// public string PrimaryId = ""; /// /// 门锁Id -->键名 : DoorLockId (可选) /// public int DelDoorLockDelType; } #endregion #region 获取门锁 /// /// 获取门锁 /// public class GetDoorLockData : BaseDoorLockServerData { /// /// 云端帐号Id -->键名 : CloudAccountId (可选) /// public string CloudAccountId = ""; /// /// OpenLockMode 开锁方式(密码、指纹、IC卡) -->键名 : OpenLockMode (可选) /// //public int OpenLockMode = 0; } [Serializable] public class GetDoorLockDataRes { public List PageData = new List(); public int PageIndex; public int PageSize; public int TotalCount; public int TotalPages; public bool HasPreviousPage; public bool HasNextPage; } [Serializable] public class CloudDoorLockObj { /// /// 门锁Id /// public string DoorLockId; /// /// 云端帐号Id /// public string CloudAccountId; /// /// OpenLockMode 开锁方式(密码、指纹、IC卡) /// public int OpenLockMode; /// /// 门锁本地用户Id /// public string DoorLockLocalUserId; /// /// 住宅Id /// public byte[] Data; /// /// 用户Id备注 /// public string UserIdRemarks; /// /// 是否为管理员门锁 /// public bool IsAdminDoorLock; /// /// 是否为管理员门锁 /// public bool IsFreezeUser; /// /// 是否为管理员门锁 /// public bool IsTempUnlockAuthority; /// /// 录入时间 /// public DateTime EntryTime; /// /// 最后更新时间 /// public string LastChangeTime; /// /// 【门锁云端主键】,用于【添加门锁历史】接口中的DoorLockId参数及【删除门锁】接口中的PrimaryId参数,注意不是网关中的【门锁Id /// public string Id; /// /// 创建时间 /// public DateTime CreatedOnUtc; } /// /// 获取门锁给云服务器 /// public static async System.Threading.Tasks.Task GetDoorLockInfoFromServer(string RequestName, GetDoorLockData getDoorLockData) { return await System.Threading.Tasks.Task.Run((Func>)(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(result); int i = 0; } } return listInfo; })); } #endregion /// /// 发送门锁数据到服务器,只回复状态,没有数据处理 /// /// 获取从接口那里取到的ResponsePack /// 访问地址 /// 一个类 public static async Task SendDoorLockToServer(string RequestName, object obj) { try { //序列化对象 var requestJson = JsonConvert.SerializeObject(obj); //访问接口 var result = await CommonPage.Instance.RequestHttpsZigbeeAsync(RequestName, System.Text.Encoding.UTF8.GetBytes(requestJson)); return result; } catch (Exception ex) { Console.WriteLine(ex.Message); return null; } } /// /// 获取子账户信息 /// static List DoorLockAccountList = new List { }; public static async System.Threading.Tasks.Task> GetSubAccountByDistributedMark() { DoorLockAccountList.Clear(); return await System.Threading.Tasks.Task.Run((Func>>)(async () => { var pra = new Shared.Phone.UserCenter.MemberListInfoPra(); string result = await UserCenterLogic.GetResponseDataByRequestHttps("ZigbeeUsers/GetSubAccountByDistributedMark", false, pra); var listInfo = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); return listInfo; })); } /// /// 服务器获取数据失败提示 /// 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 门锁操作事件通知 /// /// 门锁操作事件通知 /// public DoorLockOperatingEventNotificationCommand doorLockOperatingEventNotificationCommand; /// /// 门锁操作事件通知 /// [System.Serializable] public class DoorLockOperatingEventNotificationCommand { /// /// 用户id ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id /// public int UserID; /// /// 事件触发源 /// 常用: /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹 ///不常用: /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定) /// public int OperationEventSource; /// /// 事件码 /// 常用: /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件 ///不常用: /// 请查看枚举 /// public int OperationEventCode; /// /// 保留,默认0 /// public int PIN; /// /// 门锁本地当前时间的时间戳 /// public int ZigbeeLocalTime; } public class AccountsObj { /// /// 关联app账号 /// public string Account; /// /// 保留 /// public int Type; /// /// 保留 /// public int Status; } /// /// “OperationEventSoure”列表 /// public enum OperationEventSoure { /// /// 键盘/密码 /// Keypad = 0, /// /// Zigbee无线 /// RF = 1, /// /// 手动 /// Manual = 2, /// /// 射频卡 /// RFID = 3, /// /// 指纹 /// Fingerprint = 15, /// /// Indeterminate(不确定) /// Indeterminate = 255, } /// /// “OperationEventSoure”类型为“Keypad”即密码 的“OperationEventCode”事件 /// public enum KeypadEventDescription { /// /// 未知事件 /// UnknownEvent = 0, /// /// Lock命令成功事件 /// LockSuccessEvent = 1, /// /// Unlock命令成功事件 /// UnlockSuccessEvent = 2, /// /// Lock命令:error,invalid PIN事件 /// LockInvalidPinEvent = 3, /// /// Lock命令:error,invalid schedule事件 /// LockInvalidScheduleEvent = 4, /// /// Unlock命令:error,invalid PIN事件 /// UnlockInvalidPinEvent = 5, /// /// Unlock命令:error,invalid schedule事件Unlock命令:error,invalid schedule事件 /// UnlockInvalidScheduleEvent = 6, /// /// 非访问用户操作事件 /// NonAccess = 15, } /// /// “OperationEventSoure”类型为“RF” 的“OperationEventCode”事件 /// public enum RfEventDescription { /// /// 未知事件 /// UnknownEvent = 0, /// /// Lock命令成功事件 /// LockSuccessEvent = 1, /// /// Unlock命令成功事件 /// UnlockSuccessEvent = 2, /// /// Lock命令:error,invalid code事件 /// LockInvalidPinEvent = 3, /// /// Lock命令:error,invalid schedule事件 /// LockInvalidScheduleEvent = 4, /// /// Unlock命令:error,invalid code事件 /// UnlockInvalidPinEvent = 5, /// /// Unlock命令:error,invalid schedule事件 /// UnlockInvalidScheduleEvent = 6, } /// /// “OperationEventSoure”类型为“Manual” 的“OperationEventCode”事件 /// public enum ManualEventDescription { /// /// 未知事件 /// UnknownEvent = 0, /// /// Thumbturn Lock;手动转动上锁 /// ThumbturnLockEvent = 1, /// /// Thumbturn Unlock;手动转动解锁 /// UnlockSuccessEvent = 2, /// /// One touch Lock;一键上锁 /// LockInvalidPinEvent = 7, /// ///Key Lock;按键上锁 /// LockInvalidScheduleEvent = 8, /// /// Key Unlock;按键解锁 /// UnlockInvalidPinEvent = 9, /// /// Auto lock;自动上锁 /// UnlockInvalidScheduleEvent = 10, /// /// Schedule Lock;时间表上锁 /// ScheduleLockEvent = 11, /// /// Schedule Unlock;时间表解锁 /// ScheduleUnlockEvent = 12, /// /// Manual Lock(Key or Thumbturn);手动上锁 /// ManualLockEvent = 13, /// ///anual Unlock(Key or Thumbturn);手动解锁 /// ManualUnlockEvent = 14, } /// /// “OperationEventSoure”类型为“RFID” 的“OperationEventCode”事件 /// public enum RfidEventDescription { /// /// 未知事件 /// UnknownEvent = 0, /// /// Lock命令成功事件 /// LockSuccessEvent = 1, /// /// Unlock命令成功事件 /// UnlockSuccessEvent = 2, /// /// Lock命令:error,invalid RFID ID事件 /// LockInvalidRfidIdEvent = 3, /// /// Lock命令:error,invalid schedule事件 /// LockInvalidScheduleEvent = 4, /// /// Unlock命令:error,invalid RFID ID事件 /// UnlockInvalidRfidIdEvent = 5, /// /// Unlock命令:error,invalid schedule事件 /// UnlockInvalidScheduleEvent = 6, } #endregion #region 门锁编程事件通知 /// /// 门锁编程事件通知 /// public DoorLockProgrammingEventNotificationCommand doorLockProgrammingEventNotificationCommand; /// /// 门锁编程事件通知 /// [System.Serializable] public class DoorLockProgrammingEventNotificationCommand { /// /// 用户id ///门锁本地录入的密码、指纹、感应卡都有唯一对应的用户Id /// public int UserID; /// /// 保留 /// public int UserType; /// /// 保留 /// public int UserStatus; /// /// 编程事件触发源 /// 常用: /// 0:Keypad(键盘/密码);3:RFID(射频卡);15:指纹 ///不常用: /// 1:RF(Zigbee无线);2:Manual(手动);255:Indeterminate(不确定) /// public int ProgramEventSoure; /// /// 编程事件码 /// 常用: /// 键盘/密码,指纹、感应卡:1:Lock命令成功事件;2:Unlock命令成功事件 ///不常用: /// 请查看枚举 /// public int ProgramEventCode; /// /// 保留,默认0 /// public int PIN; /// /// 门锁本地当前时间的时间戳 /// public int ZigbeeLocalTime; } #endregion #region 临时密码信息 /// /// 临时密码本地存储对象 /// public TempPasswordObj tempPasswordObj = new TempPasswordObj(); /// /// 临时密码本地对象 /// [System.Serializable] public class TempPasswordObj { /// /// 门锁有效时间 /// public int validTime; /// /// 门锁时间 /// public int times; } #endregion #region 私有命令 #region 用户管理控制 /// ///用户管理控制 /// passData:透传数据 /// public async System.Threading.Tasks.Task DefaultControlAsync(string passData) { DefaultControlResponseAllData result = null; if (Gateway == null) { result = new DefaultControlResponseAllData { errorMessageBase = "当前没有网关" }; return result; } return await System.Threading.Tasks.Task.Run(async () => { Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(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("Data_ID") }; gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(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 = Convert.ToInt32(data[10].ToString() + data[11].ToString() + data[12].ToString() + data[13].ToString(), 16); tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16); result = new DefaultControlResponseAllData { defaultControlResponseData = tempD }; DebugPrintLog($"UI收到通知后的主题_command:0402_{ 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 > WaitReceiveDataTime) { result = new DefaultControlResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 用户管理发送数据 /// 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; } /// /// 用户管理发送数据回复 /// public DefaultControlResponseAllData defaultControlResponseAllData; [System.Serializable] public class DefaultControlResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 用户管理数据回复 /// public DefaultControlResponseData defaultControlResponseData; } /// /// 用户管理数据回复 /// [System.Serializable] public class DefaultControlResponseData { /// ///响应操作码(0-ffff) /// public int command = -1; /// /// 状态值 /// 默认响应结果: ///0 删除成功 ///1 删除失败 ///2 用户不存在 ///32 冻结成功 ///34 冻结失败 ///33 解冻成功 ///35 解冻失败 /// public int status = -1; } public enum AccessType { /// /// 0x00 删除全部单次用户 /// DelAllUsers = 0, /// /// 0x01 删除指定用户(按编号) /// DelCurrentUser = 1, /// /// 0x20 冻结指定用户 /// DisEnable = 2, /// /// 0x21 解冻指定用户 /// Enable = 3, } #endregion #region 验证门锁密码 /// ///验证门锁密码 ///inputPassword:输入的门锁密码 /// public async System.Threading.Tasks.Task VerifyPasswordAsync(string inputPassword) { VerifyPasswordResponseAllData result = null; if (Gateway == null) { result = new VerifyPasswordResponseAllData { errorMessageBase = "当前没有网关" }; return result; } return await System.Threading.Tasks.Task.Run(async () => { Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(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("Data_ID") }; gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(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:0402_{ 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) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { result = new VerifyPasswordResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 验证门锁密码 /// 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; } /// /// 用户管理发送数据回复 /// public VerifyPasswordResponseAllData verifyPasswordResponseAllData; [System.Serializable] public class VerifyPasswordResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 用户管理数据回复 /// 0:成功 ///1:失败 /// public int result = -1; } #endregion #region 远程开锁 /// ///远程开锁 ///inputPassword: 输入密码/para> /// public async System.Threading.Tasks.Task RemoteControlAsync(string inputPassword) { ResponseAllData result = null; if (Gateway == null) { result = new ResponseAllData { errorMessageBase = "当前没有网关" }; return result; } return await System.Threading.Tasks.Task.Run(async () => { Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { result = new ResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { result = new ResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbDataPassthrough") { var gatewayTemp = new ZbGateway() { DataID = jobject.Value("Data_ID") }; gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gatewayTemp.clientDataPassthroughResponseData == null) { result = new ResponseAllData { 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 ResponseData(); tempD.command = Convert.ToInt32(data[10].ToString() + data[11].ToString() + data[12].ToString() + data[13].ToString(), 16); tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16); result = new ResponseAllData { responseData = tempD }; System.Console.WriteLine($"UI收到通知后的主题_command:0400_{ 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 < 9000)// WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (result != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { result = new ResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 远程发送数据 /// 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; } #endregion #region 临时密码发送数据 /// ///远程开锁 ///inputPassword: 输入密码/para> /// public async System.Threading.Tasks.Task 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 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(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("Data_ID") }; gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(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 = Convert.ToInt32(data[10].ToString() + data[11].ToString() + data[12].ToString() + data[13].ToString(), 16); tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16); result = new TempPasswordResponseAllData { responseData = tempD }; System.Console.WriteLine($"UI收到通知后的主题_command:0400_{ 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) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { result = new TempPasswordResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 临时密码发送数据 /// 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 += passwordStr.Substring(i, 2); } var startTimeStr = System.Convert.ToString(GetUnixTimeStamp(startTime, false), 16); var endTimeStr = System.Convert.ToString(GetUnixTimeStamp(endTime, false), 16); 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 + vaildTimeStr; } catch { }; return data; } /// /// 临时密码回复数据 /// public TempPasswordResponseAllData keyColorDataResponseAllData; [System.Serializable] public class TempPasswordResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 临时密码回复数据 /// public TempPasswordResponseData responseData; } /// /// 临时密码回复数据 /// [System.Serializable] public class TempPasswordResponseData { /// ///响应操作码(0-ffff) /// public int command = -1; /// /// 状态值 /// 0--注册成功 /// 1--注册失败 /// 2--用户已存在(重复密码) /// 3-- 用户已满(+已满类型回复) /// 4--有效时间重叠 /// public int status = -1; } #endregion #region 获取门锁密钥 /// /// 门锁随机密码 /// 获取加密的随机密钥,返回的密钥经过一个简单的加法加密加上0x190605,因此获取的密钥需要减上0x190605 /// /// async System.Threading.Tasks.Task 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; } /// ///获取门锁密钥 /// async System.Threading.Tasks.Task 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 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(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("Data_ID") }; gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(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; }); } /// /// 获取门锁密钥 /// 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; } /// /// 获取门锁密钥回复 /// [System.Serializable] public class KeyPasswordInfo { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// ///密钥类型 /// /// public int keyType = -1; /// /// 密钥 /// public string keyPassword; } #endregion #region 读取锁上信息 /// ///读取锁上信息 /// public async System.Threading.Tasks.Task GetDoorlockUserInfoAsync() { DoorlockUserInfo result = null; 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 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(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(); 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); 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 { } //接收一个包最多等5秒,没有收到就退出 while ((DateTime.Now - dateTime).TotalMilliseconds < 5000) { await System.Threading.Tasks.Task.Delay(100); } Gateway.Actions -= action; DebugPrintLog("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 读取锁上信息 /// 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; } /// /// 读取锁上信息回复 /// [System.Serializable] public class DoorlockUserInfo { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 门锁设备返回信息 /// public DoorLockUserDetailData doorLockUserDetailData; } /// /// 门锁设备返回信息 /// public class DoorLockUserDetailData { /// /// 类型 /// public int userType; /// /// 数据包总数 /// public int totalNum; /// /// 数据包序号 /// public int currentNum; /// /// 虚拟驱动信息 /// public List UserObjList = new List(); } public class UserObj { /// /// 门锁用户类型 /// public int UserType; /// /// 门锁用户Id号 /// public int UserId; } #endregion /// /// 获取从格林威治时间到当前某一时刻的总毫秒数 /// /// 北京时间 /// 精确到毫秒,否到秒 /// 返回一个长整数时间戳 public static long GetUnixTimeStamp(DateTime dateTime, bool accurateToMilliseconds) { DateTime startTime = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));//北京所在东八区 DateTime endTime = TimeZoneInfo.ConvertTimeToUtc(dateTime); return (long)(accurateToMilliseconds ? (endTime - startTime).TotalMilliseconds : (endTime - startTime).TotalSeconds); } /// /// 将UNIX时间戳转为北京时间 /// /// 时间戳 /// 精确到毫秒,佛为秒 /// public static DateTime GetLocalTime(int unixTimeStamp, bool accurateToMilliseconds) { DateTime startTime = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));//北京所在东八区 return (accurateToMilliseconds ? startTime.AddMilliseconds(unixTimeStamp) : startTime.AddSeconds(unixTimeStamp)).ToLocalTime(); } #endregion } }