using System; using System.Collections.Generic; using ZigBee.Common; using Shared; using System.Linq; using System.Text; using System.Threading; using System.Net.Sockets; using System.Net; using Newtonsoft.Json.Linq; using MQTTnet; using Shared.Common; using Shared.Phone.UserView; using MQTTnet.Client; using System.Threading.Tasks; namespace ZigBee.Device { /// ƒ /// ZigBee网关对象 /// [System.Serializable] public class ZbGateway : ZbGatewayData { #region 一堆变量 /// /// 主网关 /// [Newtonsoft.Json.JsonIgnore] public static ZbGateway MainGateWay { get { ZbGateway mainWay = null; for (int i = 0; i < GateWayList.Count; i++) { if (GateWayList[i].HomeId == Config.Instance.HomeId) { //2020.07.16变更:别管那么多,如果住宅ID一样,先确定就是它了(不然有时候经常返回null,有可能是刷新不到) mainWay = GateWayList[i]; if (mainWay.IsMainGateWay == true) { //然后如果它确实是主网关,直接break break; } } } return mainWay; } } /// /// 是否使用远程连接模式 /// [Newtonsoft.Json.JsonIgnore] public static bool IsRemote; /// /// 网关保存路径 /// /// The file path. [Newtonsoft.Json.JsonIgnore] public string FilePath { get { var fileName = "Gateway_" + DeviceType.ZbGateway.ToString() + "_" + this.GwId; return fileName; } } /// /// 等待从网关接收数据的时间 /// /// The wait receive data time. [Newtonsoft.Json.JsonIgnore] public int WaitReceiveDataTime { get { if (Device.ZbGateway.RemoteMqttClient != null && Device.ZbGateway.RemoteMqttClient.IsConnected) { return 10000; } else { return 3000; } } } /// /// 局域网加密密码 /// private string password; /// /// 局域网加密密钥 /// [Newtonsoft.Json.JsonIgnore] public string Password { get { if (password == null) { password = Guid.NewGuid().ToString().Substring(0, 16); } return password; } } /// /// 网关远程连接的一个标识ID,获取到了就不再改变 /// [Newtonsoft.Json.JsonIgnore] private static string RemoteClientId = new Random().Next(10, 99).ToString(); /// /// 网关是否加密 /// [Newtonsoft.Json.JsonIgnore] public bool IsEncry; /// /// 网关当前公钥 /// [Newtonsoft.Json.JsonIgnore] public string PubKey; /// /// 所有的网关列表 /// [Newtonsoft.Json.JsonIgnore] public static List GateWayList = new List(); /// /// 网关推送数据 /// 第一个参数:如果为 DeviceInComingRespon:设备新上报 /// 第一个参数:如果为 DeviceStatusReport:设备上报 /// 第一个参数:如果为 IASInfoReport:IAS安防信息上报 /// 第一个参数:如果为 DeviceStatusReport:设备上报 /// 第一个参数:如果为 EnOrWithdrawSucceedReport:通过外部方式布防撤防成功时报告 /// 第一个参数:如果为 DownloadFileProgress:下载进度 /// 第一个参数:如果为 CordinatorUpgradePercent:协调器升级百分比 /// 第一个参数:如果为 DeviceUpgradePercent:节点设备升级百分比 /// 第一个参数:如果为 VirtualDriveUpgrade:虚拟设备升级进度 /// 第一个参数:如果为 ZoneTriggerReport:防区被触发时报告 /// 第一个参数:如果为 LogicExecuteReport:逻辑被调用反馈 /// 第一个参数:如果为 TimingWillArrive:时间点条件推迟执行 /// 第一个参数: 如果为 ModeTriggerReport:模式安防动作被最终激活时发送报警信息 /// 第一个参数:如果为 EnOrWithdrawSucceedReport:通过外部方式布防撤防成功时报告息 /// 第一个参数:如果为 PushTargetInfoReport:胁迫密码撤防时短信推送 /// 第一个参数:如果为 DDevice/IsGetEpointInfo:有新设备加入zigbee网络反馈设备请求APP获取升级数据 /// 第一个参数:如果为 Device/DeviceJoinZbNet:获取新设备所有端点信息是否成功反馈 /// 第一个参数:如果为 DeviceRequestAcUpdateData: 设备请求空调发升级数据 /// [Newtonsoft.Json.JsonIgnore] public Action ReportAction; /// /// 网关文件流内容通知 /// [Newtonsoft.Json.JsonIgnore] public Action FileContentAction; /// /// 网关回复数据内容通知 /// [Newtonsoft.Json.JsonIgnore] public Action GwResDataAction; /// /// 与网关通讯时发送和接收数据通知 /// [Newtonsoft.Json.JsonIgnore] public Action Actions; #endregion #region 网关API #region 网关信息 /// ///获取网关版本信息 /// gateway:当前网关 /// public async System.Threading.Tasks.Task GetZbGwVersionInfoAsync() { return await System.Threading.Tasks.Task.Run(async () => { GetGwVersionAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GetGwVersionAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GetGwVersionAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "GetZbGwVersionRespon") { var getGwVersion = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (getGwVersion == null) { d = new GetGwVersionAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GetGwVersionAllData { getGwVersion = getGwVersion }; //Save(); DebugPrintLog($"UI收到通知后的主题_{topic}"); } } }; Actions += action; DebugPrintLog("GetGwVersionData_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 92 } }; Send("GetZbGwVersion", 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 GetGwVersionAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GetGwVersionData_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 获取网关信息 /// /// 获取网关信息 /// gateway:当前网关 /// public async System.Threading.Tasks.Task GetZbGwInfoAsync() { return await System.Threading.Tasks.Task.Run(async () => { GetGwAllData data = null; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "GetZbGwInfo_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); var getGwInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (getGwInfo == null) { data = new GetGwAllData { errorMessageBase = "网关返回的数据为空" }; } else { data = new GetGwAllData { getGwData = getGwInfo }; DebugPrintLog($"UI收到通知后的主题_{topic}"); } } }; Actions += action; DebugPrintLog("GetGwData_Actions 启动" + "_" + System.DateTime.Now.ToString()); var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 95 } }; Send("GetZbGwInfo", jObject.ToString()); var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (data != null) { break; } } Actions -= action; DebugPrintLog("GetGwData_Actions 退出" + System.DateTime.Now.ToString()); return data; }); } #endregion #region 读取协调器MAC地址. /// /// 读取协调器MAC地址/端点默认是08 /// public async System.Threading.Tasks.Task ReadMacAsync() { return await System.Threading.Tasks.Task.Run(async () => { GetMacResponData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GetMacResponData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GetMacResponData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGw/GetMac_Respon") { var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { d = new GetMacResponData { errorMessageBase = "网关返回的数据为空" }; } else { d = new GetMacResponData { macAddrData = tempData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; var jObject = new JObject { { "Cluster_ID", 64512 }, { "Command", 13 } }; Send(("ZbGw/GetMac"), jObject.ToString()); 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 GetMacResponData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; return d; }); } #endregion #region 修改网关名称 /// /// 修改网关名称 ///gwName:网关名称 /// public async System.Threading.Tasks.Task GwReNameAsync(string gwName) { return await System.Threading.Tasks.Task.Run(async () => { GwReNameAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GwReNameAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GwReNameAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "GwReName_Respon") { var gwRename = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwRename == null) { d = new GwReNameAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new GwReNameAllData { gwReNameData = gwRename }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("GwReName_Actions 启动" + System.DateTime.Now.ToString()); try { var bytes = new byte[32]; var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(gwName); System.Array.Copy(reamarkGwBytes, 0, bytes, 0, 32 < reamarkGwBytes.Length ? 32 : reamarkGwBytes.Length); gwName = System.Text.Encoding.UTF8.GetString(bytes); var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 91 } }; var data = new JObject { { "GwName", gwName } }; jObject.Add("Data", data); Send("GwReName", 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 GwReNameAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GwReName_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 设定网关住宅id /// /// 设定网关住宅id /// homeId:住宅id /// public async System.Threading.Tasks.Task GwSetHomeIdAsync(string homeId) { return await System.Threading.Tasks.Task.Run(async () => { GwSetHomeIdAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GwSetHomeIdAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GwSetHomeIdAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "GwSetHomeId_Respon") { var gwSetHomeId = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwSetHomeId == null) { d = new GwSetHomeIdAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new GwSetHomeIdAllData { gwSetHomeIdData = gwSetHomeId }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("GwReName_Actions 启动" + System.DateTime.Now.ToString()); try { //账号ID string accountId = string.Empty; if (homeId != string.Empty) { accountId = Config.Instance.Guid; } var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 82 } }; var data = new JObject { { "HomeId", homeId }, { "AccountId", accountId } }; jObject.Add("Data", data); //住宅ID的设置,固定使用局域网,不存在远程的说法 SendLocation("GwSetHomeId", System.Text.Encoding.UTF8.GetBytes(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 GwSetHomeIdAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GwReName_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 允许设备入网 /// /// 搜索新入网的设备(允许设备入网) /// Time:0-255,0:关闭搜索,255:一直开启 /// public async void AddNewDeviceToGateway(int time = 3) { await System.Threading.Tasks.Task.Run(async () => { Action action1 = (topic, message) => { }; Actions += action1; var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 94 } }; var data = new JObject { { "Time", time } }; jObject.Add("Data", data); Send(("SearchNewDevice"), jObject.ToString()); Actions -= action1; }); } #endregion #region 协调器恢复出厂设置 /// ///zigbee协调器恢复出厂设置 /// DelAllInfo:0/1 /// 0:仅将协调器恢复出厂设置,不删除网关保存的设备列表,组列表,场景列表等信息。 ///1:将协调器恢复出厂设置,并删除网关保存的设备列表,组列表,场景列表等信息。 /// public void GwOperationReset(int delAllInfo) { Action action = (topic, message) => { }; Actions += action; try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 160 } }; var data = new JObject { { "DelAllInfo", delAllInfo } }; jObject.Add("Data", data); Send(("ZbGwOperation/Reset"), jObject.ToString()); } catch { } Actions -= action; } #endregion #region 网关恢复出厂设置 /// ///网关恢复出厂设置 /// 该指令用于网关linux系统恢复出厂设置。恢复出厂设置后,系统将自动重启 /// 0:命令已接收,系统即将恢复出厂并重启。 /// public async System.Threading.Tasks.Task GwLinuxResetAsync() { return await System.Threading.Tasks.Task.Run(async () => { GwLinuxResetResponData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GwLinuxResetResponData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GwLinuxResetResponData { errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "GwLinuxReset_Respon") { var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (result == null) { d = new GwLinuxResetResponData { errorMessageBase = "网关返回的数据为空" }; } else { d = new GwLinuxResetResponData { Result = result }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("GwLinuxReset Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 84 } }; Send("GwLinuxReset", 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 GwLinuxResetResponData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GwLinuxReset Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 重启网关系统 /// ///重启网关系统 /// 发送该指令将使网关主动断开所有mqtt连接并执行重启。重启时间大约需要60秒 /// 返回值是0:命令已接收,系统即将重启。 /// public async System.Threading.Tasks.Task GwRebootAsync() { return await System.Threading.Tasks.Task.Run(async () => { GwRebootResponAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GwRebootResponAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GwRebootResponAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "GwReboot_Respon") { var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (result == null) { d = new GwRebootResponAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new GwRebootResponAllData { Result = result }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("GwReboot Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 83 } }; Send("GwReboot", 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 GwRebootResponAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GwReboot Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 网关和协调器升级 /// ///保存zigbee协调器组网信息 /// public async System.Threading.Tasks.Task SaveNVFile(string imageName, string imagePath) { return await System.Threading.Tasks.Task.Run(async () => { SaveNVFileResponseAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new SaveNVFileResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new SaveNVFileResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGwOperation/SaveNVFile_Respon") { var zbGwOperationSaveNVFileData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (zbGwOperationSaveNVFileData == null) { d = new SaveNVFileResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new SaveNVFileResponseAllData { saveNVFileResponseData = zbGwOperationSaveNVFileData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("ZbGwOperation/SaveNVFile Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 500 } }; var data = new JObject { { "ImageName", imageName }, { "ImagePath", imagePath } }; jObject.Add("Data", data); Send(("ZbGwOperation/SaveNVFile"), 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 SaveNVFileResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("ZbGwOperation/SaveNVFile Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 协调器恢复组网信息 /// ///协调器恢复组网信息 /// public async System.Threading.Tasks.Task RestoreNV(string imageName, string imagePath) { return await System.Threading.Tasks.Task.Run(async () => { RestoreNVAllDtta d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new RestoreNVAllDtta { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new RestoreNVAllDtta { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGwOperation/RestoreNV_Respon") { var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { d = new RestoreNVAllDtta { errorMessageBase = "网关返回的数据为空" }; } else { d = new RestoreNVAllDtta { restoreNVDtta = tempData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("ZbGwOperation/RestoreNV Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 501 } }; var data = new JObject { { "ImageName", imageName }, { "ImagePath", imagePath } }; jObject.Add("Data", data); Send(("ZbGwOperation/RestoreNV"), 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 RestoreNVAllDtta { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("ZbGwOperation/RestoreNV Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 获取协调器当前信道. /// /// 获取协调器当前信道 /// public async System.Threading.Tasks.Task GetChannelAsync() { return await System.Threading.Tasks.Task.Run(async () => { GwGetChannelResponData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new GwGetChannelResponData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new GwGetChannelResponData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGw/GetChannel_Respon") { var channel = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Channel"].ToString()); d = new GwGetChannelResponData { channel = channel }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog("ZbGw/GetChannel Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 64512 }, { "Command", 8 } }; Send(("ZbGw/GetChannel"), 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 GwGetChannelResponData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("ZbGw/GetChannel Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 更改协调器当前信道 /// /// 更改协调器当前信道 /// Channel:要更改的信道: 11 -26 /// public async System.Threading.Tasks.Task ChangeChannelAsync(int channel) { return await System.Threading.Tasks.Task.Run(async () => { ChangeChannelResponAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new ChangeChannelResponAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new ChangeChannelResponAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGw/ChangeChannel_Respon") { var tempInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempInfo == null) { d = new ChangeChannelResponAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new ChangeChannelResponAllData { changeChannelResponData = tempInfo }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; try { var jObject = new JObject { { "Cluster_ID", 64512 }, { "Command", 9 } }; var data = new JObject { { "Channel", channel } }; jObject.Add("Data", data); Send(("ZbGw/ChangeChannel"), 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 ChangeChannelResponAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; return d; }); } #endregion #region 数据透传1(数据是十六进制形式的字符串) /// ///客户端向节点设备透传数据,(数据是十六进制形式的字符串) /// deviceAddr:设备的mac地址 /// devicePoint:设备端口号 /// PassData:透传的数据,最大256个字符,也就是透传128个字节 /// public async void ClientDataPassthrough(string deviceAddr, int devicePoint, string passData) { await System.Threading.Tasks.Task.Run(async () => { Action action = (topic, message) => { }; Actions += action; try { var jObject = new JObject { { "DeviceAddr", deviceAddr }, { "Epoint", devicePoint }, { "Cluster_ID", 64513 }, { "Command", 0 } }; Send(("ClientDataPassthrough"), jObject.ToString()); } catch { } Actions -= action; }); } #region 数据透传2(数据是二进制流) /// /// 客户端发送文件流到网关(数据是二进制流) /// passData: 透传数据 ///Result 0: 数据写入成功,请求发送下一个数据包 ///Result1:数据写入失败 ///Result2:数据解析错误 ///Result3:发送数据大小超出限制 /// public async System.Threading.Tasks.Task ClientDataPassthroughBytesAsync(string deviceAddr, int devicePoint, long dataLength, byte[] passData) { var myDevice = Shared.Phone.HdlDeviceCommonLogic.Current.GetDevice(deviceAddr, devicePoint); Panel.PanelSwitchLevelInfo result = null; if (myDevice.Gateway == null) { result = new Panel.PanelSwitchLevelInfo { 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 temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { result = new Panel.PanelSwitchLevelInfo { errorMessageBase = "网关错误回复,且数据是空" }; } else { result = new Panel.PanelSwitchLevelInfo { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbDataPassthrough") { var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (clientDataPassthroughResponseData == null) { result = new Panel.PanelSwitchLevelInfo { 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 == "0407") { var level1 = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16); var level2 = Convert.ToInt32(data[12].ToString() + data[13].ToString(), 16); result = new Panel.PanelSwitchLevelInfo { panelDirectionsLevel = level1, panelBacklightLevel = level2 }; System.Console.WriteLine($"UI收到通知后的主题_command:0406_{ topic}"); } } } } } }; myDevice.Gateway.Actions += action; System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString()); try { var sendDataBytes = new byte[12 + dataLength]; sendDataBytes[0] = 0xfe; //设备端点,1个bytes sendDataBytes[1] = Convert.ToByte(devicePoint); //设备mac地址,小端结构,8个bytes //var addrAllBytes = new byte[8]; int j = 0; for (int i = 14; i >= 0; i = i - 2) { var curByte = deviceAddr.Substring(i, 2); //00 0d 6f ff fe 04 51 52 sendDataBytes[2 + j] = Convert.ToByte(string.Format("0x{0}", curByte), 16); j++; } //数据长度,1个bytes sendDataBytes[10] = Convert.ToByte(dataLength % 256); // DataLen 0x01 到 0x800 (即每次最大发送2048字节)2 sendDataBytes[11] = Convert.ToByte(dataLength / 256); //透传数据 System.Array.Copy(passData, 0, sendDataBytes, 12, dataLength); await Send("ClientDataPassthrough", sendDataBytes); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (result != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { result = new Panel.PanelSwitchLevelInfo { errorMessageBase = " 回复超时,请重新操作" }; } myDevice.Gateway.Actions -= action; System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } #endregion #endregion #region 启用或关闭透传数据上传接口 /// /// 启用或关闭透传数据上传接口 /// /// The scene new identifier async. /// Gateway. /// 0:关闭透传数据上传 ;1:开启透传数据上传 public async System.Threading.Tasks.Task GetSceneNewIdAsync(int IsOn) { return await System.Threading.Tasks.Task.Run(async () => { PassthroughAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new PassthroughAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new PassthroughAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbDataPassthrough") { var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); d = new PassthroughAllData { passData = temp }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog("ZbDataPassthrough_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 64513 }, { "Command", 1 } }; Send("GetZbGwVersion", 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 PassthroughAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("GetGwVersionData_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 网关升级 /// /// 网关升级 /// /// The upgrade async. /// Image name:(升级固件名称,名称中要带有“LINUXMODULE”标识,否则将不会升级。最大128字节 public async System.Threading.Tasks.Task LinuxUpgradeAsync(string imageName) { return await System.Threading.Tasks.Task.Run(async () => { LinuxUpgradeAllData d = null; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new LinuxUpgradeAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new LinuxUpgradeAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGwOperation/LinuxUpgrade_Respon") { var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Result"].ToString()); d = new LinuxUpgradeAllData { Result = result }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog("ZbGwOperation/LinuxUpgrade_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 503 } }; var data = new JObject { { "IsForce", 0}, { "SaveChange", 1}, { "ImageName", imageName}, { "ImagePath", "/tmp"} }; jObject.Add("Data", data); Send(("ZbGwOperation/LinuxUpgrade"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000) { await System.Threading.Tasks.Task.Delay(10); if (d != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000) { d = new LinuxUpgradeAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("ZbGwOperation/LinuxUpgrade_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 协调器升级 /// /// 协调器升级 /// /// The NVA sync. /// Image name:(升级镜像名称,名称中要带有“ZBMODULE”标识,否则不允许升级。最大128字节。) public async System.Threading.Tasks.Task UpgradeNVAsync(string imageName) { return await System.Threading.Tasks.Task.Run(async () => { ZbGwOperationUpgradeAllData d = null; ; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new ZbGwOperationUpgradeAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new ZbGwOperationUpgradeAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "ZbGwOperation/Upgrade_Respon") { zbGwOperationUpgradeData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (zbGwOperationUpgradeData == null) { d = new ZbGwOperationUpgradeAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new ZbGwOperationUpgradeAllData { bGwOperationUpgradeData = zbGwOperationUpgradeData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("ZbGwOperation/Upgrade_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 502 } }; var data = new JObject { { "ImageName", imageName }, { "ImagePath", "/tmp" } }; jObject.Add("Data", data); Send(("ZbGwOperation/Upgrade"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000) { await System.Threading.Tasks.Task.Delay(10); if (d != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000) { d = new ZbGwOperationUpgradeAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("ZbGwOperation/Upgrade_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 下载云端固件. /// /// 下载云端网关或协调器固件. /// /// The file async. /// Distributed mark:固件唯一标识 /// Image name:固件版本 public async System.Threading.Tasks.Task DownloadFileAsync(string distributedMark, string imageName) { return await System.Threading.Tasks.Task.Run(async () => { CommonDevice.DownloadFileResponAllData d = null; ; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new CommonDevice.DownloadFileResponAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new CommonDevice.DownloadFileResponAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "DownloadFile_Respon") { var downloadFileResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (downloadFileResponData == null) { d = new CommonDevice.DownloadFileResponAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new CommonDevice.DownloadFileResponAllData { downloadFileResponData = downloadFileResponData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("DownloadFile_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 6000 } }; var data = new JObject { { "DistributeMark", distributedMark}, { "DownloadPath", "/tmp" }, { "FileName", imageName } }; jObject.Add("Data", data); Send(("DownloadFile"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000) { await System.Threading.Tasks.Task.Delay(10); if (d != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000) { d = new CommonDevice.DownloadFileResponAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("DownloadFile_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 查看网关记录的虚拟驱动. /// /// 查看网关记录的虚拟驱动 /// public async System.Threading.Tasks.Task CheckVDDriveCodeAsync() { return await System.Threading.Tasks.Task.Run(async () => { CheckVDDriveCodeResponseAllData d = null; ; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new CheckVDDriveCodeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new CheckVDDriveCodeResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "VirtualDrive/CatDriveCode_Respon") { var vDriveDriveCodeResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (vDriveDriveCodeResponData == null) { d = new CheckVDDriveCodeResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new CheckVDDriveCodeResponseAllData { vDriveDriveCodeResponData = vDriveDriveCodeResponData }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } } }; Actions += action; DebugPrintLog("VirtualDriveDriveCode_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 505 } }; Send(("VirtualDrive/CatDriveCode"), 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 CheckVDDriveCodeResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("VirtualDriveDriveCode_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 升级虚拟驱动设备. /// /// 升级虚拟驱动设备 /// oTAImageName:升级镜像名称 /// driveCode:驱动代号 /// public async System.Threading.Tasks.Task VirtualDriveUpgradeAsync(string imageName, int driveCode) { return await System.Threading.Tasks.Task.Run(async () => { VirtualDriveUpgradeResponseAllData d = null; ; Action 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(jobject["Data"].ToString()); if (temp == null) { d = new VirtualDriveUpgradeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { d = new VirtualDriveUpgradeResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "VirtualDrive/Upgrade_Respon") { virtualDriveUpgradeResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (virtualDriveUpgradeResponData == null) { d = new VirtualDriveUpgradeResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { d = new VirtualDriveUpgradeResponseAllData { virtualDriveUpgradeResponData = virtualDriveUpgradeResponData }; DebugPrintLog($"UI收到通知后的主题_{topic}"); } } }; Actions += action; DebugPrintLog("VirtualDrive/Upgrade_Actions 启动" + "_" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 504 } }; var data = new JObject { { "ImageName", imageName }, { "ImagePath", "/tmp" }, { "DriveCode", driveCode } }; jObject.Add("Data", data); Send(("VirtualDrive/Upgrade"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000) { await System.Threading.Tasks.Task.Delay(10); if (d != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000) { d = new VirtualDriveUpgradeResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Actions -= action; DebugPrintLog("VirtualDrive/Upgrade_Actions 退出" + System.DateTime.Now.ToString()); return d; }); } #endregion #region 客户端上传文件到网关. /// /// 客户端上传文件到网关 /// /// The admin password async. /// 上传文件后,保存的文件名称 /// 文件保存在系统的目录路径,如果目录不存在系统将自动创建该目录。如:/tmp/. public async System.Threading.Tasks.Task CreateFileAsync(string fileName, string filePath = "/etc/hdlDat") { return await System.Threading.Tasks.Task.Run(async () => { CreateFileResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new CreateFileResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new CreateFileResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/CreateFile_Respon") { var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Result"].ToString()); dataRes = new CreateFileResponseAllData { Result = result }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog("FileTransfer/CreateFile_Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3000 } }; var data = new JObject { { "FileName", fileName }, { "FilePath", filePath } }; jObject.Add("Data", data); Send(("FileTransfer/CreateFile"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new CreateFileResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/CreateFile_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 客户端发送文件流到网关 /// /// 客户端发送文件流到网关 ///Result 0: 数据写入成功,请求发送下一个数据包 ///Result1:数据写入失败 ///Result2:数据解析错误 ///Result3:发送数据大小超出限制 /// public async System.Threading.Tasks.Task SendFileAsync(byte[] data) { if (data == null) { return new SendFileResponseAllData { errorMessageBase = "数据内容是空" }; } return await System.Threading.Tasks.Task.Run(async () => { var isRespond = true; SendFileResponseAllData dataRes = null; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); if (topic == gatewayID + "/FileTransfer/SendFile_Respon") { var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Result"].ToString()); dataRes = new SendFileResponseAllData { Result = result }; if (result == 0) { isRespond = true; } DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog("FileTransfer/SendFile_Actions 启动" + System.DateTime.Now.ToString()); try { var fileBytes = data; var size = 2048; var dateTime = DateTime.Now; for (int i = 0, tempSize = 0; i < fileBytes.Length; i += tempSize) { while (!isRespond) { if (WaitReceiveDataTime < (DateTime.Now - dateTime).TotalMilliseconds) { return new SendFileResponseAllData { errorMessageBase = "回复超时,请重新操作" }; ; } await System.Threading.Tasks.Task.Delay(10); } isRespond = false; byte finish = 0; if (i + size < fileBytes.Length) { tempSize = size; } else if (i + size == fileBytes.Length) { tempSize = size; finish = 1; } else { tempSize = fileBytes.Length % size; finish = 1; } var bytes = new byte[8 + tempSize]; bytes[0] = 0xfe; bytes[1] = 0; bytes[2] = 0; bytes[3] = 0; bytes[4] = 0; bytes[5] = finish;//0x00 或 0x01 bytes[6] = Convert.ToByte(tempSize % 256); // DataLen 0x01 到 0x800 (即每次最大发送2048字节)2 bytes[7] = Convert.ToByte(tempSize / 256); System.Array.Copy(fileBytes, i, bytes, 8, tempSize); dateTime = DateTime.Now; await Send("FileTransfer/SendFile", bytes); DebugPrintLog($"上传到网关当前数据数量_{i}_是不是最后一个_{finish}_{System.DateTime.Now.ToString()}"); } } catch { } finally { Actions -= action; } DebugPrintLog("Security/ChangeAdminPassword_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 查看网关目录文件信息. /// /// 查看网关目录文件信息 /// /// The admin password async. /// 文件保存在系统的目录路径,如果目录不存在系统将自动创建该目录。如:/tmp/. public async System.Threading.Tasks.Task FileTransferLsDirAsync(string filePath = "/etc/hdlDat") { return await System.Threading.Tasks.Task.Run(async () => { FileTransferLsDiResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new FileTransferLsDiResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new FileTransferLsDiResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/lsDir_Respon") { var resultlsDir = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (resultlsDir != null) { dataRes = new FileTransferLsDiResponseAllData { fileTransferLsDiResponseData = resultlsDir }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } else { dataRes = new FileTransferLsDiResponseAllData { errorMessageBase = "收到的网关返回数据是空" }; } } }; Actions += action; DebugPrintLog("FileTransfer/lsDir_Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3002 } }; var data = new JObject { { "FilePath", filePath } }; jObject.Add("Data", data); Send(("FileTransfer/lsDir"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new FileTransferLsDiResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/lsDir_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 查看单个文件信息. /// /// 查看单个文件信息 /// /// The admin password async. /// 文件保存在系统的目录路径,如果目录不存在系统将自动创建该目录。如:/tmp/. public async System.Threading.Tasks.Task GetCurrentFileInfoAsync(string fileName, string filePath = "/etc/hdlDat/") { return await System.Threading.Tasks.Task.Run(async () => { FileTransferGetFileInfoResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new FileTransferGetFileInfoResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new FileTransferGetFileInfoResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/GetFileInfo_Respon") { var resultlsDir = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (resultlsDir != null) { dataRes = new FileTransferGetFileInfoResponseAllData { fileTransferGetFileInfoResponseData = resultlsDir }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } else { dataRes = new FileTransferGetFileInfoResponseAllData { errorMessageBase = "收到的网关返回数据是空" }; } } }; Actions += action; DebugPrintLog("FileTransfer/GetFileInfo_Actions 启动" + System.DateTime.Now.ToString()); try { var tempFilePath = filePath + fileName; var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3007 } }; var data = new JObject { { "File", tempFilePath } }; jObject.Add("Data", data); Send(("FileTransfer/GetFileInfo"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new FileTransferGetFileInfoResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/GetFileInfo_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 客户端设定要下载的文件名称和路径 /// /// 客户端设定要下载的文件名称和路径 /// fileName:下载的文件名称. /// blockStartAddress:可忽略,默认为0。下载开始地址,用于断点续传。如:文件总大小为1000Byte,客户端下载了200Byte后连接意外断开。当客户端重新连接后想继续下载后续文件流而不想从文件头重新开始下载,可将该参数设置为200,网关将从第2001Byte开始发送文件流。 /// filePath">文件所在系统的目录路径。如:/tmp. /// public async System.Threading.Tasks.Task SetDownloadFileAsync(string fileName, int blockStartAddress = 0, string filePath = "/etc/hdlDat") { return await System.Threading.Tasks.Task.Run(async () => { SetDownloadFileResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new SetDownloadFileResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new SetDownloadFileResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/SetDownloadFile_Respon") { var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData != null) { dataRes = new SetDownloadFileResponseAllData { }; var tempDa = new SetDownloadFileResponseData(); if (tempData.Result == 0) { this.byteSource.Clear(); } tempDa.Result = tempData.Result; dataRes.setDownloadFileResponseData = tempDa; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } else { dataRes = new SetDownloadFileResponseAllData { errorMessageBase = "收到的网关返回数据是空" }; } } }; Actions += action; DebugPrintLog("FileTransfer/SetDownloadFile_Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3003 } }; var data = new JObject { { "FileName", fileName }, { "FilePath", filePath }, { "BlockStartAddress", blockStartAddress } }; jObject.Add("Data", data); Send(("FileTransfer/SetDownloadFile"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new SetDownloadFileResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/SetDownloadFile_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 网关发送文件流到客户端 private List byteSource = new List(); /// /// 下载文件中的数据 /// public void DownloadFileConfirmAsync(byte[] fileBytes) { int result = 0; if (fileBytes[5] != 1) { if (fileBytes.Length == 2056) { result = 0; var tempBytes = new byte[2048]; System.Array.Copy(fileBytes, 8, tempBytes, 0, 2048); byteSource.AddRange(tempBytes); } else { var tempBytes = new byte[fileBytes.Length - 8]; System.Array.Copy(fileBytes, 8, tempBytes, 0, tempBytes.Length); byteSource.AddRange(tempBytes); return; } } else { var tempBytes = new byte[fileBytes.Length - 8]; System.Array.Copy(fileBytes, 8, tempBytes, 0, tempBytes.Length); byteSource.AddRange(tempBytes); return; } try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3004 } }; var data = new JObject { { "Result", result } }; jObject.Add("Data", data); Send("FileTransfer/DownloadFile_Respon", jObject.ToString()); } catch { } } #endregion #region 删除文件或目录 /// /// 删除文件或目录 /// /// The admin password async. /// 删除目录或文件的路径。如:/tmp/,则删除tmp目录。/tmp/aa.txt,则删除tmp目录下的aa.txt文件。 public async System.Threading.Tasks.Task DelFileOrDirAsync(string path = "/etc/hdlDat") { return await System.Threading.Tasks.Task.Run(async () => { DelFileOrDirResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new DelFileOrDirResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new DelFileOrDirResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/DelFileOrDir_Respon") { var resultDelFileOrDir = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (resultDelFileOrDir != null) { dataRes = new DelFileOrDirResponseAllData { delFileOrDirResponseData = resultDelFileOrDir }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } else { dataRes = new DelFileOrDirResponseAllData { errorMessageBase = "收到的网关返回数据是空" }; } } }; Actions += action; DebugPrintLog("FileTransfer/DelFileOrDir_Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3005 } }; var data = new JObject { { "Path", path } }; jObject.Add("Data", data); Send(("FileTransfer/DelFileOrDir"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new DelFileOrDirResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/DelFileOrDir_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 创建一个目录. /// /// 创建一个目录 /// /// The admin password async. /// 删除目录或文件的路径。如:/tmp/,则删除tmp目录。/tmp/aa.txt,则删除tmp目录下的aa.txt文件。 public async System.Threading.Tasks.Task CreateDirAsync(string path = "/etc/hdlDat") { return await System.Threading.Tasks.Task.Run(async () => { CreateDirResponseAllData dataRes = null; Action 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(jobject["Data"].ToString()); if (temp == null) { dataRes = new CreateDirResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { dataRes = new CreateDirResponseAllData { errorResponData = temp, errorMessageBase = CommonDevice.ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "FileTransfer/CreateDir_Respon") { var resultCreateDir = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (resultCreateDir != null) { dataRes = new CreateDirResponseAllData { createDirResponseData = resultCreateDir }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } else { dataRes = new CreateDirResponseAllData { errorMessageBase = "收到的网关返回数据是空" }; } } }; Actions += action; DebugPrintLog("FileTransfer/CreateDir_Actions 启动" + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 3006 } }; var data = new JObject { { "Path", path } }; jObject.Add("Data", data); Send(("FileTransfer/CreateDir"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (dataRes != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime) { dataRes = new CreateDirResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; }; Actions -= action; DebugPrintLog("FileTransfer/CreateDir_Actions 退出" + System.DateTime.Now.ToString()); return dataRes; }); } #endregion #region 客户端发送密钥到网关 /// /// 客户端发送DES密钥到网关 /// DES密钥经RSA公钥加密转成base64后所得的字符串信息 /// public async System.Threading.Tasks.Task SendAesKeyAsync(string aesKey) { return await System.Threading.Tasks.Task.Run(async () => { SendKeyResponData sendKeyResponData = null; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "SendAESKey_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); var result = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Result"].ToString()); sendKeyResponData = new SendKeyResponData { Result = result }; DebugPrintLog($"UI收到通知后的主题_{ topic}"); } }; Actions += action; DebugPrintLog($"SendAESKey_Actions 启动_{System.DateTime.Now.ToString()}"); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 100 } }; var data = new JObject { { "AesKey", aesKey } }; jObject.Add("Data", data); Send(("SendAESKey"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime) { await System.Threading.Tasks.Task.Delay(10); if (sendKeyResponData != null) { break; } } Actions -= action; DebugPrintLog($"SendAESKey_Actions 退出_{System.DateTime.Now.ToString()}"); return sendKeyResponData; }); } #endregion #endregion #region 设备状态更新 /// /// 设备状态监听列表 /// 进入当前界面时要添加 /// 退出当前界面时要关闭 /// public static readonly List StatusList = new List(); /// /// 设备信息变化 /// type:如果为 DeviceInComingRespon:设备新上报 /// type:如果为 IASInfoReport:RemoveDeviceRespon /// type:如果为 DeviceStatusReport:设备上报 /// type:如果为 IASInfoReport:IAS安防信息上报 /// type:如果为 OnlineStatusChange: 设备在线状态更新 /// /// Common device. public static void UpdateDeviceInfo(CommonDevice commonDevice, string type) { if (commonDevice == null) { return; } for (int i = 0; i < StatusList.Count; i++) { StatusList[i].DeviceInfoChange(commonDevice, type); } } #endregion #region 本地通讯连接 /// /// 本地连接是否连接成功 /// [Newtonsoft.Json.JsonIgnore] public bool LocalIsConnected; /// /// 局域网的MQTT /// private IMqttClient localMqttClient = new MqttFactory().CreateMqttClient(); /// /// 本地mqtt是否正在连接中 /// private bool localMqttIsConnecting; /// /// 本地连接的一个客户端ID(app启动之后就不变了) /// private static Guid LocalConnectGuid = Guid.NewGuid(); public async Task SendAesKey() { if (PubKey != null) { IsEncry = false; var rsaString = ZigBee.Common.SecuritySet.RSAEncrypt(PubKey, Password); var resultVerityfy = await SendAesKeyAsync(rsaString); if (resultVerityfy == null) { resultVerityfy = await SendAesKeyAsync(rsaString); } if (resultVerityfy != null && resultVerityfy.Result == 0) { IsEncry = true; } } } public async Task StartLocalMqtt(string brokerName) { if (localMqttIsConnecting || Shared.Common.Config.Instance.HomeId == "" || LocalIsConnected) { return; } await Task.Factory.StartNew(async () => { try { lock (localMqttClient) { //表示后面将进行连接 localMqttIsConnecting = true; //(3)当[连接Mqtt成功后]或者[Mqtt转发数据给网关成功后],处理接收到数据包响应时在mqttClient_ApplicationMessageReceived这个方法处理 if (localMqttClient.ApplicationMessageReceivedHandler == null) { localMqttClient.UseApplicationMessageReceivedHandler((e) => { if (!localMqttClient.IsConnected) { return; } mqttClient_MqttMsgPublishReceived(e); }); } if (localMqttClient.DisconnectedHandler == null) { localMqttClient.UseDisconnectedHandler(async (e) => { DebugPrintLog($" 本地连接断开_网关IP:{brokerName}_网关是否加:{IsEncry}"); await DisConnectLocalMqttClient("StartLocalMqtt.DisconnectedHandler"); //await StartLocalMqtt("ReConnect"); }); } if (localMqttClient.ConnectedHandler == null) { localMqttClient.UseConnectedHandler(async (e) => { DebugPrintLog($" 本地连接成功_网关IP:{brokerName}_网关是否加:{IsEncry}_当前密码:{Password}"); IsRemote = false; //Log写入(调试用) if (Shared.Phone.HdlUserCenterResourse.HideOption.WriteSendAndReceveDataToFile == 1) { Shared.Phone.HdlLogLogic.Current.WriteLog(2, "本地连接成功"); } }); } var dateTime = DateTime.Now; new System.Threading.Thread(async () => { try { if (localMqttClient.Options == null) { var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder()//MQTT连接参数填充 .WithClientId(LocalConnectGuid.ToString())//客户端ID .WithTcpServer(brokerName, 1883)//TCP服务端 1883 ,即MQTT服务端 .WithCredentials("", "")//"", "")//凭证 帐号 密码 .WithCommunicationTimeout(new TimeSpan(0, 0, 60)) //重连超时时间,默认5s .WithKeepAlivePeriod(new TimeSpan(0, 0, 15)) //保持连接时间,默认5s,心跳包 .Build();// await localMqttClient.ConnectAsync(options); } else { await DisConnectLocalMqttClient("StartLocalMqtt"); await localMqttClient.ReconnectAsync(); } LocalIsConnected = true; await SendAesKey(); } catch { } dateTime = DateTime.MinValue; }) { IsBackground = true }.Start(); while (dateTime != DateTime.MinValue) { System.Threading.Thread.Sleep(100); } } } catch (Exception ex) { //Log写入(调试用) if (Shared.Phone.HdlUserCenterResourse.HideOption.WriteSendAndReceveDataToFile == 1) { Shared.Phone.HdlLogLogic.Current.WriteLog(2, "本地连接异常:\r\n" + ex.Message); } DebugPrintLog($"局域网通讯连接出异常:{ex.Message}"); } finally { localMqttIsConnecting = false; } }); } /// /// 断开服务器连接 /// public async Task DisConnectLocalMqttClient(string s) { try { if (LocalIsConnected) { LocalIsConnected = false; //这个东西也要弄 localMqttIsConnecting = false; DebugPrintLog($"Local主动断开_{s}"); //await localMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None); await localMqttClient.DisconnectAsync(); } } catch (Exception ex) { DebugPrintLog($"Local断开通讯连接出异常:{ex.Message}"); } } /// /// 强制断开本地的网关连接 /// public async Task CloseLocalConnectionOnForce() { try { await localMqttClient.DisconnectAsync(); } catch { } finally { LocalIsConnected = false; //这个东西也要弄 localMqttIsConnecting = false; } } #endregion #region 远程通讯连接 /// /// 当前有帐号下所有的云端网关列表及信息 /// public static Dictionary DicGatewayBaseInfo = new Dictionary { }; /// /// 外网的MQTT是否正在连接 /// private static bool remoteMqttIsConnecting; /// /// 远程MqttClient /// public static IMqttClient RemoteMqttClient = new MqttFactory().CreateMqttClient(); /// /// 远程连接是否完成 /// private static bool remoteIsConnected; /// /// 远程开始连接的时间点 /// private static DateTime RemoteConnectTime = DateTime.Now; /// /// 启动远程Mqtt /// public static async Task StartRemoteMqtt() { //追加:没有远程连接的权限 if (Config.Instance.Home.IsRemoteControl == false || Config.Instance.Home.Id == "" || remoteIsConnected) { return; } //如果远程还在连接中 if (remoteMqttIsConnecting == true) { //如果这个变量一直处于连接中的状态,但是已经过去了10秒了,还是true的话,说明这里是有点问题的,需要重新创建 if ((DateTime.Now - RemoteConnectTime).TotalMilliseconds < 10 * 1000) { return; } } //记录起这次远程连接的时间点 RemoteConnectTime = DateTime.Now; //初始化远程mqtt事件 InitRemoteMqttEvent(); try { //获取远程mqtt链接信息 var pra = new { attachClientId = RemoteClientId, homeType = "ZIGBEE" }; var result = Shared.Phone.HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/mqtt/getRemoteInfo", RestSharp.Method.POST, pra); if (result != null && result.Code == Shared.Phone.HttpMessageEnum.A成功) { var jobject = JObject.Parse(result.Data.ToString()); var connEmqClientId = jobject["clientId"]?.ToString(); var connEmqUserName = jobject["userName"]?.ToString(); var connEmqPwd = jobject["passWord"]?.ToString(); //记录起当前的客户端ID Config.Instance.ConnEmqClientId = connEmqClientId; var connEmqDomainPorts = jobject["url"].ToString().Replace("//", "").Split(':'); var domain = connEmqDomainPorts[1]; var port = connEmqDomainPorts[2]; var options = new MQTTnet.Client.Options.MqttClientOptionsBuilder() .WithClientId(connEmqClientId) .WithTcpServer(domain, int.Parse(port)) .WithCredentials(connEmqUserName, connEmqPwd) .WithKeepAlivePeriod(TimeSpan.FromSeconds(20)) .WithCleanSession() .Build(); await DisConnectRemoteMqttClient("StartRemoteMqtt"); await RemoteMqttClient.ConnectAsync(options, CancellationToken.None); remoteIsConnected = true; } } catch { } finally { //最终要释放连接状态 remoteMqttIsConnecting = false; } } /// /// 初始化远程mqtt事件 /// private static void InitRemoteMqttEvent() { lock (RemoteMqttClient) { //表示后面将进行连接 remoteMqttIsConnecting = true; //(3)当[连接云端的Mqtt成功后]或者[以及后面App通过云端Mqtt转发数据给网关成功后],处理接收到云端数据包响应时在mqttServerClient_ApplicationMessageReceived这个方法处理 if (RemoteMqttClient.ApplicationMessageReceivedHandler == null) { RemoteMqttClient.UseApplicationMessageReceivedHandler((e) => { //这里是特殊的主题 if (e.ApplicationMessage.Topic == "/ZigbeeGateWayToClient/" + Config.Instance.ConnEmqClientId + "/Push/NotifySqueeze"//踢人下线 || e.ApplicationMessage.Topic == "/ZigbeeGateWayToClient/" + Config.Instance.Guid + "/Push/Deleted"//分享删除 || e.ApplicationMessage.Topic == "/ZigbeeGateWayToClient/" + Config.Instance.Guid + "/Push/DeletedShareData"//分享删除 || e.ApplicationMessage.Topic == "/ZigbeeGateWayToClient/" + Config.Instance.Guid + "/Push/Update"//成员权限变更 || e.ApplicationMessage.Topic == "/ZigbeeGateWayToClient/" + Config.Instance.Home.Id + "_" + Config.Instance.Guid + "/PrimaryUserDelYou")//子账号被删除 { mqttRemoteClient_MqttMsgPublishReceived(e); return; } if (!RemoteMqttClient.IsConnected || !IsRemote) { return; } mqttRemoteClient_MqttMsgPublishReceived(e); }); } if (RemoteMqttClient.DisconnectedHandler == null) { RemoteMqttClient.UseDisconnectedHandler(async (e) => { DebugPrintLog($"远程连接断开"); await DisConnectRemoteMqttClient("StartRemoteMqtt.DisconnectedHandler"); }); } if (RemoteMqttClient.ConnectedHandler == null) { RemoteMqttClient.UseConnectedHandler(async (e) => { DebugPrintLog($"远程连接成功"); if (Config.Instance.Home.IsOtherShare == true) { //订阅一个成员被删除的主题 string myGuid = Config.Instance.Guid; await RemoteMqttClient.SubscribeAsync("/ZigbeeGateWayToClient/" + myGuid + "/Push/Deleted"); //订阅一个分享数据已经变更的主题 await RemoteMqttClient.SubscribeAsync("/ZigbeeGateWayToClient/" + myGuid + "/Push/DeletedShareData"); //订阅一个子账号被删除的主题 await RemoteMqttClient.SubscribeAsync("/ZigbeeGateWayToClient/" + Config.Instance.Home.Id + "_" + myGuid + "/PrimaryUserDelYou"); //订阅一个成员权限已经变更的主题 await RemoteMqttClient.SubscribeAsync("/ZigbeeGateWayToClient/" + myGuid + "/Push/Update"); } //订阅一个挤下线的主题 await RemoteMqttClient.SubscribeAsync("/ZigbeeGateWayToClient/" + Config.Instance.ConnEmqClientId + "/Push/NotifySqueeze"); //如果这个函数卡久了的话,会接收到云端推送的挤下线主题,不知道为什么 new System.Threading.Thread(async () => { await InitGateWayBaseInfomation(); //没有主网关时主动读取,获取主网关信息 var gateWayList = GateWayList.FindAll(obj => obj.HomeId == Shared.Common.Config.Instance.HomeId); if (gateWayList.Find(obj => obj.IsMainGateWay == true) == null) { if (gateWayList.Count == 1) { gateWayList[0].IsMainGateWay = true; } else { for (int i = 0; i < gateWayList.Count; i++) { var gateWay = gateWayList[i]; var info = await gateWay.GetZbGwInfoAsync(); if (info == null || info.getGwData == null) { continue; } if (info.getGwData.IsDominant == 1) { for (int j = 0; j < gateWayList.Count; j++) { if (gateWayList[i].GwId == info.getGwData.GwId) { gateWayList[i].IsMainGateWay = true; } else { gateWayList[i].IsMainGateWay = false; } } break; } } } } }) { IsBackground = true }.Start(); }); } } } /// /// 初始化当前帐号所有的云端网关信息 /// /// private static async Task InitGateWayBaseInfomation() { if (Config.Instance.Home.IsRemoteControl == false) { //没有远程连接的权限 return; } //获取云端网关信息 var listGatewayInfo = Shared.Phone.HdlGatewayLogic.Current.GetGateWayListFromDataBase(Config.Instance.Home.Id); if (listGatewayInfo == null) { return; } foreach (var info in listGatewayInfo.Values) { try { //有可能云端是这么处理:如果没有远程权限,则不给AesKey if (string.IsNullOrEmpty(info.AesKey) == true) { continue; } //保存缓存 DicGatewayBaseInfo[info.Mac] = info; //我也不知道这个是干嘛的 await RemoteMqttClient.SubscribeAsync($"/ZigbeeGateWayToClient/" + info.Id + "/#", MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce); } catch (Exception ex) { Shared.Phone.HdlLogLogic.Current.WriteLog(ex); } } } /// /// 断开远程Mqtt的链接 /// public static async Task DisConnectRemoteMqttClient(string s = "") { try { if (remoteIsConnected) { remoteIsConnected = false; //这个东西也要弄 remoteMqttIsConnecting = false; DebugPrintLog($"Remote主动断开_{s}"); //await RemoteMqttClient.DisconnectAsync(new MQTTnet.Client.Disconnecting.MqttClientDisconnectOptions { }, CancellationToken.None); await RemoteMqttClient.DisconnectAsync(); } } catch (Exception e) { DebugPrintLog($"Remote断开通讯连接出异常:{e.Message}"); } } /// /// 强制断开远程Mqtt的链接 /// /// public static async Task CloseRemoteConnectionOnForce() { try { await RemoteMqttClient?.DisconnectAsync(); } catch { } finally { remoteIsConnected = false; //这个东西也要弄 remoteMqttIsConnecting = false; } } #endregion #region 数据发送 /// /// 发送消息到服务器 /// /// The send. /// Topic. /// Cluster identifier. /// Commnand. /// Message. public void Send(string topic, Cluster_ID cluster_ID, Command commnand, Newtonsoft.Json.Linq.JObject message = null) { var jObject = new Newtonsoft.Json.Linq.JObject() { { "Cluster_ID", (int)cluster_ID }, { "Command", (int)commnand } }; if (message != null) { jObject.Add("Data", message); } Send(topic, System.Text.Encoding.UTF8.GetBytes(jObject.ToString())); } /// /// 远程发送数据格式 /// async System.Threading.Tasks.Task SendRemoteMsg(string topicName, byte[] message, bool retain = false) { try { if (this.GwId == string.Empty || !DicGatewayBaseInfo.ContainsKey(this.GwId)) { return; } var gateWayBaseInfomation = DicGatewayBaseInfo[this.GwId]; message = SecuritySet.AesEncryptBytes(message, gateWayBaseInfomation.AesKey); var topicEncStr = $"/ClientToZigbeeGateWay/{gateWayBaseInfomation.Id}/Common/{topicName}"; //(6)构建Mqtt需要发布的数据包,发布给云端的MqttBroker if (remoteIsConnected) { try { await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicEncStr, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce }); } catch (Exception e) { await DisConnectRemoteMqttClient(e.Message); await StartRemoteMqtt(); if (remoteIsConnected) { await RemoteMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topicEncStr, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce }); } } } } catch { } } /// /// 发送消息到服务器 /// /// /// /// /// public async System.Threading.Tasks.Task Send(string topic, byte[] message, bool retain = false) { try { if (Shared.Common.Config.Instance.HomeId == "") { return; } //Log写入(调试用) if (Shared.Phone.HdlUserCenterResourse.HideOption.WriteSendAndReceveDataToFile == 1) { string text = "远程发送:"; if (IsRemote == false) { text = "本地发送:"; } text += topic + "\r\n"; text += Encoding.UTF8.GetString(message) + "\r\n"; Shared.Phone.HdlLogLogic.Current.WriteLog(2, text); } if (IsRemote) { await SendRemoteMsg(topic, message, retain); DebugPrintLog($"远程——发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}");//{System.DateTime.Now.ToString()}");// DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") } else { DebugPrintLog($"局域网——发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_是否加密:{IsEncry}"); if (IsEncry) { //文件流不用加密 if (topic != "FileTransfer/SendFile") { message = SecuritySet.AesEncryptBytes(message, password); } } if (LocalIsConnected) { try { await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain }); } catch (Exception e) { DebugPrintLog($"Local主动断开_{e.Message}"); await DisConnectLocalMqttClient(e.Message); await StartLocalMqtt("ReConnect"); if (LocalIsConnected) { DebugPrintLog($"局域网——二次发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_是否加密:{IsEncry}"); await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain }); } //Log写入(调试用) if (Shared.Phone.HdlUserCenterResourse.HideOption.WriteSendAndReceveDataToFile == 1) { Shared.Phone.HdlLogLogic.Current.WriteLog(2, "本地连接异常断开"); } } } } } catch (Exception ex) { DebugPrintLog($"Send:{ex.Message}"); } } /// /// 发送消息到服务器 /// /// /// /// /// public async System.Threading.Tasks.Task Send(string topic, string message, bool retain = false) { if (string.IsNullOrEmpty(message)) { return; } await Send(topic, System.Text.Encoding.UTF8.GetBytes(message), retain); } /// /// 强制指定使用本地局域网发送消息到服务器 /// /// /// /// /// public async Task SendLocation(string topic, byte[] message, bool retain = false) { try { if (Shared.Common.Config.Instance.HomeId == "") { return; } DebugPrintLog($"局域网——发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_是否加密:{IsEncry}"); if (IsEncry) { //文件流不用加密 if (topic != "FileTransfer/SendFile") { message = SecuritySet.AesEncryptBytes(message, password); } } if (LocalIsConnected) { try { await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain }); } catch (Exception e) { DebugPrintLog($"Local主动断开_{e.Message}"); await DisConnectLocalMqttClient(e.Message); await StartLocalMqtt("ReConnect"); if (LocalIsConnected) { DebugPrintLog($"局域网——二次发送到网关的主题:{topic}_发送到网关的数据:{System.Text.Encoding.UTF8.GetString(message)}_是否加密:{IsEncry}"); await localMqttClient.PublishAsync(new MqttApplicationMessage { Topic = topic, Payload = message, QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, Retain = retain }); } } } } catch (Exception ex) { DebugPrintLog($"Send:{ex.Message}"); } } #endregion #region 数据接收处理 /// /// 接收远程数据处理 /// /// Sender. /// E. static void mqttRemoteClient_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e) { try { var topic = e.ApplicationMessage.Topic.TrimStart('/'); var payload = e.ApplicationMessage.Payload; var message = string.Empty; //你当前的IP及端口在云端不存在,请重新登录连接下! var topics = topic.Split("/"); if (topics.Length < 3) { return; } if (topics[0] != "ZigbeeGateWayToClient") { return; } if (topics[2] == "NotifyGateWayInfoChange") { InitGateWayBaseInfomation(); return; } if (topics[2] == "Common") { var macMark = topics[1]; topic = topic.Substring(topics[0].Length + topics[1].Length + topics[2].Length + 3); if (payload[0] == (byte)'{' && payload[payload.Length - 1] == (byte)'}') { message = System.Text.Encoding.UTF8.GetString(payload); } else { foreach (var key in DicGatewayBaseInfo.Keys) { var value = DicGatewayBaseInfo[key]; if (value.Id == macMark) { topic = $"{key}/{topic}"; message = System.Text.Encoding.UTF8.GetString(ZigBee.Common.SecuritySet.AesDecryptBytes(e.ApplicationMessage.Payload, value.AesKey)); break; } } } } DebugPrintLog($"远程返回的主题:{ topic}_远程返回的数据_{message}");//{System.DateTime.Now.ToString()}");// DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") ReceiveMessage(topic, message, payload); } catch (Exception ex) { DebugPrintLog($"接收云端数据异常:{ex.Message} "); } } /// /// 接收局域网中的数据 /// 当订阅消息成功后,该事件会被调用 /// /// Sender. /// E. void mqttClient_MqttMsgPublishReceived(MqttApplicationMessageReceivedEventArgs e) { try { var topic = e.ApplicationMessage.Topic; string payloadString = ""; if (IsEncry) { //主题 //下载的字节流不需要解密 if (topic.Split('/')[0] + "/" + topic.Split('/')[1] == topic.Split('/')[0] + "/" + "FileTransfer") { if (topic.Split('/')[2] != "DownloadFile") { payloadString = System.Text.Encoding.UTF8.GetString(Common.SecuritySet.AesDecryptBytes(e.ApplicationMessage.Payload, Password)); } } else if (topic == topic.Split('/')[0] + "/" + "SendAESKey_Respon") { }//回复主题是秘文,数据是明文 else { payloadString = System.Text.Encoding.UTF8.GetString(Common.SecuritySet.AesDecryptBytes(e.ApplicationMessage.Payload, Password)); } } else { payloadString = System.Text.Encoding.UTF8.GetString(e.ApplicationMessage.Payload); } DebugPrintLog($"网关返回的主题:{topic}_网关返回的负载:{payloadString}"); ReceiveMessage(topic, payloadString, e.ApplicationMessage.Payload); } catch (Exception ex) { DebugPrintLog($"接收网关数据异常:{ex.Message}"); } } /// /// 数据接收处理 /// /// Topic. /// Message. /// E. static void ReceiveMessage(string topic, string message, byte[] payload) { try { if (string.IsNullOrEmpty(message)) { message = "{}"; } var gatewayID = topic.Split('/')[0];//网关返回的网关ID var reportStatus = ""; reportStatus = topic.Split('/')[1];//主题为设备上报的主题 string addr = "";//上报的设备addr string epoint = "";//上报的设备epoint string cluID = "";//上报的设备cluID string attrId = "";//上报的设备attrId if (reportStatus == "DeviceStatusReport") { addr = topic.Split('/')[2]; epoint = topic.Split('/')[3]; cluID = topic.Split('/')[4]; attrId = topic.Split('/')[5]; } //Log写入(调试用) if (Shared.Phone.HdlUserCenterResourse.HideOption.WriteSendAndReceveDataToFile == 1) { string text = "网关回复:" + topic + "\r\n"; text += message + "\r\n"; Shared.Phone.HdlLogLogic.Current.WriteLog(2, text); } //全局接收网关推送的的逻辑(为了执行速度,尽可能的别加耗时的操作) Shared.Phone.HdlGatewayReceiveLogic.Current.GatewayOverallMsgReceive(gatewayID, topic, reportStatus, message); var gwa = GateWayList.Find(obj => obj.GwId == gatewayID); if (gwa == null) { return; } if (gwa.Actions != null) { gwa?.Actions(topic, message); } gwa.GwResDataAction?.Invoke(topic, message); var jobject = new Newtonsoft.Json.Linq.JObject(); if (topic.Split('/')[0] + "/" + topic.Split('/')[1] == topic.Split('/')[0] + "/" + "FileTransfer") { if (topic.Split('/')[2] == "DownloadFile") { gwa.DownloadFileConfirmAsync(payload); message = System.Text.Encoding.UTF8.GetString(payload); gwa.FileContentAction?.Invoke(topic, payload); DebugPrintLog($"网关返回数据流_{message}"); return; } } else { jobject = Newtonsoft.Json.Linq.JObject.Parse(message); } #region 远程,主网关上报通知 if (IsRemote) { if (topic == gatewayID + "/" + "BeMainGw_Report") { var gwData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwData != null) { var gwList = GateWayList.FindAll(obj => obj.HomeId == Shared.Common.Config.Instance.HomeId); for (int i = 0; i < gwList.Count; i++) { if (gwList[i].GwId == gatewayID) { gwList[i].IsMainGateWay = true; } else { gwList[i].IsMainGateWay = false; } } } } } #endregion #region 设备在线状态更新反馈 //2020.05.11 删除 #endregion #region 设备状态上报 if (topic == gatewayID + "/" + "DeviceStatusReport" + "/" + addr + "/" + epoint + "/" + cluID + "/" + attrId) { var deviceID = jobject.Value("Device_ID"); var deviceAddr = jobject.Value("DeviceAddr"); var tempEpoint = jobject.Value("Epoint"); var dataId = jobject.Value("Data_ID"); var tempDevice = new CommonDevice { DeviceID = deviceID, DeviceAddr = deviceAddr, DeviceEpoint = tempEpoint }; tempDevice.DeviceStatusReport = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); UpdateDeviceInfo(tempDevice, "DeviceStatusReport"); } #endregion #region 门锁操作事件通知 else if (topic == gatewayID + "/" + "DoorLock/DoorLockOperatingEventNotificationCommand") { var deviceID = jobject.Value("Device_ID"); switch ((DeviceType)(deviceID)) { case DeviceType.DoorLock: var doorLock = new DoorLock() { DeviceID = jobject.Value("Device_ID"), DeviceAddr = jobject.Value("DeviceAddr"), DeviceEpoint = jobject.Value("Epoint"), CurrentGateWayId = gwa.GwId }; var OperatingEventNotificationDatad = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (OperatingEventNotificationDatad != null) { doorLock.doorLockOperatingEventNotificationCommand = OperatingEventNotificationDatad; } if (gwa.ReportAction != null) { DebugPrintLog("DoorLockProgrammingEventNotificationCommand已经通知"); gwa.ReportAction("DoorLockProgrammingEventNotificationCommand", doorLock); } UpdateDeviceInfo(doorLock, "DoorLockProgrammingEventNotificationCommand"); break; } } #endregion #region 门锁编程事件通知 else if (topic == gatewayID + "/" + "DoorLock/DoorLockProgrammingEventNotificationCommand") { var deviceID = jobject.Value("Device_ID"); switch ((DeviceType)(deviceID)) { case DeviceType.DoorLock: var doorLock = new DoorLock() { DeviceID = jobject.Value("Device_ID"), DeviceAddr = jobject.Value("DeviceAddr"), DeviceEpoint = jobject.Value("Epoint"), CurrentGateWayId = gwa.GwId }; var ProgrammingEventNotificationData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (ProgrammingEventNotificationData != null) { doorLock.doorLockProgrammingEventNotificationCommand = ProgrammingEventNotificationData; } if (gwa.ReportAction != null) { DebugPrintLog("DoorLockProgrammingEventNotificationCommand已经通知"); gwa.ReportAction("DoorLockProgrammingEventNotificationCommand", doorLock); } UpdateDeviceInfo(doorLock, "DoorLockProgrammingEventNotificationCommand"); break; } } #endregion #region IAS安防信息上报 //2020.05.11 删除 #endregion #region 下载进度上报 else if (topic == gatewayID + "/" + "DownloadFile_Progress") { gwa.downloadFileProgressResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwa.downloadFileProgressResponData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("DownloadFileProgress"); gwa.ReportAction("DownloadFileProgress", gwa); } } else if (topic == gatewayID + "/" + "ZbGwOperation/Upgrade_Respon") { gwa.zbGwOperationUpgradeData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwa.zbGwOperationUpgradeData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("协调器升级百分比"); gwa.ReportAction("CordinatorUpgradePercent", gwa); } } else if (topic == gatewayID + "/" + "OTA/Schedule_Respon") { gwa.oTAScheduleResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwa.oTAScheduleResponData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("节点设备升级百分比"); gwa.ReportAction("DeviceUpgradePercent", gwa); } } else if (topic == gatewayID + "/" + "VirtualDrive/Upgrade_Respon") { gwa.virtualDriveUpgradeResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwa.virtualDriveUpgradeResponData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("虚拟驱动升级百分比"); gwa.ReportAction("VirtualDriveUpgrade", gwa); } } #endregion #region 重启网关系统 else if (topic == gatewayID + "/" + "GwReboot_Respon") { var gwRebootResponData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (gwRebootResponData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("GwReboot_Respon已经通知"); gwa.ReportAction("GwReboot_Respon", gwRebootResponData); } } #endregion #region 防区被触发时报告 else if (topic == gatewayID + "/" + "Security/ZoneTriggerReport") { var ias = new Safeguard() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; ias.zoneTriggerReportData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (ias.zoneTriggerReportData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("ZoneTriggerReport已经通知"); gwa.ReportAction("ZoneTriggerReport", ias.zoneTriggerReportData); } } #endregion #region 逻辑被调用反馈 else if (topic == gatewayID + "/" + "Logic/Execute_Respon") { //var logic = new Logic() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; //logic.logicExecuteRespo = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); //if (logic.logicExecuteRespo == null) //{ // return; //} ////上报类型通知 //if (gwa.ReportAction != null) //{ // DebugPrintLog("LogicExecuteReport已经通知"); // gwa.ReportAction("LogicExecuteReport", logic.logicExecuteRespo); //} } #endregion #region 时间点条件推迟执行 else if (topic == gatewayID + "/" + "Logic/TimingWillArrive") { //var logic = new Logic() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; //logic.timingWillArriveData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); //if (logic.timingWillArriveData == null) //{ // return; //} ////上报类型通知 //if (gwa.ReportAction != null) //{ // DebugPrintLog("TimingWillArrive已经通知"); // gwa.ReportAction("TimingWillArrive", logic.timingWillArriveData); //} } #endregion #region 模式安防动作被最终激活时发送报警信息 else if (topic == gatewayID + "/" + "Security/ModeTriggerReport") { var ias = new Safeguard() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; ias.modeTriggerReportData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (ias.modeTriggerReportData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("ModeTriggerReport已经通知"); gwa.ReportAction("ModeTriggerReport", ias.modeTriggerReportData); } } #endregion #region 通过外部方式布防撤防成功时报告息 else if (topic == gatewayID + "/" + "Security/EnOrWithdrawSucceedReport") { var ias = new Safeguard() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; ias.enOrWithdrawSucceedReportData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (ias.enOrWithdrawSucceedReportData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("EnOrWithdrawSucceedReport"); gwa.ReportAction("EnOrWithdrawSucceedReport", ias.enOrWithdrawSucceedReportData); } } #endregion #region 胁迫密码撤防时短信推送 else if (topic == gatewayID + "/" + "Security/PushTargetInfo") { var ias = new Safeguard() { DataID = jobject.Value("Data_ID"), GateWayId = gwa.GwId }; ias.coercedPWDWithdrawReportData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (ias.coercedPWDWithdrawReportData == null) { return; } //上报类型通知 if (gwa.ReportAction != null) { DebugPrintLog("PushTargetInfoReport"); gwa.ReportAction("PushTargetInfoReport", ias.coercedPWDWithdrawReportData); } } #endregion #region 设备请求APP获取升级数据 else if (topic == gatewayID + "/" + "ZbDataPassthrough") { //上报类型通知 if (gwa.ReportAction != null) { var clientDataPassthrough = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (clientDataPassthrough != null) { DebugPrintLog("DeviceRequestAcUpdateData"); gwa.ReportAction("DeviceRequestAcUpdateData", clientDataPassthrough); } } } #endregion } catch (Exception ex) { DebugPrintLog($"处理回复的数据抛出异常:{ex.Message}"); } } #endregion #region 保存缓存 /// /// 重新保存设备 /// public void ReSave() { if (Shared.Common.Config.Instance.Home.IsShowTemplate == true) { //展示模板时,不允许保存文件(防止属性上报用的) return; } Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this))); } #endregion #region 调试打印 /// /// 调试时打开打印信息,true:打印,false:不打印 /// /// Message. /// If set to true flage. public static void DebugPrintLog(string msg, bool flage = true) { #if DEBUG if (flage == true) { //if (msg.Contains("DeviceInfoRespon") == true) { System.Console.WriteLine(msg + " " + System.DateTime.Now.ToLongTimeString() + " " + System.DateTime.Now.Millisecond); } } #endif } #endregion } }