using Newtonsoft.Json; using Shared.Common; using System; using System.Collections.Generic; using System.Threading.Tasks; using ZigBee.Device; namespace Shared.Phone.UserCenter { /// /// 网关业务的逻辑类 /// public class HdlGatewayLogic { #region ■ 变量声明___________________________ /// /// 网关业务的逻辑类 /// private static HdlGatewayLogic m_Current = null; /// /// 网关业务的逻辑类 /// public static HdlGatewayLogic Current { get { if (m_Current == null) { m_Current = new HdlGatewayLogic(); } return m_Current; } } /// /// 备份用的网关ID /// private List listBackupGwId = new List(); /// /// 网关文件的前缀名字 /// private string gwFirstName = "Gateway_"; /// /// 全部网关(这里保存的是虚拟网关,而不是真实物理网关对象) /// private Dictionary dicGateway = new Dictionary(); #endregion #region ■ 刷新网关___________________________ /// /// 刷新本地网关信息 /// public void ReFreshByLocal() { lock (dicGateway) { this.dicGateway.Clear(); List listFile = this.GetAllGatewayFile(); //反序列化添加到缓存 foreach (string file in listFile) { //从文件中反序列化出网关对象 var gateway = this.GetGatewayFromFile(file); if (gateway == null) { continue; } //添加缓存 dicGateway[gateway.GwId] = gateway; } } } /// /// 刷新APP前一次选择的网关ID /// public void RefreshAppOldSelectGatewayId() { GatewayResourse.AppOldSelectGatewayId = string.Empty; //从文件中获取上一次选择的网关id byte[] data = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.AppOldSelectGatewayFile); if (data != null) { string strvalue = System.Text.Encoding.UTF8.GetString(data); GatewayResourse.AppOldSelectGatewayId = JsonConvert.DeserializeObject(strvalue); } //如果本地没有这个网关的话 if (this.IsGatewayExist(GatewayResourse.AppOldSelectGatewayId) == false) { GatewayResourse.AppOldSelectGatewayId = string.Empty; lock (dicGateway) { //随便选一个网关 foreach (string wayId in this.dicGateway.Keys) { GatewayResourse.AppOldSelectGatewayId = wayId; break; } } } } /// /// 同步云端的网关id,如果本地拥有云端不存在的id,则表示应该被换绑了,直接删除(切换住宅后,重新刷新网关列表和设备之后使用) /// /// public void SynchronizeDbGateway() { //从云端获取网列表ID Dictionary result = HdlGatewayLogic.Current.GetGateWayListFromDataBase(); if (result == null) { return; } List listBackupGwId = new List(); var fileData = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile); if (fileData != null) { //新增:虽然概率低,但是确实发生了。如果有网络时,App重新绑定记录的网关失败的话 //不应该删除它 listBackupGwId = JsonConvert.DeserializeObject>(System.Text.Encoding.UTF8.GetString(fileData)); } List listDelete = new List(); foreach (var gatewayId in this.dicGateway.Keys) { if (result.ContainsKey(gatewayId) == false && listBackupGwId.Contains(gatewayId) == false) { //本地存在云端不存在的网关,则删除 listDelete.Add(gatewayId); } } foreach (var gatewayId in listDelete) { //删除本地这个网关所有的设备 List list = Common.LocalDevice.Current.GetDeviceByGatewayID(gatewayId); foreach (var device in list) { //删除一般设备 Common.LocalDevice.Current.DeleteMemmoryDevice(device, true); //删除Ota设备 Common.LocalDevice.Current.DeleteMemmoryOtaDevice(device.DeviceAddr); } //删除网关文件 this.DeleteGatewayFile(gatewayId); } //LOG输出 if (listDelete.Count > 0) { string msg = "本地拥有的网关:"; foreach (var gatewayId in this.dicGateway.Keys) { msg += gatewayId + ","; } msg += "\r\n被删除的网关:"; foreach (var gatewayId in listDelete) { msg += gatewayId + ","; } msg += "\r\n此时云端返回当前账号所绑定有的网关:"; foreach (var gatewayId in result.Keys) { msg += gatewayId + ","; } var bytes = System.Text.Encoding.UTF8.GetBytes(msg); Common.Global.WriteFileByBytesByHomeId("GatewayDeleteLog.txt", bytes); } } /// /// 从文件中反序列化出网关对象 /// /// /// private ZbGateway GetGatewayFromFile(string file) { try { byte[] filebyte = Global.ReadFileByHomeId(file); string strvalue = System.Text.Encoding.UTF8.GetString(filebyte); var gateway = JsonConvert.DeserializeObject(strvalue); if (gateway.GwId == string.Empty) { //这是旧数据,需要特殊处理 var jobject = Newtonsoft.Json.Linq.JObject.Parse(strvalue); string gwInfo = jobject["getGwInfo"].ToString(); var result = JsonConvert.DeserializeObject(gwInfo); //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(gateway, result); } return gateway; } catch (Exception ex) { HdlLogLogic.Current.WriteLog(ex); return null; } } #endregion #region ■ 添加网关___________________________ /// /// 添加新网关(仅限追加新的网关) /// /// 网关 /// 是否显示错误 public async Task AddNewGateway(ZbGateway zbGateway, ShowErrorMode mode) { //设置网关的经纬度 bool falge = this.SetGatewaySite(zbGateway, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.NO); if (falge == false) { return falge; } //执行添加网关到内存 var result = await this.DoAddGatewayToMemory(zbGateway, mode); //前的网关绑定在了当前账号下的不同住宅里面 if (result == 0) { if (mode == ShowErrorMode.YES) { //网关绑定在当前账号下的其他住宅里\r\n请解除绑定后再试 string msg = Language.StringByID(R.MyInternationalizationString.uTheGatewayInOtherResidenceMsg); if (msg.Contains("{0}") == true) { msg = string.Format(msg, "\r\n"); } this.ShowTipMsg(msg); } return false; } if (result == -1) { return false; } //添加网关的话,强制主页刷新 UserView.UserPage.Instance.RefreshForm = true; return true; } /// /// 创建一个虚拟的网关对象 /// /// 网关ID public void AddVirtualGateway(string gatewayId) { var gateWay = new ZbGateway { IsVirtual = true }; gateWay.GwId = gatewayId; gateWay.HomeId = Shared.Common.Config.Instance.HomeId; gateWay.ReSave(); this.dicGateway[gatewayId] = gateWay; } /// /// 执行添加网关到内存(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面) /// /// 网关对象 /// 是否显示错误 /// private async Task DoAddGatewayToMemory(ZbGateway zbGateway, ShowErrorMode mode) { if (zbGateway == null) { if (mode == ShowErrorMode.YES) { //错误:网关对象丢失 string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg); this.ShowTipMsg(msg); } return -1; } //获取网关的信息 var result = await zbGateway.GetZbGwInfoAsync(); //检测网关返回的共通错误状态码 string error = HdlCheckLogic.Current.CheckCommonErrorCode(result); if (error != null) { if (mode == ShowErrorMode.YES) { this.ShowTipMsg(error); } return -1; } if (result == null) { if (mode == ShowErrorMode.YES) { //获取网关信息失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail); this.ShowTipMsg(msg); } return -1; } if (result.getGwData == null) { if (mode == ShowErrorMode.YES) { //获取网关信息失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail); this.ShowTipMsg(msg); } return -1; } //设置住宅ID到网关 bool flage2 = await this.SetHomeIdToGateway(zbGateway, Common.Config.Instance.HomeId, mode); if (flage2 == false) { if (mode == ShowErrorMode.YES) { //向网关设置住宅ID失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetHomeIdToGatewayFail); this.ShowTipMsg(msg); } return -1; } //更新云端数据库 int flage1 = this.SetGatewayIdToDataBase(zbGateway); //异常也不鸟它,0是特殊含义 if (flage1 == 0) { return flage1; } if (flage1 == -1) { //备份失败的网关ID this.BackupGatewayIdOnNotNetwork(zbGateway); } //是否已经存在 string gwID = zbGateway.GwId; bool isEsist = this.IsGatewayExist(zbGateway); if (isEsist == false) { //新建一个虚拟的网关出来 zbGateway.ReSave(); var way = this.GetGatewayFromFile(zbGateway.FilePath); this.dicGateway[gwID] = way; } //刷新的是缓存,不刷新真实物理网关 this.dicGateway[gwID].GatewayOnlineFlage = zbGateway.GatewayOnlineFlage; //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result.getGwData); //顺便这个变量也设置一下 this.SetGatewayDataToLocalMemmory(zbGateway, result.getGwData, false); if (isEsist == false) { //添加备份 HdlAutoBackupLogic.AddOrEditorFile(this.dicGateway[gwID].FilePath); } return 1; } /// /// 设置住宅ID到网关(失败时,不弹出任何错误信息,网关断网除外) /// /// /// /// public async Task SetHomeIdToGateway(ZbGateway zbGateway, string HomeId, ShowErrorMode mode) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { if (mode == ShowErrorMode.YES) { //错误:网关对象丢失 string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg); this.ShowTipMsg(msg); } return false; } var info = await realWay.GwSetHomeIdAsync(HomeId); if (info != null && info.gwSetHomeIdData != null) { return true; } return false; } /// /// 更新网关ID到云端数据库(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面) /// /// 网关对象 /// private int SetGatewayIdToDataBase(ZbGateway zbGateway) { //调用接口,绑定网关(即使失败,也返回true往下走) var bindGateway = new BindGatewayPra(); bindGateway.BindGateways.Add(zbGateway.GwId); //获取控制主人账号的Token bindGateway.LoginAccessToken = UserCenterLogic.GetConnectMainToken(); var result = UserCenterLogic.GetResultCodeByRequestHttps("App/BindGatewayToHome", true, bindGateway); if (result == "Error") { return -1; } if (result == "BindGatewaysExists") { return 0; } return result == "Success" ? 1 : -1; } /// /// 住宅ID是否为空 /// /// /// public bool HomeIdIsEmpty(ZbGateway zbGateway) { return this.HomeIdIsEmpty(zbGateway.HomeId); } /// /// 住宅ID是否为空 /// /// /// public bool HomeIdIsEmpty(string HomeId) { if (string.IsNullOrEmpty(HomeId) == true || HomeId[0] == '\0') { return true; } return false; } #endregion #region ■ 重新绑定网关_______________________ /// /// 重新绑定网关(1:正常 -1:异常 0:当前的网关绑定在了当前账号下的不同住宅里面) /// /// 网关 /// 消息控件 public async Task ReBindNewGateway(ZbGateway zbGateway, NormalViewControl btnMsg = null) { if (zbGateway == null) { //错误:网关对象丢失 string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg); this.ShowTipMsg(msg); return -1; } //设置网关的经纬度 bool falge = this.SetGatewaySite(zbGateway, Common.Config.Instance.Home.Longitude, Common.Config.Instance.Home.Latitude, ShowErrorMode.YES); if (falge == false) { return -1; } //设置住宅ID到网关 bool flage2 = await this.SetHomeIdToGateway(zbGateway, Common.Config.Instance.HomeId, ShowErrorMode.YES); if (flage2 == false) { //向网关设置住宅ID失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetHomeIdToGatewayFail); this.ShowTipMsg(msg); return -1; } //更新云端数据库 int flage1 = this.SetGatewayIdToDataBase(zbGateway); //异常也不鸟它,0是特殊含义 if (flage1 == 0) { return flage1; } if (flage1 == -1) { //备份失败的网关ID HdlGatewayLogic.Current.BackupGatewayIdOnNotNetwork(zbGateway); } if (btnMsg == null) { //网关内部数据变更中,请稍后 ProgressBar.SetValue(Language.StringByID(R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait)); } else { HdlThreadLogic.Current.RunMain(() => { //网关内部数据变更中,请稍后 btnMsg.TextID = R.MyInternationalizationString.uGatewayDataIsChangingPleaseWhait; }); } await Task.Delay(8000); //获取网关的信息 ZbGatewayData.GetGwAllData result = null; int count = 5; while (count >= 0) { result = await zbGateway.GetZbGwInfoAsync(); if (result != null && result.getGwData != null) { break; } count--; //最多再等20秒 await Task.Delay(4000); } //检测网关返回的共通错误状态码 string error = HdlCheckLogic.Current.CheckCommonErrorCode(result); if (error != null) { this.ShowTipMsg(error); return -1; } if (result == null || result.getGwData == null) { //获取网关信息失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail); this.ShowTipMsg(msg); return -1; } //是否已经存在 string gwID = zbGateway.GwId; bool isEsist = HdlGatewayLogic.Current.IsGatewayExist(zbGateway); if (isEsist == false) { //新建一个虚拟的网关出来 zbGateway.ReSave(); var way = this.GetGatewayFromFile(zbGateway.FilePath); this.dicGateway[gwID] = way; } //刷新的是缓存,不刷新真实物理网关 this.dicGateway[gwID].GatewayOnlineFlage = zbGateway.GatewayOnlineFlage; //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(this.dicGateway[gwID], result.getGwData); //顺便这个变量也设置一下 this.SetGatewayDataToLocalMemmory(zbGateway, result.getGwData, false); if (isEsist == false) { //添加备份 HdlAutoBackupLogic.AddOrEditorFile(this.dicGateway[gwID].FilePath); } //添加网关的话,强制主页刷新 UserView.UserPage.Instance.RefreshForm = true; return 1; } #endregion #region ■ 修改网关___________________________ /// /// 修改本地网关名字(失败时会显示信息) /// /// 网关对象 /// 网关名 public async Task ReName(ZbGateway zbGateway, string gatewayName) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //获取网关对象失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail); this.ShowErrorMsg(msg); return false; } var result = await realWay.GwReNameAsync(gatewayName); //检测网关返回的共通错误状态码 string error = HdlCheckLogic.Current.CheckCommonErrorCode(result); if (error != null) { this.ShowErrorMsg(error); return false; } if (result == null) { //网关名称修改失败 string msg = Language.StringByID(R.MyInternationalizationString.uGatewayReNameFail); this.ShowErrorMsg(msg); return false; } //网关修改失败 if (result.gwReNameData == null) { //网关名称修改失败 string msg = Language.StringByID(R.MyInternationalizationString.uGatewayReNameFail); this.ShowErrorMsg(msg); return false; } //修改缓存 string gwID = zbGateway.GwId; this.dicGateway[gwID].GwName = gatewayName; this.dicGateway[gwID].ReSave(); //添加自动备份 HdlAutoBackupLogic.AddOrEditorFile(zbGateway.FilePath); return true; } #endregion #region ■ 网关切换___________________________ /// /// 执行切换网关操作 /// /// public async Task DoSwitchGateway(string gatewayId) { var zbGateway = this.GetLocalGateway(gatewayId); if (this.CheckGatewayOnlineByFlag(zbGateway) == true) { //重新获取在线网关的信息 var result = await this.GetOnlineGatewayInfo(gatewayId); if (result == false) { return false; } } //切换网关,保存缓存 this.SaveGatewayIdToLocation(gatewayId); //切换网关的话,主页需要重新刷新 UserView.UserPage.Instance.RefreshForm = true; return true; } /// /// 获取在线网关信息 /// /// /// private async Task GetOnlineGatewayInfo(string gatewayId) { //显示进度条 ProgressBar.Show(); //检测广播到的这个网关是否拥有住宅ID ZbGateway realWay = null; bool getGatewayInfo = true; if (this.GetRealGateway(ref realWay, gatewayId) == true) { //重新设置住宅ID(这个应该是不经过APP,直接把网关恢复了出厂设置) if (this.HomeIdIsEmpty(realWay.HomeId) == true) { int result2 = await this.ReBindNewGateway(realWay); if (result2 == 0) { //出现未知错误,请稍后再试 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uUnKnowErrorAndResetAgain)); //关闭进度条 ProgressBar.Close(); } else if (result2 == -1) { //关闭进度条 ProgressBar.Close(); return false; } //重新绑定网关里面已经重新获取了网关信息 getGatewayInfo = false; } } if (getGatewayInfo == true) { //获取网关信息 var info = this.GetGatewayInfo(realWay); if (info == null) { //关闭进度条 ProgressBar.Close(); return false; } } //获取全部设备 int result = LocalDevice.Current.SetDeviceToMemmoryByGateway(realWay); //关闭进度条 ProgressBar.Close(); if (result == -1) { return false; } return true; } /// /// 保存选择的网关ID到本地 /// /// public void SaveGatewayIdToLocation(string gatewayId) { GatewayResourse.AppOldSelectGatewayId = gatewayId; byte[] data = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(GatewayResourse.AppOldSelectGatewayId)); Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.AppOldSelectGatewayFile, data); } #endregion #region ■ 删除网关___________________________ /// /// 删除网关,包括云端和本地(失败时不会显示信息,并且会返回true) /// /// public async Task DeleteGateway(ZbGateway zbGateway) { //移除本地网关信息 return await this.DeleteGateway(zbGateway.GwId); } /// /// 删除网关,包括云端和本地(失败时不会显示信息,并且会返回true) /// /// public async Task DeleteGateway(string zbGatewayID) { ZbGateway realWay = null; bool hadReal = this.GetRealGateway(ref realWay, zbGatewayID); //暂不支持分享 if (hadReal == true && realWay.GatewayOnlineFlage == true) { //清空网关的住宅ID bool result = await this.SetHomeIdToGateway(realWay, string.Empty, ShowErrorMode.YES); if (result == false) { //网关解绑失败 不理它,因为网关可以按按键强制搜索得到 string msg = Language.StringByID(R.MyInternationalizationString.uGatewayUnBindFail); //this.ShowErrorMsg(msg); //return false; } } //删除云端的网关 this.DeleteDataBaseGateway(zbGatewayID); //删除网关文件 this.DeleteGatewayFile(zbGatewayID); //移除 ZbGateway.GateWayList.RemoveAll((obj) => obj.GwId == zbGatewayID); //断开mqtt连接 realWay.DisConnectLocalMqttClient("GD"); return true; } /// /// 删除网关文件 /// /// 网关id public void DeleteGatewayFile(string zbGatewayID) { if (dicGateway.ContainsKey(zbGatewayID) == false) { return; } //删除文件 string file = dicGateway[zbGatewayID].FilePath; if (Global.IsExistsByHomeId(file) == true) { Global.DeleteFilebyHomeId(file); } //移除缓存 dicGateway.Remove(zbGatewayID); //删除自动备份 HdlAutoBackupLogic.DeleteFile(file); //删除设备文件 List list = Common.LocalDevice.Current.GetDeviceByGatewayID(zbGatewayID); foreach (var device in list) { //删除设备文件 Common.LocalDevice.Current.DeleteMemmoryDevice(device, true); //删除Ota设备 Common.LocalDevice.Current.DeleteMemmoryOtaDevice(device.DeviceAddr); } //如果是主网关 if (this.IsMainGateway(zbGatewayID) == 1) { var listAllRoom = UserCenter.HdlRoomLogic.Current.GetAllListRooms(); foreach (var room in listAllRoom) { //删除场景文件 foreach (var sceneId in room.ListSceneId) { if (Global.IsExistsByHomeId($"Scene_{sceneId}.json") == true) { Global.DeleteFilebyHomeId($"Scene_{sceneId}.json"); } } } } } #endregion #region ■ 网关掉线___________________________ /// /// 刷新网关的在线状态(注意,刷新的是缓存,请调用CheckGatewayOnlineByFlag来判断是否在线) /// /// /// public void RefreshGatewayOnlineStatu(List listGateway) { var listRealWay = new List(); for (int i = 0; i < listGateway.Count; i++) { ZbGateway zbTemp = null; if (this.GetRealGateway(ref zbTemp, listGateway[i]) == true) { //真实物理网关 listRealWay.Add(zbTemp); } else { //虚拟物理网关 listRealWay.Add(listGateway[i]); } //标识指定网关为不在线 listRealWay[i].GatewayOnlineFlage = false; } //这是第一道坎,强制检查WIFI:等待2秒(因为wifi的时候,它会自动去刷新flage) System.Threading.Thread.Sleep(2000); //检查是否拥有网关存在于WIFi下 if (this.CheckHadGatewayInWifi(listRealWay) == false) { //第二道坎:在远程的情况下刷新网关的在线状态 this.RefreshGatewayOnlineOnRemode(listRealWay); } //刷新缓存的在线标识 foreach (var zbway in listRealWay) { string gwID = zbway.GwId; if (this.dicGateway.ContainsKey(gwID) == false) { continue; } this.dicGateway[gwID].GatewayOnlineFlage = zbway.GatewayOnlineFlage; } } /// /// 检查是否拥有网关存在于WIFi下 /// /// /// private bool CheckHadGatewayInWifi(List listGateway) { foreach (var zbway in listGateway) { //是否存在网关存在于WIFI下 if (zbway.GatewayOnlineFlage == true) { return true; } } return false; } /// /// 在远程的情况下刷新网关的在线状态 /// /// /// private void RefreshGatewayOnlineOnRemode(List listGateway) { //获取云端上面的网关 Dictionary dicDbGateway = HdlGatewayLogic.Current.GetGateWayListFromDataBase(); if (dicDbGateway == null) { return; } foreach (var way in listGateway) { if (way == null) { continue; } string strId = way.GwId; if (dicDbGateway.ContainsKey(strId) == true) //如果云端上面有这个网关 { way.GatewayOnlineFlage = dicDbGateway[strId].MqttOnlineStatus; } } } /// /// 根据某种标识判断指定网关是否在线 /// /// /// public bool CheckGatewayOnlineByFlag(ZbGateway zbGateway) { if (zbGateway == null) { return false; } //使用缓存的,因为刷新在线状态的时候,刷新的就是缓存,而不是真实物理网关 string gwID = zbGateway.GwId; if (this.dicGateway.ContainsKey(gwID) == true) { return this.dicGateway[gwID].GatewayOnlineFlage; } return zbGateway.GatewayOnlineFlage; } #endregion #region ■ 获取网关___________________________ /// /// 从网关获取全部的网关(以本地网关为标准) /// /// public List GetAllGatewayFromGateway() { //不要去Foreach 它的列表 List list = new List(); list.AddRange(ZbGateway.GateWayList); List newlist = new List(); foreach (var way in list) { if (Config.Instance.HomeId != way.HomeId) { //如果不是当前住宅 continue; } string gwID = way.GwId; if (this.dicGateway.ContainsKey(gwID) == false) { //如果本地并没有这个网关 continue; } newlist.Add(way); } return newlist; } /// /// 获取本地全部的网关 /// /// The all gateway. public List GetAllLocalGateway() { List listData = new List(); lock (dicGateway) { foreach (var way in dicGateway.Values) { listData.Add(way); } } return listData; } /// /// 获取本地的网关 /// /// 网关ID /// public ZbGateway GetLocalGateway(string gatewayId) { if (this.dicGateway.ContainsKey(gatewayId) == true) { return this.dicGateway[gatewayId]; } return null; } /// /// 获取本地所有的网关文件 /// /// public List GetAllGatewayFile() { List list = new List(); List listFile = Global.FileListByHomeId(); foreach (string file in listFile) { //只获取网关设备 if (file.StartsWith(gwFirstName) == false) { continue; } list.Add(file); } return list; } /// /// 获取系统内部的真实网关对象变量 /// /// 真实网关 /// 目标网关 /// public bool GetRealGateway(ref ZbGateway zbGateway, ZbGateway tagartWay) { if (tagartWay == null) { return false; } return this.GetRealGateway(ref zbGateway, tagartWay.GwId); } /// /// 获取系统内部的真实网关对象变量 /// /// /// /// public bool GetRealGateway(ref ZbGateway zbGateway, string gwId) { var realWay = ZbGateway.GateWayList.Find((obj) => { return obj.GwId == gwId; }); if (realWay == null) { //如果网关对象丢失了,则创建个新的 realWay = new ZbGateway { IsVirtual = true, }; realWay.GwId = gwId; realWay.HomeId = Shared.Common.Config.Instance.HomeId; ZbGateway.GateWayList.Add(realWay); } zbGateway = realWay; return true; } #endregion #region ■ 获取协调器当前信道_________________ /// /// 获取协调器当前信道(会有等待延迟,返回-1代表错误) /// /// /// public int GetGatewayChannelId(ZbGateway zbGateway) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //错误:网关对象丢失 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg)); return -1; } int data = -1; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "ZbGw/GetChannel_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); data = Convert.ToInt32(jobject["Data"]["Channel"].ToString()); } }; realWay.Actions += action; var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 8 } }; realWay.Send("ZbGw/GetChannel", jObject.ToString()); int TimeOut = 0; while (data == -1 && TimeOut < 30) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (data == -1) { //获取协调器信道失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayChannelIdFail); msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowTipMsg(msg); } return data; } #endregion #region ■ 获取协调器MAC______________________ /// /// 获取协调器MAC地址(会有等待延迟,返回null代表错误) /// /// /// public string GetGatewayCoordinatorMac(ZbGateway zbGateway) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //错误:网关对象丢失 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg)); return null; } string data = null; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "ZbGw/GetMac_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); data = jobject["Data"]["MacAddr"].ToString(); } }; realWay.Actions += action; var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 13 } }; realWay.Send("ZbGw/GetMac", jObject.ToString()); int TimeOut = 0; while (data == null && TimeOut < 30) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (data == null) { //获取协调器Mac失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayCoordinatorMacFail); msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowTipMsg(msg); } return data; } #endregion #region ■ 获取协调器PanID____________________ /// /// 获取协调器PanID(会有等待延迟,返回-1代表错误) /// /// /// public int GetGatewayPanId(ZbGateway zbGateway) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //错误:网关对象丢失 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg)); return -1; } int panId = -1; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "ZbGw/GetPanId_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); panId = Convert.ToInt32(jobject["Data"]["PANID"].ToString()); } }; realWay.Actions += action; var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 64512 }, { "Command", 12 } }; realWay.Send("ZbGw/GetPanId", jObject.ToString()); int TimeOut = 0; while (panId == -1 && TimeOut < 30) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (panId == -1) { //获取协调器PanID失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayPanIDFail); msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowTipMsg(msg); } return panId; } #endregion #region ■ 网关自动备份设置___________________ /// /// 获取网关自动备份设置(-1:异常 0:关闭 1:打开) /// /// /// public int GetGatewayAutoBackupStatu(ZbGateway zbGateway) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //错误:网关对象丢失 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg)); return -1; } int statu = -1; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/GatewayAutoBackup_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); statu = Convert.ToInt32(jobject["Data"]["AutoBackupStatus"].ToString()); } }; realWay.Actions += action; var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 6205 } }; var data = new Newtonsoft.Json.Linq.JObject { { "AutoBackup", 1 } }; jObject.Add("Data", data); realWay.Send("GatewayAutoBackup", jObject.ToString()); int TimeOut = 0; while (statu == -1 && TimeOut < 60) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (statu == -1) { //获取网关自动备份设置失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayAutoBackupStatuFail); msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowTipMsg(msg); } return statu; } /// /// 设置网关自动备份设置 /// /// /// /// public bool SetGatewayAutoBackupStatu(ZbGateway zbGateway, bool statu) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { //错误:网关对象丢失 this.ShowTipMsg(Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg)); return false; } int result = -1; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/GatewayAutoBackup_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); result = Convert.ToInt32(jobject["Data"]["AutoBackupStatus"].ToString()); } }; realWay.Actions += action; var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 6205 } }; var data = new Newtonsoft.Json.Linq.JObject { { "AutoBackup", statu == true ? 2 : 3 } }; jObject.Add("Data", data); realWay.Send("GatewayAutoBackup", jObject.ToString()); int TimeOut = 0; while (result == -1 && TimeOut < 60) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (result == -1) { //设置网关自动备份失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetGatewayAutoBackupStatuFail); msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowTipMsg(msg); return false; } return true; } #endregion #region ■ 获取名称___________________________ /// /// 获取网关加特效的名称 /// /// /// /// public string GetGatewayName(ZbGateway zbGateway, GetNameMode mode = GetNameMode.SpecialGateway) { string gwId = zbGateway.GwId; if (this.dicGateway.ContainsKey(gwId) == false) { return zbGateway.GwName; } var localWay = this.dicGateway[gwId]; string name = this.GetGatewaySimpleName(localWay); if (string.IsNullOrEmpty(name) == false) { return name; } if (mode == GetNameMode.SpecialGateway) { string keyName = Common.LocalDevice.deviceModelIdName + localWay.LinuxImageType; if (LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true) { //没有名称时,则使用R文件里面设置的默认设备名称 return Language.StringByID(LocalDevice.Current.dicDeviceAllNameID[keyName] + 20000); } } return string.Empty; } /// /// 单纯获取网关名称 /// /// 网关对象 /// private string GetGatewaySimpleName(ZbGateway zbGateway) { if (zbGateway == null) { return string.Empty; } return zbGateway.GwName; } /// /// 设置网关镜像类型的翻译名字 /// /// /// /// public void SetGatewayImageText(Button button, ZbGateway zbGateway) { //初始值:无法识别的网关设备 button.TextID = R.MyInternationalizationString.uUnDistinguishTheGatewayDevice; string gwId = zbGateway.GwId; if (this.dicGateway.ContainsKey(gwId) == false) { //如果这个网关没有信息,则从新获取 if (zbGateway.LinuxImageType != -1) { string keyName = Common.LocalDevice.deviceModelIdName + zbGateway.LinuxImageType; if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true) { //使用R文件里面设置的东西 button.TextID = LocalDevice.Current.dicDeviceAllNameID[keyName]; } } else { //给一个线程去获取它的镜像类型 HdlThreadLogic.Current.RunThread(() => { var result = this.GetGatewayInfo(zbGateway, ShowErrorMode.NO); if (result != null) { //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(zbGateway, result, false); HdlThreadLogic.Current.RunMain(() => { string keyName = Common.LocalDevice.deviceModelIdName + zbGateway.LinuxImageType; if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true) { //使用R文件里面设置的东西 button.TextID = LocalDevice.Current.dicDeviceAllNameID[keyName]; } }); } }); } } else { string keyName = Common.LocalDevice.deviceModelIdName + this.dicGateway[gwId].LinuxImageType; if (Common.LocalDevice.Current.dicDeviceAllNameID.ContainsKey(keyName) == true) { //使用R文件里面设置的东西 button.TextID = Common.LocalDevice.Current.dicDeviceAllNameID[keyName]; } } } #endregion #region ■ 获取网关信息_______________________ /// /// 获取网关信息(版本信息,镜像类型,基本信息等。只刷新本地网关的缓存) /// /// /// /// public ZbGatewayData.GetGwData GetGatewayInfo(ZbGateway zbGateway, ShowErrorMode mode = ShowErrorMode.YES) { //获取网关版本信息 var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 95 } }; var result = this.SendJobjectDataToGateway(zbGateway, "GetZbGwInfo", jObject.ToString(), "GetZbGwInfo_Respon"); if (result.ErrorMsgDiv != 1) { if (mode == ShowErrorMode.YES) { //获取网关信息失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail); //拼接上【网关回复超时】的Msg msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); this.ShowErrorMsg(msg); } return null; } var getGwInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); string gwID = zbGateway.GwId; if (this.dicGateway.ContainsKey(gwID) == true) { //刷新缓存 ZbGateway localWay = this.dicGateway[gwID]; //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(localWay, getGwInfo); } //顺便这个变量也设置一下 this.SetGatewayDataToLocalMemmory(zbGateway, getGwInfo, false); return getGwInfo; } /// /// 将网关的数据设置到本地缓存中 /// /// 本地网关 /// 网关数据 /// 是否保存文件 private void SetGatewayDataToLocalMemmory(ZbGateway localWay, ZbGatewayData.GetGwData data, bool saveFile = true) { localWay.GwId = data.GwId; localWay.GwName = data.GwName; localWay.GwSerialNum = data.GWSN; localWay.IsMainGateWay = data.IsDominant == 1 ? true : false; localWay.GwIP = data.GwIP; localWay.LinuxImageType = data.LinuxImageType; localWay.LinuxHardVersion = data.LinuxHWVersion; localWay.LinuxFirmwareVersion = data.LinuxFWVersion; localWay.CoordinatorHardVersion = data.ZbHWVersion; localWay.CoordinatorFirmwareVersion = data.ZbFWVersion; localWay.CoordinatorImageId = data.ZbImageType; localWay.DriveCodeList = data.DriveCodeList; if (saveFile == true) { localWay.ReSave(); } } #endregion #region ■ 网关房间相关_______________________ /// /// 获取网关所在的房间 /// /// 网关对象 /// public Room GetRoomByGateway(ZbGateway zbGateway) { return this.GetRoomByGateway(zbGateway.GwId); } /// /// 获取网关所在的房间 /// /// 网关ID /// public Room GetRoomByGateway(string gatewayId) { var localGateway = this.GetLocalGateway(gatewayId); if (localGateway == null) { return null; } return HdlRoomLogic.Current.GetRoomById(localGateway.RoomId); } /// /// 变更网关房间 /// /// 网关对象 /// 房间ID public void ChangedGatewayRoom(ZbGateway zbGateway, string roomId) { var localGateway = this.GetLocalGateway(zbGateway.GwId); if (localGateway != null) { localGateway.RoomId = roomId; localGateway.ReSave(); //添加备份 HdlAutoBackupLogic.AddOrEditorFile(localGateway.FilePath); } } #endregion #region ■ 清空真实网关列表___________________ /// /// 清空全部的真实物理网关对象 /// public void ClearAllRealGateway() { //因为那一瞬间,有可能mqtt会加回来,所以先加缓存 var list = new List(); list.AddRange(ZbGateway.GateWayList); //然后清空掉 ZbGateway.GateWayList.Clear(); //最后再断开mqtt连接 for (int i = 0; i < list.Count; i++) { list[i].DisConnectLocalMqttClient("G"); } list.Clear(); } #endregion #region ■ 检测并获取网关各种固件新版本_______ /// /// 检测并获取网关各固件的新版本,没有新版本,则对应位置存的是null,直接返回null代表失败(0:Linux新版本 1:协调器新版本 2~X:都是虚拟驱动的) /// /// 网关对象 /// 错误时,是否显示错误 /// public List GetGatewayAllNewVersion(ZbGateway zbGateway, ShowErrorMode mode = ShowErrorMode.YES) { //获取网关版本信息 var result = this.GetGatewayInfo(zbGateway, mode); if (result == null) { return null; } //使用本地缓存对象 var localWay = this.GetLocalGateway(zbGateway.GwId); if (localWay == null) { return null; } //添加网关的升级固件(成不成功都无所谓) var flage = HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.Linux, localWay.LinuxHardVersion.ToString(), localWay.LinuxImageType.ToString()); //添加协调器的升级固件(成不成功都无所谓) 必须能够联网才行 if (flage == 1) { //没网的时候不再处理 HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.Coordinator, localWay.CoordinatorHardVersion.ToString(), localWay.CoordinatorImageId.ToString()); } //网关的版本 var gatewayFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.Linux, localWay.LinuxHardVersion.ToString(), localWay.LinuxImageType.ToString(), localWay.LinuxFirmwareVersion); //协调器版本 var coordinatorFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.Coordinator, localWay.CoordinatorHardVersion.ToString(), localWay.CoordinatorImageId.ToString(), localWay.CoordinatorFirmwareVersion); var list = new List(); list.Add(gatewayFirmware); list.Add(coordinatorFirmware); //这个网关需要有虚拟驱动这个东西才行 if (localWay.LinuxImageType != 6) { //虚拟驱动号 foreach (var data in localWay.DriveCodeList) { //添加虚拟驱动的升级固件(成不成功都无所谓) 必须能够联网才行 if (flage == 1) { HdlFirmwareUpdateLogic.AddFirmwareVersionInfo(FirmwareLevelType.VirtualDevice, data.DriveHwVersion.ToString(), data.DriveImageType.ToString()); } //虚拟驱动 var virtualFirmware = HdlFirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.VirtualDevice, data.DriveHwVersion.ToString(), data.DriveImageType.ToString(), data.DriveFwVersion); if (virtualFirmware != null) { virtualFirmware.VirtualCode = data.DriveCode; list.Add(virtualFirmware); } } } if (list.Count == 2) { //虚拟驱动如果没有新版本的话,固定添加一个空的 list.Add(null); } return list; } /// /// 获取网关的虚拟驱动号(返回null时代表获取失败) /// /// /// public List GetListVDDriveCode(ZbGateway zbGateway) { var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 505 } }; var result = this.SendJobjectDataToGateway(zbGateway, "VirtualDrive/CatDriveCode", jObject.ToString(), "VirtualDrive/CatDriveCode_Respon"); if (result.ErrorMsg != null) { this.ShowTipMsg(result.ErrorMsg); } if (result.ErrorMsgDiv == 0) { return null; } var dataInfo = JsonConvert.DeserializeObject(result.ReceiptData); return dataInfo.DriveCodeList; } #endregion #region ■ 主网关判定_________________________ /// /// 判断是否主网关(1:主网关 0:不在线 2:子网关) /// /// 网关对象 /// public int IsMainGateway(ZbGateway zbGateway) { return this.IsMainGateway(zbGateway.GwId); } /// /// 判断是否主网关(1:主网关 0:不在线 2:子网关) /// /// 网关id /// public int IsMainGateway(string waiID) { ZbGateway zbGateway = null; if (this.GetRealGateway(ref zbGateway, waiID) == false) { return 0; } return zbGateway.IsMainGateWay == true ? 1 : 2; } #endregion #region ■ 设置网关图片_______________________ /// /// 设置真实网关的图片 /// /// /// public void SetRealGatewayPictrue(Button button, ZbGateway zbGateway) { var localWay = this.GetLocalGateway(zbGateway.GwId); if (localWay == null) { if (zbGateway.LinuxImageType != -1) { button.UnSelectedImagePath = "Gateway/RealGateway" + zbGateway.LinuxImageType + ".png"; } else { //给一个线程去获取它的镜像类型 HdlThreadLogic.Current.RunThread(() => { var result = this.GetGatewayInfo(zbGateway, ShowErrorMode.NO); if (result != null) { //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(zbGateway, result, false); HdlThreadLogic.Current.RunMain(() => { button.UnSelectedImagePath = "Gateway/RealGateway" + result.LinuxImageType + ".png"; }); } }); } } else { button.UnSelectedImagePath = "Gateway/RealGateway" + localWay.LinuxImageType + ".png"; } } /// /// 设置网关图标 /// /// /// public void SetGatewayIcon(Button button, ZbGateway zbGateway) { var localWay = this.GetLocalGateway(zbGateway.GwId); if (localWay == null) { if (zbGateway.LinuxImageType != -1) { button.UnSelectedImagePath = "Gateway/GatewayIcon" + zbGateway.LinuxImageType + ".png"; } else { //给一个线程去获取它的镜像类型 HdlThreadLogic.Current.RunThread(() => { var result = this.GetGatewayInfo(zbGateway, ShowErrorMode.NO); if (result != null) { //将网关的数据设置到本地缓存中 this.SetGatewayDataToLocalMemmory(zbGateway, result, false); HdlThreadLogic.Current.RunMain(() => { button.UnSelectedImagePath = "Gateway/GatewayIcon" + result.LinuxImageType + ".png"; }); } }); } } else { button.UnSelectedImagePath = "Gateway/GatewayIcon" + localWay.LinuxImageType + ".png"; } } #endregion #region ■ 网关存在检测_______________________ /// /// 网关是否已经存在 /// /// /// public bool IsGatewayExist(ZbGateway zbGateway) { return this.IsGatewayExist(zbGateway.GwId); } /// /// 网关是否已经存在 /// /// 网关ID /// public bool IsGatewayExist(string gatewayId) { if (gatewayId == null) { return false; } return dicGateway.ContainsKey(gatewayId); } #endregion #region ■ 网关定位___________________________ /// /// 发送指令到网关进行定位(网关LED闪烁识别) /// /// public void SetFixedPositionCommand(ZbGateway zbGateway) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, zbGateway) == false) { return; } var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 85 } }; if (this.IsGatewayExist(zbGateway) == true) { realWay.Send("GwLinuxLocate_Respon", jObject.ToString()); } else { //如果这个网关还没有绑定的话,则强制使用本地连接 realWay.SendLocation("GwLinuxLocate_Respon", System.Text.Encoding.UTF8.GetBytes(jObject.ToString())); } } #endregion #region ■ 从云端获取全部网关列表ID___________ /// /// 从云端获取全部网关列表ID /// /// 从云端获取全部网关列表ID public Dictionary GetGateWayListFromDataBase() { Dictionary dicDbGateway = null; if (UserCenterResourse.UserInfo.AuthorityNo == 3) { //成员 return dicDbGateway; } bool canBreak = false; HdlThreadLogic.Current.RunThread(() => { List list = new List() { "NotCheck" }; //设置访问接口的参数 var pra = new GetGatewayPra(); pra.ReqDto.PageSetting.Page = 1; pra.ReqDto.PageSetting.PageSize = 999; //获取控制主人账号的Token pra.ReqDto.LoginAccessToken = UserCenterLogic.GetConnectMainToken(); var result = UserCenterLogic.GetResponseDataByRequestHttps("App/GetSingleHomeGatewayPagger", true, pra, list); if (string.IsNullOrEmpty(result) == true) { canBreak = true; return; } var infoResult = Newtonsoft.Json.JsonConvert.DeserializeObject(result); Dictionary dic = new Dictionary(); foreach (var data in infoResult.PageData) { dic[data.GatewayUniqueId] = data; } dicDbGateway = dic; canBreak = true; }); int count = 0; while (canBreak == false) { System.Threading.Thread.Sleep(200); count++; if (count == 25) { //如果5秒还不能获取得到数据,则中断此次操作 break; } } return dicDbGateway; } #endregion #region ■ 设置网关经纬度_____________________ /// /// 设置网关经纬度 /// /// 网关对象 /// 经度 /// 维度 /// 显示错误 /// public bool SetGatewaySite(ZbGateway gateway, double Longitude, double Latitude, ShowErrorMode mode) { ZbGateway realWay = null; if (this.GetRealGateway(ref realWay, gateway) == false) { if (mode == ShowErrorMode.YES) { //错误:网关对象丢失 string msg = Language.StringByID(R.MyInternationalizationString.uErrorGatewayLostMsg); this.ShowTipMsg(msg); } return false; } int result = -1; Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; if (topic == gatewayID + "/" + "Logic/SetSite_Respon") { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); result = Convert.ToInt32(jobject["Data"]["Result"].ToString()); } }; realWay.Actions += action; //两位小数 Longitude = Math.Round(Longitude, 2); Latitude = Math.Round(Latitude, 2); int intLongitude = Convert.ToInt32(Longitude.ToString().Replace(".", string.Empty)); int intLatitude = Convert.ToInt32(Latitude.ToString().Replace(".", string.Empty)); var jObject = new Newtonsoft.Json.Linq.JObject { { "Cluster_ID", 0 }, { "Command", 2013 } }; var data = new Newtonsoft.Json.Linq.JObject { { "Longitude", intLongitude }, { "Latitude", intLatitude } }; jObject.Add("Data", data); if (this.IsGatewayExist(gateway) == true) { realWay.Send("Logic/SetSite", jObject.ToString()); } else { //如果这个网关还没有绑定的话,则强制使用本地连接 realWay.SendLocation("Logic/SetSite", System.Text.Encoding.UTF8.GetBytes(jObject.ToString())); } int TimeOut = 0; while (result == -1 && TimeOut < 30) { System.Threading.Thread.Sleep(100); TimeOut++; } realWay.Actions -= action; if (result != 0) { if (mode == ShowErrorMode.YES) { //设置网关经纬度失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetGatewaySiteFail); if (result == -1) { msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, null, "回复超时"); } this.ShowTipMsg(msg); } return false; } return true; } #endregion #region ■ 解绑云端网关_______________________ /// /// 解绑云端绑定的网关 /// /// public bool DeleteDataBaseGateway(string strWayId) { var Pra = new DeleteGatewayPra(); Pra.BindGateways.Add(strWayId); //获取控制主人账号的Token Pra.LoginAccessToken = UserCenterLogic.GetConnectMainToken(); List listNotShowError = new List() { "NoExist", "NoBind", "NoRecord" }; bool result = UserCenterLogic.GetResultStatuByRequestHttps("App/ReleaseGatewayToHome", true, Pra, listNotShowError); if (result == false) { return false; } return true; } #endregion #region ■ 断网备份及绑定网关ID_______________ /// /// 在没网的情况下备份网关ID /// /// public void BackupGatewayIdOnNotNetwork(ZbGateway zbGateway) { var strId = zbGateway.GwId; if (listBackupGwId.Contains(strId) == false) { listBackupGwId.Add(strId); //备份 var strData = Newtonsoft.Json.JsonConvert.SerializeObject(listBackupGwId); var byteData = System.Text.Encoding.UTF8.GetBytes(strData); Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile, byteData); } } /// /// 重新发送命令去绑定断网情况下备份的网关 /// public void ResetComandToBindBackupGateway() { HdlThreadLogic.Current.RunThread(() => { var fileData = Global.ReadFileByDirectory(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile); if (fileData == null) { return; } this.listBackupGwId = Newtonsoft.Json.JsonConvert.DeserializeObject>(System.Text.Encoding.UTF8.GetString(fileData)); var listTempId = new List(); listTempId.AddRange(this.listBackupGwId); //调用接口,绑定网关 var bindGateway = new BindGatewayPra(); //获取控制主人账号的Token bindGateway.LoginAccessToken = UserCenterLogic.GetConnectMainToken(); foreach (var gwId in listTempId) { bindGateway.BindGateways.Clear(); bindGateway.BindGateways.Add(gwId); var result = UserCenterLogic.GetResultCodeByRequestHttps("App/BindGatewayToHome", true, bindGateway); if (result == "Success") { this.listBackupGwId.Remove(gwId); } if (result == "Error") { break; } } if (this.listBackupGwId.Count == 0) { //如果没有了内容,则删除文件 string file = UserCenterLogic.CombinePath(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile); if (System.IO.File.Exists(file) == true) { System.IO.File.Delete(file); } } else { //备份 var strData = Newtonsoft.Json.JsonConvert.SerializeObject(listBackupGwId); var byteData = System.Text.Encoding.UTF8.GetBytes(strData); Global.WriteFileToDirectoryByBytes(DirNameResourse.LocalMemoryDirectory, DirNameResourse.BackupGatewayIdFile, byteData); } }); } #endregion #region ■ 发送网关命令给网关_________________ /// /// 发送数据到网关,并接受网关返回的数据(ReceiptData为返回值) /// /// 网关对象 /// 发送的主题 /// 需要发送的数据 JObject.ToString()的东西 /// 指定接收哪个主题 /// 超时时间(秒) /// 网关返回的数据 public ReceiptGatewayResult SendJobjectDataToGateway(ZbGateway gateway, string sendTopic, string sendData, string receiptTopic, int waitTime = 5) { var reResult = new ReceiptGatewayResult(); ZbGateway myGateway = null; if (this.GetRealGateway(ref myGateway, gateway) == false) { //获取网关对象失败 reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail); reResult.ErrorMsgDiv = -1; return reResult; } //网关ID string gatewayID = gateway.GwId; //错误主题 string errorTopic = gatewayID + "/" + "Error_Respon"; //检测对象的主题 string checkTopic = gatewayID + "/" + receiptTopic; Action receiptAction = (topic, message) => { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); //网关回复错误 if (topic == errorTopic) { var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error); } //如果是指定的主题 if (topic == checkTopic) { reResult.ReceiptData = jobject["Data"].ToString(); } }; myGateway.Actions += receiptAction; //发送数据 myGateway.Send(sendTopic, sendData); //超时时间 int TimeOut = 0; waitTime = 20 * waitTime; while (reResult.ReceiptData == null && TimeOut < waitTime) { //全部接收才退出 System.Threading.Thread.Sleep(50); TimeOut++; } myGateway.Actions -= receiptAction; receiptAction = null; if (reResult.ReceiptData == null) { reResult.ErrorMsgDiv = 0; } return reResult; } #endregion #region ■ 网关监视___________________________ /// /// 当前的网络连接模式 /// private GatewayConnectMode nowGwConnectMode = GatewayConnectMode.None; /// /// 是否存在网关正在升级 /// private bool hadGatewayUpdate = false; /// /// 当网关的连接方式改变时,记录当前的连接方式 /// /// 网关变更后的连接方式 public void CheckGatewayByConnectChanged(GatewayConnectMode connectMode) { this.nowGwConnectMode = connectMode; } /// /// 开启检测网关在线状态的线程(此方法是给设备列表界面用的) /// /// 界面对象 public void StartCheckGatewayOnlineThread(EditorCommonForm frameLayout) { HdlThreadLogic.Current.RunThread(() => { int waitCount = 0; //如果住宅ID变更了,则不再处理 while (frameLayout.Parent != null && Config.Instance.HomeId != string.Empty) { System.Threading.Thread.Sleep(1000); if (this.hadGatewayUpdate == true) { //网关正在升级,不需要操作 continue; } waitCount++; if (this.nowGwConnectMode == GatewayConnectMode.Remote) { //远程每20秒检测一次 if (waitCount < 20) { continue; } } else if (this.nowGwConnectMode == GatewayConnectMode.WIFI) { //局域网每5秒检测一次 if (waitCount < 5) { continue; } } waitCount = 0; //获取前回网关的在线状态 Dictionary dicOldOnline = this.GetOldGatewayOnlineStatu(); if (dicOldOnline == null) { //则不处理 continue; } //可以叫4G if (this.nowGwConnectMode == GatewayConnectMode.Remote) { //在远程的条件下,检查网关的在线状态 this.CheckGatewayStatuByRemote(dicOldOnline); } //WIFI else if (this.nowGwConnectMode == GatewayConnectMode.WIFI) { //在WIFI的条件下,检查网关的在线状态 this.CheckGatewayStatuByWIFI(dicOldOnline); } } }, ShowErrorMode.NO); } /// /// 在WIFI的条件下,检查网关的在线状态 /// private void CheckGatewayStatuByWIFI(Dictionary dicOldOnline) { //从网关获取全部的网关 List list = this.GetAllGatewayFromGateway(); foreach (var way in list) { //将标识置为false way.GatewayOnlineFlage = false; } //等个2秒 System.Threading.Thread.Sleep(2000); //2020.05.25追加:此住宅是否拥有网关在线 var hadGwOnline = false; foreach (var way in list) { if (dicOldOnline.ContainsKey(way.GwId) == true) { if (way.GatewayOnlineFlage == true) { //有一个网关在线,即在线 hadGwOnline = true; break; } } } foreach (var way in list) { string gwId = way.GwId; if (dicOldOnline.ContainsKey(gwId) == true) { //网关也不多,直接推送吧 this.PushGatewayOnlineStatuToForm(gwId, way.GatewayOnlineFlage, hadGwOnline); } else { //没有包含,默认为false this.PushGatewayOnlineStatuToForm(gwId, false, hadGwOnline); } } } /// /// 在远程的条件下,检查网关的在线状态 /// private void CheckGatewayStatuByRemote(Dictionary dicOldOnline) { //获取云端上面的网关 Dictionary dicDbGateway = HdlGatewayLogic.Current.GetGateWayListFromDataBase(); if (dicDbGateway == null) { //如果网络不通,则也往下走 dicDbGateway = new Dictionary(); } //2020.05.25追加:此住宅是否拥有网关在线 var hadGwOnline = false; foreach (var gwId in dicOldOnline.Keys) { //如果云端上面有这个网关 if (dicDbGateway.ContainsKey(gwId) == true && dicDbGateway[gwId].MqttOnlineStatus == true) { //有一个网关在线,即在线 hadGwOnline = true; break; } } foreach (var gwId in dicOldOnline.Keys) { //如果云端上面有这个网关 if (dicDbGateway.ContainsKey(gwId) == true) { //网关也不多,直接推送 this.PushGatewayOnlineStatuToForm(gwId, dicDbGateway[gwId].MqttOnlineStatus, hadGwOnline); } else { //云端不包含的,当不在线处理 this.PushGatewayOnlineStatuToForm(gwId, false, hadGwOnline); } } } /// /// 获取前回网关的在线状态 /// /// private Dictionary GetOldGatewayOnlineStatu() { if (this.dicGateway.Count == 0) { //没有网关,则不处理 return null; } try { var dicOldOnline = new Dictionary(); //如果在循环的过程中,动了里面的东西,报错则不理它,下一回合 foreach (var zbway in this.dicGateway.Values) { //获取前回的在线状态 dicOldOnline[zbway.GwId] = zbway.GatewayOnlineFlage; } return dicOldOnline; } catch { return null; } } /// /// 将变化的网关推送到界面上 /// /// /// /// 2020.05.25追加:此住宅是否拥有网关在线 private void PushGatewayOnlineStatuToForm(string gwId, bool online, bool hadGwOnline) { try { for (int i = 0; i < UserCenterResourse.listActionFormId.Count; i++) { string formId = UserCenterResourse.listActionFormId[i]; if (UserCenterResourse.DicActionForm.ContainsKey(formId) == false) { continue; } //网关在线推送 var zbway = this.GetLocalGateway(gwId); if (zbway != null) { //切换住宅时,这个东西有可能是null zbway.GatewayOnlineFlage = online; UserCenterResourse.DicActionForm[formId]?.GatewayOnlinePush(zbway, online, hadGwOnline); } } } catch { } } /// /// 设置存在网关正在升级的标识 /// /// 是否有网关在升级 public void SetHadGatewayUpdateFlage(bool update) { this.hadGatewayUpdate = update; } #endregion #region ■ 一般方法___________________________ /// /// 显示错误信息窗口 /// /// private void ShowErrorMsg(string msg) { Application.RunOnMainThread(() => { var contr = new ShowMsgControl(ShowMsgType.Error, msg); contr.Show(); }); } /// /// 显示Tip信息窗口 /// /// private void ShowTipMsg(string msg) { Application.RunOnMainThread(() => { var contr = new ShowMsgControl(ShowMsgType.Tip, msg); contr.Show(); }); } #endregion } }