using Shared.Phone.UserCenter; using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; namespace Shared.Phone { /// /// 模板的共通逻辑类 /// public class HdlTemplateCommonLogic { #region ■ 变量声明___________________________ /// /// 模板的共通逻辑类 /// private static HdlTemplateCommonLogic m_Current = null; /// /// 模板的共通逻辑类 /// public static HdlTemplateCommonLogic Current { get { if (m_Current == null) { m_Current = new HdlTemplateCommonLogic(); } return m_Current; } } /// /// 模板数据 /// public TemplateMemoryData modelData = new TemplateMemoryData(); /// /// 模板文件中 #start# 到 #end# 的内容(临时变量) /// private string strTempContentData = string.Empty; /// /// 本地模板文件的名字 /// private const string TemplateFileName = "ModelData_Release.bin"; #endregion #region ■ 加载本地模板缓存___________________ /// /// 加载本地模板文件缓存(此方法以本地缓存为准,切换住宅时使用) /// public void LoadLocalTemplateMemoryData() { this.modelData = new TemplateMemoryData(); //保存的路径 string saveFile = HdlFileNameResourse.LocalTemplateDirectory; //如果当前住宅拥有选择的模板 if (Common.Config.Instance.Home.SelectTemplate != string.Empty) { string checkFile = System.IO.Path.Combine(saveFile, TemplateFileName); //如果本地没有这个bin文件 if (System.IO.File.Exists(checkFile) == false) { //复制模板bin文件到本地的模板文件夹里 this.CopyTemplateFileToLocalDirectory(Common.Config.Instance.Home.SelectTemplate); } } //获取这个路径下面全部的文件 var listFile = HdlFileLogic.Current.GetFileFromDirectory(saveFile); //模板Bin文件 string templateBinFile = string.Empty; //这里是读取他上一次编辑完成之后的模板数据(也就是编辑到一半之后,退出App,下一次再编辑) foreach (var fileName in listFile) { if (fileName == TemplateFileName) { //模板Bin文件 templateBinFile = fileName; continue; } if (fileName.StartsWith("Device_") == false) { //只要设备 continue; } string fileData = HdlFileLogic.Current.ReadFileTextContent(System.IO.Path.Combine(saveFile, fileName)); if (fileData == null) { continue; } string deviceData = string.Empty; ModelDeviceSaveEnum saveDiv = ModelDeviceSaveEnum.A未定义; //根据换行符切分数据文本 string[] arryData = fileData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string strData in arryData) { //设备数据标志 if (strData.StartsWith("===>") == true) { if (deviceData != string.Empty) { //反序列化设备的保存文件内容 var tempData = this.DeserializeDeviceDataByDiv(saveDiv, deviceData); //将设备模板数据添加入缓存 string mainKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(tempData.DeviceMac, tempData.DeviceEpoint); this.SetTemplateDeviceDataToMemmory(tempData, deviceData, mainKey, true); } //清空 deviceData = string.Empty; saveDiv = (ModelDeviceSaveEnum)Convert.ToInt32(strData.Substring(4)); continue; } deviceData += strData; } if (deviceData != string.Empty) { //反序列化设备的保存文件内容 var tempData = this.DeserializeDeviceDataByDiv(saveDiv, deviceData); //将设备模板数据添加入缓存 string mainKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(tempData.DeviceMac, tempData.DeviceEpoint); this.SetTemplateDeviceDataToMemmory(tempData, deviceData, mainKey, true); } } //读取模板Bin文件 if (templateBinFile != string.Empty) { bool hadRoom = HdlRoomLogic.Current.GetAllListRooms().Count > 1 && Common.Config.Instance.Home.FloorDics.Count == 0; //开始读取文件内容 this.ReadTemplateFileMethord((strData, saveDiv, deviceType) => { //在加载本地缓存的前提下,处理模板文件里面的特殊内容 var result = this.AdjustTemplateBinFileContentOnLoadMemory(strData, hadRoom); //false代表它不是特殊内容 if (result == false) { //处理模板文件里面的共通内容 //因为上面已经加载了指定本地的缓存,所以这里不需要添加入dicDeviceTemplateData中 this.AdjustTemplateBinFileCommonContent(strData, saveDiv, deviceType, false); } }); } //清空对象缓存 this.strTempContentData = string.Empty; //加载设备和网关模板选择的数据 this.modelData.dicDeviceTemplateSelect = new Dictionary(); this.modelData.dicGatewayTemplateSelect = new Dictionary(); string fileData2 = HdlFileLogic.Current.ReadFileTextContent(HdlFileNameResourse.DeviceTemplateSelectFile); if (fileData2 != null) { //设备选择的模板对象(keys:本地设备的Mac value:模板中的Mac) this.modelData.dicDeviceTemplateSelect = Newtonsoft.Json.JsonConvert.DeserializeObject>(fileData2); } fileData2 = HdlFileLogic.Current.ReadFileTextContent(HdlFileNameResourse.GatewayTemplateSelectFile); if (fileData2 != null) { //网关对象选择的模板对象(keys:本地网关ID, value:模板中的网关ID) this.modelData.dicGatewayTemplateSelect = Newtonsoft.Json.JsonConvert.DeserializeObject>(fileData2); } } /// /// 在加载本地缓存的前提下,处理模板文件里面的特殊内容 /// /// 模板文件中的行数据 /// 是否已经有了房间 private bool AdjustTemplateBinFileContentOnLoadMemory(string strData, bool hadRoom) { //场景对象 if (strData == "#SceneTemplate END#") { if (hadRoom == false) { //只初始化一次,有房间时代表已经不是第一次加载了 var scene = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); scene.Save(); } this.strTempContentData = string.Empty; return true; } //楼层对象 else if (strData == "#FloorInfo END#") { if (hadRoom == false) { //只初始化一次,有房间时代表已经不是第一次加载了 Common.Config.Instance.Home.FloorDics = Newtonsoft.Json.JsonConvert.DeserializeObject>(this.strTempContentData); Common.Config.Instance.Home.Save(false); } this.strTempContentData = string.Empty; return true; } //房间对象 else if (strData == "#RoomInfo END#") { var room = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); //各自端点所处的房间ID,保存起来 foreach (var deviceKey in room.ListDevice) { this.modelData.dicDeviceTemplateRoom[deviceKey] = room.Id; } foreach (var strMac in room.ListDeviceMac) { //物理设备所在的区域,在这个函数外面已经初始化了这个变量 this.modelData.dicDeviceTemplateRealRoom[strMac] = room.Id; } if (hadRoom == false) { //第一次加载,设备列表需要清空,选择设备模板时,才添加 room.ListDevice.Clear(); room.Save(); } this.strTempContentData = string.Empty; return true; } //设备选择的模板 else if (strData == "#DeviceSelectTemplate END#") { //这个东西在这个分支下不从文件中读取,从本地缓存文件当中获取 this.strTempContentData = string.Empty; return true; } //网关选择的模板 else if (strData == "#GatewaySelectTemplate END#") { //这个东西在这个分支下不从文件中读取,从本地缓存文件当中获取 this.strTempContentData = string.Empty; return true; } return false; } #endregion #region ■ 根据模板Bin文件恢复数据____________ /// /// 根据模板Bin文件,恢复数据(分两个函数吧,太难控制了) /// public void RecoverDataByTemplateBinFile() { //重新初始化 this.modelData = new TemplateMemoryData(); //开始读取文件内容 this.ReadTemplateFileMethord((strData, saveDiv, deviceType) => { //在恢复数据的前提下,处理模板文件里面的特殊内容 var result = this.AdjustTemplateBinFileContentOnRecover(strData); //false代表它不是特殊内容 if (result == false) { //处理模板文件里面的共通内容 //因为是以模板来恢复住宅数据,所以这里需要添加入dicDeviceTemplateData中 this.AdjustTemplateBinFileCommonContent(strData, saveDiv, deviceType, true); } }); //清空对象缓存 this.strTempContentData = string.Empty; //删掉这两个保存选择模板的文件(这两个东西可能还存在) HdlFileLogic.Current.DeleteFile(HdlFileNameResourse.DeviceTemplateSelectFile); HdlFileLogic.Current.DeleteFile(HdlFileNameResourse.GatewayTemplateSelectFile); //再次初始化房间 HdlRoomLogic.Current.InitAllRoom(); //无模板模式时,恢复备份的时候,把备份文件删除 if (Common.Config.Instance.Home.TemplateMode != 2) { //存放的路径 string fullFile = System.IO.Path.Combine(HdlFileNameResourse.LocalTemplateDirectory, TemplateFileName); HdlFileLogic.Current.DeleteFile(fullFile); } } /// /// 在恢复数据的前提下,处理模板文件里面的特殊内容 /// /// 模板文件中的行数据 private bool AdjustTemplateBinFileContentOnRecover(string strData) { //场景对象 if (strData == "#SceneTemplate END#") { var scene = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); scene.Save(); this.strTempContentData = string.Empty; return true; } //楼层对象 else if (strData == "#FloorInfo END#") { Common.Config.Instance.Home.FloorDics = Newtonsoft.Json.JsonConvert.DeserializeObject>(this.strTempContentData); Common.Config.Instance.Home.Save(false); this.strTempContentData = string.Empty; return true; } //房间对象 else if (strData == "#RoomInfo END#") { var room = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); room.Save(); //各自端点所处的房间ID,保存起来 foreach (var deviceKey in room.ListDevice) { this.modelData.dicDeviceTemplateRoom[deviceKey] = room.Id; } foreach (var strMac in room.ListDeviceMac) { //物理设备所在的区域,在这个函数外面已经初始化了这个变量 this.modelData.dicDeviceTemplateRealRoom[strMac] = room.Id; } this.strTempContentData = string.Empty; return true; } //设备选择的模板 else if (strData == "#DeviceSelectTemplate END#") { this.modelData.dicDeviceTemplateSelect = Newtonsoft.Json.JsonConvert.DeserializeObject>(this.strTempContentData); this.strTempContentData = string.Empty; return true; } //网关选择的模板 else if (strData == "#GatewaySelectTemplate END#") { this.modelData.dicGatewayTemplateSelect = Newtonsoft.Json.JsonConvert.DeserializeObject>(this.strTempContentData); this.strTempContentData = string.Empty; return true; } return false; } #endregion #region ■ 处理模板文件里面的共通内容_________ /// /// 处理模板文件里面的共通内容 /// /// 模板文件中的行数据 /// 模板设备保存的区分(设备数据时有效) /// 模板中设备的deviceType(设备数据时有效,反射用) /// 是否添加到设备模板缓存中 private void AdjustTemplateBinFileCommonContent(string strData, ModelDeviceSaveEnum saveDiv, string deviceType, bool addToTemplate) { //模板基本数据 if (strData == "#TemplateData END#") { var templateData = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); this.modelData.TemplateName = templateData.ModelName; this.strTempContentData = string.Empty; return; } //设备模板 else if (strData == "#DeviceTemplate END#") { //反序列化设备的保存文件内容 var tempData = this.DeserializeDeviceDataByDiv(saveDiv, this.strTempContentData); //将设备模板数据添加入缓存(此处特殊,不需要加入设备模板缓存中) string mainKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(tempData.DeviceMac, tempData.DeviceEpoint); this.SetTemplateDeviceDataToMemmory(tempData, this.strTempContentData, mainKey, addToTemplate); this.strTempContentData = string.Empty; return; } //设备对象 else if (strData == "#DeviceInfo END#") { //反序列化设备 CommonDevice device = null; if (HdlCheckLogic.Current.CheckIsNumber(deviceType) == true) { //数值型为新数据,直接转换 device = CommonDevice.CommonDeviceByByteString(Convert.ToInt32(deviceType), this.strTempContentData); } else { //字符串型为旧数据,需要特殊处理 var myType = (DeviceType)Enum.Parse(typeof(DeviceType), deviceType); device = CommonDevice.CommonDeviceByByteString((int)myType, this.strTempContentData); } if (device != null) { if (this.modelData.dicDeviceInfo.ContainsKey(device.DeviceAddr) == false) { this.modelData.dicDeviceInfo[device.DeviceAddr] = new List(); } this.modelData.dicDeviceInfo[device.DeviceAddr].Add(device); } this.strTempContentData = string.Empty; return; } //网关对象数据 else if (strData == "#GatewayInfo END#") { //反序列化设备 var gateway = Newtonsoft.Json.JsonConvert.DeserializeObject(this.strTempContentData); this.modelData.dicGatewayInfo[gateway.GwId] = gateway; this.strTempContentData = string.Empty; return; } //模板住宅的信息(目前在这里基本没用) else if (strData == "#TemplateHomeInfo END#") { this.strTempContentData = string.Empty; return; } this.strTempContentData += strData; } #endregion #region ■ 读取模板文件内容___________________ /// /// 读取模板文件内容 /// /// /// 参数1:模板文件中的行数据 /// 参数2:模板设备保存的区分(设备数据时有效) /// 参数3:板中设备的deviceType(设备数据时有效,反射用) /// private void ReadTemplateFileMethord(Action AdjustAction) { //保存的路径 string saveFile = HdlFileNameResourse.LocalTemplateDirectory; saveFile = System.IO.Path.Combine(saveFile, TemplateFileName); string fileData = HdlFileLogic.Current.ReadFileTextContent(saveFile); if (fileData == null) { AdjustAction = null; return; } var saveDiv = ModelDeviceSaveEnum.A未定义; var deviceType = string.Empty; //根据换行符切分数据文本 string[] arryData = fileData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string strData in arryData) { if (strData == "#START#") { //无附加数据的【数据标题】 continue; } if (strData.StartsWith("#DeviceTemplate START#") == true) { //附加数据:设备保存区分 saveDiv = (ModelDeviceSaveEnum)Convert.ToInt32(strData.Substring(22)); continue; } if (strData.StartsWith("#DeviceInfo START#") == true) { //附加数据:设备对象类型 deviceType = strData.Substring(18); continue; } try { //执行数据处理 AdjustAction(strData, saveDiv, deviceType); } catch (Exception ex) { HdlLogLogic.Current.WriteLog(ex, "模板bin文件出问题\r\n" + this.strTempContentData); this.strTempContentData = string.Empty; } } } #endregion #region ■ 反序列化设备的保存文件内容_________ /// /// 反序列化设备的保存文件内容 /// /// 保存区分 /// /// private TemplateDeviceDataCommon DeserializeDeviceDataByDiv(ModelDeviceSaveEnum saveDiv, string fileData) { TemplateDeviceDataCommon modelData = null; if (saveDiv == ModelDeviceSaveEnum.APir配置) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A空调摆风功能) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A空调自定义模式) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A窗帘手拉控制) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A窗帘方向及限位) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A端点名称) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A设备名称) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A设备绑定列表) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A面板亮度调节) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A面板节能模式) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A面板指示灯) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } else if (saveDiv == ModelDeviceSaveEnum.A面板震动功能) { modelData = Newtonsoft.Json.JsonConvert.DeserializeObject(fileData); } return modelData; } /// /// 将设备模板数据添加入缓存 /// /// 模板数据 /// 设备保存在文件中的内容(可为null) /// 添加的主键 /// 是否添加到设备模板缓存中 private void SetTemplateDeviceDataToMemmory(TemplateDeviceDataCommon modelData, string fileData, string mainKey, bool addToTemplate) { if (modelData == null) { return; } //从模板主文件中获取的设备模板信息,是不需要添加到这个变量中的 //因为它只能慢慢一个个匹配 if (addToTemplate == true) { if (this.modelData.dicDeviceTemplateData.ContainsKey(mainKey) == false) { this.modelData.dicDeviceTemplateData[mainKey] = new List(); } this.modelData.dicDeviceTemplateData[mainKey].Add(modelData); } if (fileData != null) { //临时缓存:模板中各自端点所保存的内容(keys:设备主键),设备选择模板时,模板数据迁移使用,因为是引用类型,所以需要重新New if (this.modelData.dicDeviceFileContent.ContainsKey(mainKey) == false) { this.modelData.dicDeviceFileContent[mainKey] = new List(); } var fileCentent = new TemplateDeviceContent(); fileCentent.saveDiv = modelData.DataSaveDiv; fileCentent.FileContent = fileData; fileCentent.DeviceMac = modelData.DeviceMac; this.modelData.dicDeviceFileContent[mainKey].Add(fileCentent); } } #endregion #region ■ 保存模板数据到本地相关_____________ /// /// 保存模板数据到本地 /// /// 备份名称 /// 是否下载固件 public void SaveTemplateDataToLocation(string backupName, bool downloadFirmware = true) { //获取本地全部的模板列表的基本信息 var localModel = this.GetLocalAllModelList(); var fileName = this.GetNewTemplateFileName(); foreach (var model in localModel) { //名字一样时 if (model.ModelName == backupName) { fileName = model.FileName; //备份数据已经存在,是否覆盖? this.ShowMassage(ShowMsgType.Confirm, Language.StringByID(R.MyInternationalizationString.BackUpDataIsEsixtAndPickUp), () => { //将模板数据保存到到指定的文件夹中 this.SaveTemplateDataToLocation2(fileName, backupName, downloadFirmware); }); return; } } //将模板数据保存到到指定的文件夹中 this.SaveTemplateDataToLocation2(fileName, backupName, downloadFirmware); } /// /// 保存模板数据到本地 /// /// 保存文件的名字 /// 模板备份的名字 /// 是否下载固件 private void SaveTemplateDataToLocation2(string fileName, string backupName, bool downloadFirmware = true) { HdlThreadLogic.Current.RunThread(() => { ProgressFormBar.Current.Start(); ProgressFormBar.Current.SetMsg("正在保存模板数据"); System.Threading.Thread.Sleep(1500); //将模板数据保存到到指定的文件夹中 var fileFullName = this.SaveTemplateDataToFile(fileName, backupName); if (downloadFirmware == false) { //本地备份保存成功 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.SaveLocalBackDataSuccess)); ProgressFormBar.Current.Close(); return; } //获取升级固件文件 var result = HdlFirmwareUpdateLogic.Current.DownLoadTemplateDeviceFirmware(fileFullName, "正在保存升级固件数据"); if (result == -1) { this.ShowMassage(ShowMsgType.Tip, "保存升级固件数据失败"); //删掉这个模板 HdlFileLogic.Current.DeleteFile(fileFullName); } else { //本地备份保存成功 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.SaveLocalBackDataSuccess)); } ProgressFormBar.Current.Close(); }); } /// /// 在生成模板数据之前,检测模板数据 /// private void CheckTempLateDataBeforCreat() { //为了保证模板里的设备数和本地的一致,所以检测一下 //如果缺少,则添加修改Mac的数据进去 //其他的,如果不点击各自的配置界面,则当做是默认设备原来的配置状态 //获取目前已经设置设备物理名称的设备Mac var listMac = new HashSet(); foreach (var listData in this.modelData.dicDeviceTemplateData.Values) { if (listData.Count > 0 && listMac.Contains(listData[0].DeviceMac) == true) { //已经加了 continue; } foreach (var data in listData) { if (data.DataSaveDiv == ModelDeviceSaveEnum.A设备名称) { listMac.Add(data.DeviceMac); } } } var listDevice = HdlDeviceCommonLogic.Current.listAllDevice; foreach (var device in listDevice) { if (listMac.Contains(device.DeviceAddr) == false) { listMac.Add(device.DeviceAddr); //重新添加Mac名字缓存 HdlTemplateDeviceDataLogic.Current.ReDeviceMacName(device, HdlDeviceCommonLogic.Current.GetDeviceMacName(device)); } //重新添加端点名字缓存 HdlTemplateDeviceDataLogic.Current.ReDeviceEpointName(device, HdlDeviceCommonLogic.Current.GetDeviceEpointName(device)); } } #endregion #region ■ 获取模板对象相关___________________ /// /// 获取本地全部的模板列表的基本信息 /// /// public List GetLocalAllModelList() { var dicData = new Dictionary>(); var listTime = new List(); var strPath = HdlFileNameResourse.AllResidenceTemplateDirectory; //获取全部文件 var arryFile = System.IO.Directory.GetFiles(strPath, "ModelData_*"); foreach (string modelFile in arryFile) { //读取文件内容 var textValue = HdlFileLogic.Current.ReadFileTextContent(modelFile); if (textValue == null) { continue; } //从文件中获取指定的内容 string modelBaseInfo = this.GetDataFromFileContent(textValue, "#START#", "#TemplateData END#"); if (modelBaseInfo != string.Empty) { var myModel = Newtonsoft.Json.JsonConvert.DeserializeObject(modelBaseInfo); myModel.FileName = modelFile.Substring(strPath.Length + 1); if (dicData.ContainsKey(myModel.EditorTime) == false) { dicData[myModel.EditorTime] = new List(); listTime.Add(myModel.EditorTime); } dicData[myModel.EditorTime].Add(myModel); string homeData = this.GetDataFromFileContent(textValue, "#START#", "#TemplateHomeInfo END#"); if (homeData != string.Empty) { var homeInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(homeData); myModel.ListUintContent.AddRange(homeInfo.ListUintContent); myModel.ListUintName.AddRange(homeInfo.ListUintName); myModel.ResidenceAddressName = homeInfo.ResidenceAddressName; } } } //按时间排序 listTime.Sort(); var listData = new List(); for (int i = listTime.Count - 1; i >= 0; i--) { listData.AddRange(dicData[listTime[i]]); } return listData; } /// /// 获取云端全部的模板列表的基本信息 /// /// 失败时是否显示tip消息 /// public List GetCloundAllModelList(ShowNetCodeMode mode= ShowNetCodeMode.YES) { var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/template/metaInfo/findAll", RestSharp.Method.POST, null); //检测状态码 if (HdlCheckLogic.Current.CheckNetCode(result, mode) == false) { return new List(); } var dicData = new Dictionary>(); var listTime = new List(); var listCloundData = Newtonsoft.Json.JsonConvert.DeserializeObject>(result.Data.ToString()); foreach (var data in listCloundData) { //变更时间格式 data.CreateTime = HdlCommonLogic.Current.ConvertUtcTimeToLocalTime2(data.CreateTime).ToString("yyyy.MM.dd HH:mm"); if (dicData.ContainsKey(data.CreateTime) == false) { dicData[data.CreateTime] = new List(); listTime.Add(data.CreateTime); } dicData[data.CreateTime].Add(data); } //按时间排序 listTime.Sort(); var listData = new List(); for (int i = listTime.Count - 1; i >= 0; i--) { listData.AddRange(dicData[listTime[i]]); } return listData; } /// /// 获取一个新的模板保存文件名 /// /// public string GetNewTemplateFileName() { return "ModelData_Local_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".bin"; } /// /// 获取一个新的模板保存文件名 /// /// public string GetNewTemplateFileName(DateTime dateTime) { return "ModelData_Local_" + dateTime.ToString("yyyyMMdd_HHmmss") + ".bin"; } #endregion #region ■ 上传模板备份_______________________ /// /// 上传模板备份(内部使用线程来执行,有转圈的界面) /// /// 本地模板信息 /// 备份名字 /// 失败时是否显示tip消息 public void UpLoadTemplateData(LocalModelBaseInfo i_localTemplate, string i_saveName, ShowNetCodeMode mode = ShowNetCodeMode.YES) { HdlThreadLogic.Current.RunThread(() => { ProgressBar.Show(); //获取云端的模板列表 var listTemplate = this.GetCloundAllModelList(); foreach (var data in listTemplate) { if (data.TemplateName == i_saveName) { //模板名字已经存在 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.TheTemplateNameIsEsixt)); ProgressBar.Close(); return; } } //创建新的模板备份 var templateId = this.CreatNewTemplateNameToDB(i_saveName, mode); if (templateId == null) { ProgressBar.Close(); return; } //这里修改掉模板文件里面记载的模板名称 string templateFile = System.IO.Path.Combine(HdlFileNameResourse.AllResidenceTemplateDirectory, i_localTemplate.FileName); string binFileData = HdlFileLogic.Current.ReadFileTextContent(templateFile); var arryBinFile = binFileData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); //替换目标 这里是模板基本信息的json数据 string strFileData = arryBinFile[1]; var templateBaseInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(strFileData); templateBaseInfo.ModelName = i_saveName;//更改掉名字 templateBaseInfo.EditorTime = DateTime.Now.ToString("yyyy.MM.dd HH:mm");//更改掉时间 //替换对象 string replaceDta = Newtonsoft.Json.JsonConvert.SerializeObject(templateBaseInfo); binFileData = binFileData.Replace(strFileData, replaceDta); var dicQuery = new Dictionary(); dicQuery["fileName"] = "ModelData_Cloud_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".bin"; dicQuery["templateId"] = templateId; var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/template/file/add", RestSharp.Method.POST, Encoding.UTF8.GetBytes(binFileData), dicQuery, null, CheckMode.A不检测, true, 10); //检测状态码 if (HdlCheckLogic.Current.CheckNetCode(result, mode) == true) { //上传模板成功 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.UploadTemplateSuccess)); } else { //上传模板失败 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.UploadTemplateFail)); } ProgressBar.Close(); }); } /// /// 在云端创建新的模板名称 /// /// 新名字 /// 失败时是否显示tip消息 /// private string CreatNewTemplateNameToDB(string i_saveName, ShowNetCodeMode mode = ShowNetCodeMode.YES) { var pra = new { templateName = i_saveName }; var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/template/metaInfo/add", RestSharp.Method.POST, pra); //检测状态码 if (HdlCheckLogic.Current.CheckNetCode(result, mode) == false) { return null; } var idData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.Data.ToString()); return idData.Id; } #endregion #region ■ 下载模板备份_______________________ /// /// 下载模板备份(内部是使用线程执行,有界面型进度条) /// /// 数据库主键 /// 下载完全成功之后的回调事件,参数为保存模板的全路径(参数null代表失败) /// 失败时是否显示tip消息 public void DownLoadTemplate(string i_templateId, Action i_SuccessAction = null,ShowNetCodeMode mode= ShowNetCodeMode.YES) { HdlThreadLogic.Current.RunThread(() => { ProgressFormBar.Current.Start(); ProgressFormBar.Current.SetMsg("正在下载模板数据"); System.Threading.Thread.Sleep(1500); var pra = new { templateId = i_templateId }; //获取指定模板的列表文件 var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/template/file/findAll", RestSharp.Method.POST, pra); //检测状态码 if (HdlCheckLogic.Current.CheckNetCode(result, mode) == false) { //下载模板失败 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.DownloadTemplateFail)); ProgressFormBar.Current.Close(); i_SuccessAction?.Invoke(null); return; } var listFileData = Newtonsoft.Json.JsonConvert.DeserializeObject>(result.Data.ToString()); if (listFileData.Count == 0) { //下载模板失败 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.DownloadTemplateFail)); ProgressFormBar.Current.Close(); i_SuccessAction?.Invoke(null); return; } //下载模板的内容 var pra2 = new { templateFileId = listFileData[0].Id, templateMetaInfoId = i_templateId }; var byteContent = HdlHttpLogic.Current.RequestByteFromZigbeeHttps("home-wisdom/app/template/file/downOne", RestSharp.Method.POST, pra2, null, null, CheckMode.A不检测, true, 10); if (byteContent == null || byteContent.Length == 0) { //下载模板失败 this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.DownloadTemplateFail)); ProgressFormBar.Current.Close(); i_SuccessAction?.Invoke(null); return; } //解析这个模板的名字 var strFileData = this.GetDataFromFileContent(Encoding.UTF8.GetString(byteContent), "#START#", "#TemplateData END#"); var templateBaseInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(strFileData); //检测本地的模板是否有同名的 var listLocal = this.GetLocalAllModelList(); string fileName = listFileData[0].FileName; foreach (var localData in listLocal) { if (localData.ModelName == templateBaseInfo.ModelName) { //替换,直接使用本地的模板文件名字 fileName = localData.FileName; break; } } //存成文件 string fileFullName = System.IO.Path.Combine(HdlFileNameResourse.AllResidenceTemplateDirectory, fileName); HdlFileLogic.Current.SaveByteToFile(fileFullName, byteContent); byteContent = null; //获取升级固件文件 var result2 = HdlFirmwareUpdateLogic.Current.DownLoadTemplateDeviceFirmware(fileFullName, "正在获取升级固件数据"); if (result2 == -1) { this.ShowMassage(ShowMsgType.Tip, "获取升级固件数据失败"); ProgressFormBar.Current.Close(); i_SuccessAction?.Invoke(null); return; } ProgressFormBar.Current.Close(); i_SuccessAction?.Invoke(fileFullName); }); } /// /// 下载模板 /// private class DownloadTemplateData { /// /// 模板文件名字 /// public string FileName = string.Empty; /// /// 主键 /// public string Id = string.Empty; } #endregion #region ■ 删除模板备份_______________________ /// /// 删除云端模板备份 /// /// 模板主键 /// 失败时是否显示tip消息 /// public bool DeleteTemplateFromDb(string i_templateId, ShowNetCodeMode mode = ShowNetCodeMode.YES) { var pra = new { templateId = i_templateId }; var result = HdlHttpLogic.Current.RequestResponseFromZigbeeHttps("home-wisdom/app/template/metaInfo/delete", RestSharp.Method.POST, pra); if (result != null && result.Code == HttpMessageEnum.A10605) { //模板对象不存在,当做成功 return true; } //检测状态码 if (HdlCheckLogic.Current.CheckNetCode(result, mode) == false) { return false; } return true; } /// /// 删除本地模板备份 /// /// 本地模板的基本信息 /// public void DeleteLocalTemplate(LocalModelBaseInfo i_baseInfo) { var fullFile = System.IO.Path.Combine(HdlFileNameResourse.AllResidenceTemplateDirectory, i_baseInfo.FileName); HdlFileLogic.Current.DeleteFile(fullFile); } #endregion #region ■ 生成模板数据相关___________________ /// /// 保存模板数据到文件(返回保存文件的全路径) /// /// 保存文件的名字(新建时用 GetNewTemplateFileName函数新建) /// 模板备份的名字 public string SaveTemplateDataToFile(string fileName, string backUpName) { //写入文件的内容 string writeText = string.Empty; //在生成模板数据之前,检测模板数据 this.CheckTempLateDataBeforCreat(); //生成写入文件的【模板基本数据】 this.CreatWriteTemplateBaseData(ref writeText, backUpName); //生成写入文件的【模板住宅信息数据】 this.CreatWriteTemplateHomeData(ref writeText); //生成写入文件的【设备模板数据】 this.CreatWriteDeviceTemplateData(ref writeText); //生成写入文件的【设备对象数据】 this.CreatWriteCommonDeviceData(ref writeText); //生成写入文件的【网关对象数据】 this.CreatWriteGatewayData(ref writeText); //生成写入文件的【场景模板数据】 this.CreatWriteSceneData(ref writeText); //生成写入文件的【房间模板数据】 this.CrearWriteRoomTemplateData(ref writeText); //生成写入文件的【设备和网关选择的模板的数据】 this.CrearWriteDeviceSelectTemplateData(ref writeText); //写入内容 string saveFile = HdlFileNameResourse.AllResidenceTemplateDirectory; saveFile = System.IO.Path.Combine(saveFile, fileName); HdlFileLogic.Current.SaveTextToFile(saveFile, writeText); return saveFile; } /// /// 生成写入文件的【模板基本数据】 /// /// public void CreatWriteTemplateBaseData(ref string writeText, string backUpName) { var modelData = new LocalModelBaseInfo(); modelData.EditorTime = DateTime.Now.ToString("yyyy.MM.dd HH:mm"); modelData.ModelName = backUpName; modelData.FloorCount = Common.Config.Instance.Home.FloorDics.Count; modelData.DeviceCount = this.modelData.dicDeviceTemplateData.Count; //功能数 int funcCount = 0; foreach (var listData in this.modelData.dicDeviceTemplateData.Values) { if (listData.Count > 0) { var listDevice = HdlDeviceCommonLogic.Current.GetDevicesByMac(listData[0].DeviceMac, false); funcCount += listDevice.Count; } } modelData.FunctionCount = funcCount; writeText += "#START#\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(modelData); writeText += dataInfo + "\r\n"; writeText += "#TemplateData END#\r\n\r\n"; } /// /// 生成写入文件的【模板住宅信息数据】 /// /// public void CreatWriteTemplateHomeData(ref string writeText) { var homeData = new TemplateHomeInfo(); homeData.ResidenceAddressName = Common.Config.Instance.Home.ResidenceAddressName; homeData.ListUintName.AddRange(Common.Config.Instance.Home.ListUintName); homeData.ListUintContent.AddRange(Common.Config.Instance.Home.ListUintContent); writeText += "#START#\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(homeData); writeText += dataInfo + "\r\n"; writeText += "#TemplateHomeInfo END#\r\n\r\n"; } /// /// 生成写入文件的【设备模板数据】 /// /// public void CreatWriteDeviceTemplateData(ref string writeText) { foreach (var list in this.modelData.dicDeviceTemplateData.Values) { foreach (var data in list) { writeText += "#DeviceTemplate START#" + (int)data.DataSaveDiv + "\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(data); writeText += dataInfo + "\r\n"; writeText += "#DeviceTemplate END#\r\n\r\n"; } } } /// /// 生成写入文件的【设备对象数据】 /// /// public void CreatWriteCommonDeviceData(ref string writeText) { var listDevice = HdlDeviceCommonLogic.Current.listAllDevice; var listCheck = new HashSet(); foreach (var device in listDevice) { //设备端点 writeText += "#DeviceInfo START#" + (int)device.Type + "\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(device); writeText += dataInfo + "\r\n"; writeText += "#DeviceInfo END#\r\n\r\n"; //添加Ota设备对象的缓存 if (listCheck.Contains(device.DeviceAddr) == false) { listCheck.Add(device.DeviceAddr); var otaDevice = HdlDeviceCommonLogic.Current.GetOTADevice(device.DeviceAddr); if (otaDevice != null) { writeText += "#DeviceInfo START#" + (int)otaDevice.Type + "\r\n"; string dataInfo2 = Newtonsoft.Json.JsonConvert.SerializeObject(otaDevice); writeText += dataInfo2 + "\r\n"; writeText += "#DeviceInfo END#\r\n\r\n"; } } } } /// /// 生成写入文件的【网关对象数据】 /// /// public void CreatWriteGatewayData(ref string writeText) { var listGateway = HdlGatewayLogic.Current.GetAllLocalGateway(); foreach (var gateway in listGateway) { //设备端点 writeText += "#START#\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(gateway); writeText += dataInfo + "\r\n"; writeText += "#GatewayInfo END#\r\n\r\n"; } } /// /// 生成写入文件的【场景数据】 /// /// public void CreatWriteSceneData(ref string writeText) { //全部的场景 var listScene = HdlSceneLogic.Current.GetAllLocalScene(); foreach (var scene in listScene) { writeText += "#START#\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(scene); writeText += dataInfo + "\r\n"; writeText += "#SceneTemplate END#\r\n\r\n"; } } /// /// 生成写入文件的【房间模板数据】 /// /// public void CrearWriteRoomTemplateData(ref string writeText) { //楼层数据 writeText += "#START#\r\n"; string dataInfo1 = Newtonsoft.Json.JsonConvert.SerializeObject(Common.Config.Instance.Home.FloorDics); writeText += dataInfo1 + "\r\n"; writeText += "#FloorInfo END#\r\n\r\n"; //房间数据 var listRoom = HdlRoomLogic.Current.GetAllListRooms(); foreach (var room in listRoom) { writeText += "#START#\r\n"; string dataInfo2 = Newtonsoft.Json.JsonConvert.SerializeObject(room); writeText += dataInfo2 + "\r\n"; writeText += "#RoomInfo END#\r\n\r\n"; } } /// /// 生成写入文件的【设备和网关选择的模板的数据】 /// /// public void CrearWriteDeviceSelectTemplateData(ref string writeText) { //设备选择模板的数据 writeText += "#START#\r\n"; string dataInfo1 = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicDeviceTemplateSelect); writeText += dataInfo1 + "\r\n"; writeText += "#DeviceSelectTemplate END#\r\n\r\n"; //网关选择模板的数据 writeText += "#START#\r\n"; string dataInfo2 = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicGatewayTemplateSelect); writeText += dataInfo2 + "\r\n"; writeText += "#GatewaySelectTemplate END#\r\n\r\n"; } #endregion #region ■ 强制执行的特殊函数_________________ /// /// 强制从缓存当中生成设备和网关文件 /// public void CreatDeviceAndGatewayFileFromMemoryByForce() { //原来的状态 bool oldShowTemplate = Common.Config.Instance.Home.IsShowTemplate; //让它可以生成文件 Common.Config.Instance.Home.IsShowTemplate = false; //生成设备文件 foreach (var listDevice in this.modelData.dicDeviceInfo.Values) { foreach (var device in listDevice) { device.ReSave(); } } //生成网关文件 foreach (var gateway in this.modelData.dicGatewayInfo.Values) { gateway.ReSave(); } //还原状态 Common.Config.Instance.Home.IsShowTemplate = oldShowTemplate; } #endregion #region ■ 设备和网关模板选择相关_____________ /// /// 添加/修改 设备模板选择目标 /// /// 设备Mac对象 /// 目标Mac对象 public void AddDeviceTemplateSelect(string sourceMac, string targetMac) { //获取本地指定的Mac的全部设备 var listDevice = HdlDeviceCommonLogic.Current.GetDevicesByMac(sourceMac, false); var otaDevice = HdlDeviceCommonLogic.Current.GetOTADevice(sourceMac); if (otaDevice != null) { //这里ota设备也要加进去,重中之重 listDevice.Add(otaDevice); } foreach (var device in listDevice) { //模板选择的时候,他们的端点是一致的 string localDeviceKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(device); string templateDeviceKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(targetMac, device.DeviceEpoint); if (this.modelData.dicDeviceTemplateRoom.ContainsKey(templateDeviceKey) == true && (device is OTADevice) == false) { //如果模板里面,这个端点设置有房间的话 HdlRoomLogic.Current.ChangedRoom(device, this.modelData.dicDeviceTemplateRoom[templateDeviceKey], false); } //如果这个端点有模板数据的话 if (this.modelData.dicDeviceFileContent.ContainsKey(templateDeviceKey) == true) { //如果原来它选择有模板数据的话 if (this.modelData.dicDeviceTemplateData.ContainsKey(localDeviceKey) == true) { //删除这个设备的模板保存文件 HdlFileLogic.Current.DeleteFile(System.IO.Path.Combine(HdlFileNameResourse.LocalTemplateDirectory, device.FilePath)); //移除当前端点保存的模板数据 this.modelData.dicDeviceTemplateData.Remove(localDeviceKey); } //反序列化设备数据 foreach (var strCentent in this.modelData.dicDeviceFileContent[templateDeviceKey]) { var tempData = this.DeserializeDeviceDataByDiv(strCentent.saveDiv, strCentent.FileContent); //这里需要替换掉Mac tempData.DeviceMac = sourceMac; //添加缓存(主键为本地设备的主键) this.SetTemplateDeviceDataToMemmory(tempData, null, localDeviceKey, true); //修改端点缓存名字 if (tempData.DataSaveDiv == ModelDeviceSaveEnum.A端点名称) { HdlDeviceCommonLogic.Current.SetEpointName(device, ((ModelDeviceEpointNameInfo)tempData).deviceEpointName); } else if (tempData.DataSaveDiv == ModelDeviceSaveEnum.A设备名称) { HdlDeviceCommonLogic.Current.SetMacName(device, ((ModelDeviceMacNameInfo)tempData).deviceMacName); } } } //不管如何,都需要则重新保存成文件 this.SaveDeviceMemmoryData(device.DeviceAddr, device.DeviceEpoint); //还原及变更场景的执行目标 //this.RecoverAndChangedSceneAdjustTarget(device, targetMac); } //更改物理设备所在的房间 if (this.modelData.dicDeviceTemplateRealRoom.ContainsKey(targetMac) == true) { HdlRoomLogic.Current.SaveRealDeviceRoomId(listDevice, this.modelData.dicDeviceTemplateRealRoom[targetMac], false); } //记录缓存 this.modelData.dicDeviceTemplateSelect[sourceMac] = targetMac; //保存的路径 string fileData = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicDeviceTemplateSelect); HdlFileLogic.Current.SaveTextToFile(HdlFileNameResourse.DeviceTemplateSelectFile, fileData); } /// /// 还原及变更场景的执行目标 /// /// 本地设备对象 /// 需要变更的模板设备的Mac private void RecoverAndChangedSceneAdjustTarget(CommonDevice device, string targetMac) { //如果这个设备是替换选择的模板的话 if (this.modelData.dicDeviceTemplateSelect.ContainsKey(device.DeviceAddr) == false) { return; } //全部的场景 var listScene = HdlSceneLogic.Current.GetAllLocalScene(); //还没有执行变更前,它目前选择的模板的Mac string oldTemplateMac = this.modelData.dicDeviceTemplateSelect[device.DeviceAddr]; //将场景对象中,这个回路的主键,替换回原来模板中的Mac+端口 foreach (var scene in listScene) { bool save = false; for (int i = 0; i < scene.AdjustTargetList.Count; i++) { if (scene.AdjustTargetList[i].Type != 0) { //只处理设备绑定目标 continue; } //如果是当前回路 if (scene.AdjustTargetList[i].DeviceAddr == device.DeviceAddr && scene.AdjustTargetList[i].Epoint == device.DeviceEpoint) { //替换掉Mac scene.AdjustTargetList[i].DeviceAddr = oldTemplateMac; save = true; continue; } //如果是模板目标回路 if (targetMac != null && scene.AdjustTargetList[i].DeviceAddr == targetMac && scene.AdjustTargetList[i].Epoint == device.DeviceEpoint) { //将目标的Mac变更为当前设备的Mac scene.AdjustTargetList[i].DeviceAddr = device.DeviceAddr; save = true; continue; } } if (save == true) { //保存缓存 scene.Save(); } } } /// /// 获取设备已经选择了的模板目标的设备的Mac(没有目标时,返回null) /// /// 设备的Mac /// public string GetDeviceTemplateSelectMac(string sourceMac) { if (this.modelData.dicDeviceTemplateSelect.ContainsKey(sourceMac) == true) { return this.modelData.dicDeviceTemplateSelect[sourceMac]; } return null; } /// /// 获取设备已经选择了的模板目标的设备的Mac名字(没有目标时,返回null) /// /// 设备的Mac /// public string GetDeviceTemplateSelectName(string sourceMac) { if (this.modelData.dicDeviceTemplateSelect.ContainsKey(sourceMac) == true) { string tempMac = this.modelData.dicDeviceTemplateSelect[sourceMac]; foreach (var listData in this.modelData.dicDeviceFileContent.Values) { foreach (var data in listData) { if (data.DeviceMac != tempMac || data.saveDiv != ModelDeviceSaveEnum.A设备名称) { continue; } var tempModel = Newtonsoft.Json.JsonConvert.DeserializeObject(data.FileContent); return tempModel.deviceMacName; } } } return null; } /// /// 取消设备模板的选择目标 /// /// 设备的Mac public void RemoveDeviceTemplateSelect(string sourceMac) { ////获取本地指定的Mac的全部设备 //var listDevice = HdlDeviceCommonLogic.Current.GetDevicesByMac(sourceMac, false); //foreach (var device in listDevice) //{ // //还原场景的执行目标 // this.RecoverAndChangedSceneAdjustTarget(device, null); //} //记录缓存 this.modelData.dicDeviceTemplateSelect.Remove(sourceMac); //保存的路径 string fileData = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicDeviceTemplateSelect); HdlFileLogic.Current.SaveTextToFile(HdlFileNameResourse.DeviceTemplateSelectFile, fileData); } /// /// 添加/修改 网关模板选择目标 /// /// 网关id /// 目标网关id(模板) public void AddGatewayTemplateSelect(string sourceGwid, string targetGwid) { //记录缓存 this.modelData.dicGatewayTemplateSelect[sourceGwid] = targetGwid; //保存的路径 string fileData = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicGatewayTemplateSelect); HdlFileLogic.Current.SaveTextToFile(HdlFileNameResourse.GatewayTemplateSelectFile, fileData); //变更网关房间 if (this.modelData.dicDeviceTemplateRealRoom.ContainsKey(targetGwid) == true) { HdlRoomLogic.Current.ChangedGatewayRoom(sourceGwid, this.modelData.dicDeviceTemplateRealRoom[targetGwid]); } //变更网关名字 //if (this.modelData.dicGatewayInfo.ContainsKey(targetGwid) == true) //{ // var localGateway = HdlGatewayLogic.Current.GetLocalGateway(sourceGwid); // string gwName = HdlGatewayLogic.Current.GetGatewayName(this.modelData.dicGatewayInfo[targetGwid]); // HdlGatewayLogic.Current.ReName(localGateway, gwName); //} } /// /// 取消网关模板选择目标 /// /// 网关id /// 目标网关id public void RemoveGatewayTemplateSelect(string sourceGwid) { //记录缓存 this.modelData.dicGatewayTemplateSelect.Remove(sourceGwid); //保存的路径 string fileData = Newtonsoft.Json.JsonConvert.SerializeObject(this.modelData.dicGatewayTemplateSelect); HdlFileLogic.Current.SaveTextToFile(HdlFileNameResourse.GatewayTemplateSelectFile, fileData); } /// /// 获取网关已经选择了的模板目标的网关的名字(没有目标时,返回null) /// /// 网关id /// public string GetGatewayTemplateSelectName(string sourceGwid) { if (this.modelData.dicGatewayTemplateSelect.ContainsKey(sourceGwid) == true) { string tempMac = this.modelData.dicGatewayTemplateSelect[sourceGwid]; if (this.modelData.dicGatewayInfo.ContainsKey(tempMac) == true) { string gwName = HdlGatewayLogic.Current.GetGatewayName(this.modelData.dicGatewayInfo[tempMac]); return gwName; } } return null; } /// /// 获取网关已经选择了的模板目标的网关的名字(没有目标时,返回null) /// /// 网关id /// public string GetGatewayTemplateSelectId(string sourceGwid) { if (this.modelData.dicGatewayTemplateSelect.ContainsKey(sourceGwid) == true) { return this.modelData.dicGatewayTemplateSelect[sourceGwid]; } return null; } /// /// 获取模板中全部网关的名字 /// /// public Dictionary GetAllGatewayTemplateName() { var dic = new Dictionary(); foreach (string gwId in this.modelData.dicGatewayInfo.Keys) { string gwName = HdlGatewayLogic.Current.GetGatewayName(this.modelData.dicGatewayInfo[gwId]); dic[gwId] = gwName; } return dic; } /// /// 获取指定网关能够选择的模板名字 /// /// public Dictionary GetGatewayCanSelectTemplateName(ZbGateway zbGateway) { var dic = new Dictionary(); foreach (var zbway in this.modelData.dicGatewayInfo.Values) { if (zbGateway.LinuxImageType == zbway.LinuxImageType) { string gwName = HdlGatewayLogic.Current.GetGatewayName(zbway); dic[zbway.GwId] = gwName; } } return dic; } /// /// 清除全部已经已经选择好了模板对象的设备和网关 /// public void ClearAllSelectDeviceAndGateway() { //重新初始化 this.modelData.dicDeviceTemplateSelect = new Dictionary(); this.modelData.dicGatewayTemplateSelect = new Dictionary(); //删掉这两个保存选择模板的文件 HdlFileLogic.Current.DeleteFile(HdlFileNameResourse.DeviceTemplateSelectFile); HdlFileLogic.Current.DeleteFile(HdlFileNameResourse.GatewayTemplateSelectFile); } #endregion #region ■ 获取能够选择的模板_________________ /// /// 获取能够选择的模板 /// /// 本地设备 /// public List GetCanSelectDeviceTemplate(CommonDevice localDevice) { var listCanSelect = new List(); if (this.modelData.dicGatewayTemplateSelect.ContainsKey(localDevice.CurrentGateWayId) == false) { //该网关没有匹配模板,不提供模板选择 return listCanSelect; } var listHadSelect = new HashSet(); foreach (var localMac in this.modelData.dicDeviceTemplateSelect.Keys) { //它自己的话,可以显示(因为有个取消绑定的功能) if (localMac != localDevice.DeviceAddr) { //目前已经被选择了的模板Mac listHadSelect.Add(this.modelData.dicDeviceTemplateSelect[localMac]); } } var listCheck = new HashSet(); //设备的模块ID string modelId = this.GetDeviceModelId(localDevice.DeviceAddr); //模板中的网关ID string gatewayTemplateId = this.modelData.dicGatewayTemplateSelect[localDevice.CurrentGateWayId]; foreach (var mainKey in this.modelData.dicDeviceFileContent.Keys) { var listData = this.modelData.dicDeviceFileContent[mainKey]; foreach (var data in listData) { if (data.saveDiv != ModelDeviceSaveEnum.A设备名称) { //只获取设备mac名称的模板数据 continue; } if (listHadSelect.Contains(data.DeviceMac) == true || listCheck.Contains(data.DeviceMac) == true) { //如果这个模板已经被其他设备选择了,或者这个Mac已经处理了,则break break; } if (this.modelData.dicDeviceInfo.ContainsKey(data.DeviceMac) == false || this.modelData.dicDeviceInfo[data.DeviceMac][0].CurrentGateWayId != gatewayTemplateId || this.modelData.dicDeviceInfo[data.DeviceMac][0].ModelIdentifier != modelId) { //该模板不是这个网关的,或者模块ID不一样的 break; } if (localDevice.DriveCode != 0) { //如果是虚拟设备,则如果不是同一个端点,则不能作为模板对象 string checkKey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(data.DeviceMac, localDevice.DeviceEpoint); if (checkKey != mainKey) { break; } } listCheck.Add(data.DeviceMac); var info = Newtonsoft.Json.JsonConvert.DeserializeObject(data.FileContent); var selectData = new TemplateCanSelectContent(); selectData.DeviceMac = data.DeviceMac; selectData.DeviceName = info.deviceMacName; Common.Room room = null; if (this.modelData.dicDeviceTemplateRealRoom.ContainsKey(data.DeviceMac) == true) { room = HdlRoomLogic.Current.GetRoomById(this.modelData.dicDeviceTemplateRealRoom[data.DeviceMac]); } selectData.RoomName = HdlRoomLogic.Current.GetRoomName(room); listCanSelect.Add(selectData); } } return listCanSelect; } #endregion #region ■ 删除设备___________________________ /// /// 删除设备 /// /// public void DeleteDevice(CommonDevice device) { //删除保存文件 string saveFile = HdlFileNameResourse.LocalTemplateDirectory; saveFile = System.IO.Path.Combine(saveFile, device.FilePath); HdlFileLogic.Current.DeleteFile(saveFile); //移除模板缓存 this.modelData.dicDeviceTemplateData.Remove(HdlDeviceCommonLogic.Current.GetDeviceMainKeys(device)); //移除设备选择缓存 if (this.modelData.dicDeviceTemplateSelect.ContainsKey(device.DeviceAddr) == true) { this.modelData.dicDeviceTemplateSelect.Remove(device.DeviceAddr); HdlFileLogic.Current.SaveFileContent(HdlFileNameResourse.DeviceTemplateSelectFile, this.modelData.dicDeviceTemplateSelect); } } #endregion #region ■ 保存设备缓存_______________________ /// /// 保存设备缓存(考虑有的设备用的是200端点,所以这里最好不用设备对象作为参数) /// /// 设备mac /// 设备Epoint public void SaveDeviceMemmoryData(string deviceMac, int deviceEpoint) { string mainkey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(deviceMac, deviceEpoint); if (this.modelData.dicDeviceTemplateData.ContainsKey(mainkey) == false) { return; } //保存路径 string saveFile = HdlFileNameResourse.LocalTemplateDirectory; saveFile = System.IO.Path.Combine(saveFile, "Device_" + mainkey); var listData = this.modelData.dicDeviceTemplateData[mainkey]; if (listData.Count == 0) { //删除掉这个文件 HdlFileLogic.Current.DeleteFile(saveFile); return; } //写入文件的内容 string writeText = string.Empty; foreach (var data in listData) { writeText += "===>" + (int)data.DataSaveDiv + "\r\n"; string dataInfo = Newtonsoft.Json.JsonConvert.SerializeObject(data); writeText += dataInfo + "\r\n"; } //写入内容 HdlFileLogic.Current.SaveTextToFile(saveFile, writeText); } #endregion #region ■ 获取需要升级的设备对象_____________ /// /// 获取需要升级的设备对象,按网关分组(key:网关ID value的key:本地Ota设备的Mac value:升级固件地址) /// /// public Dictionary> GetNeedToUpdateDevice() { var dicGatewayDevice = new Dictionary>(); //循环设备匹配的模板 foreach (var localMac in this.modelData.dicDeviceTemplateSelect.Keys) { string tempMac = this.modelData.dicDeviceTemplateSelect[localMac]; if (this.modelData.dicDeviceInfo.ContainsKey(tempMac) == false) { //应该不会进来,即使进来,我也不知道为什么 continue; } //取本地Ota设备对象 var localOta = HdlDeviceCommonLogic.Current.GetOTADevice(localMac); if (localOta == null) { //应该不会进来,即使进来,我也不知道为什么 continue; } foreach (var tempDevice in this.modelData.dicDeviceInfo[tempMac]) { //取模板Ota设备对象 if (tempDevice is OTADevice) { //只要两者的固件版本不一样,并且本地有这个升级固件,则都需要升级 if (localOta.ImgVersion != tempDevice.ImgVersion && HdlFirmwareUpdateLogic.Current.IsEsixtDeviceFirmwareFile((OTADevice)tempDevice) == true) { //按网关分组 if (dicGatewayDevice.ContainsKey(localOta.CurrentGateWayId) == false) { dicGatewayDevice[localOta.CurrentGateWayId] = new Dictionary(); } var dicDevice = dicGatewayDevice[localOta.CurrentGateWayId]; dicDevice[localMac] = HdlFirmwareUpdateLogic.Current.GetDeviceFirmwareFile((OTADevice)tempDevice); } break; } } } return dicGatewayDevice; } /// /// 获取需要升级的网关对象(key:本地网关的id value:升级固件地址,第一位是Linux,第二位是协调器,之后都是虚拟驱动) /// /// public Dictionary> GetNeedToUpdateGateway() { var dicGateway = new Dictionary>(); //循环网关匹配的模板 foreach (var localId in this.modelData.dicGatewayTemplateSelect.Keys) { string tempId = this.modelData.dicGatewayTemplateSelect[localId]; if (this.modelData.dicGatewayInfo.ContainsKey(tempId) == false) { //应该不会进来,即使进来,我也不知道为什么 continue; } //取本地网关对象 var localGateway = HdlGatewayLogic.Current.GetLocalGateway(localId); if (localGateway == null) { //应该不会进来,即使进来,我也不知道为什么 continue; } var tempGateway = this.modelData.dicGatewayInfo[tempId]; //初始化容器 var listUpdateInfo = new List() { null, null }; bool needUpdate = false; //Linux版本比较 if (tempGateway.LinuxFirmwareVersion != localGateway.LinuxFirmwareVersion) { //Linux升级固件文件全路径 string updateFile = HdlFirmwareUpdateLogic.Current.GetGatewayLinuxFirmwareFile(tempGateway); if (System.IO.File.Exists(updateFile) == true) { //如果存在的话 var info = new GatewayNeedUpdateInfo(); info.Div = 1; info.FullFileName = updateFile; listUpdateInfo[0] = info; needUpdate = true; } } //协调器版本比较 if (tempGateway.CoordinatorFirmwareVersion != localGateway.CoordinatorFirmwareVersion) { //协调器升级固件文件全路径 string updateFile = HdlFirmwareUpdateLogic.Current.GetGatewayCoordinatorFirmwareFile(tempGateway); if (System.IO.File.Exists(updateFile) == true) { //如果存在的话 var info = new GatewayNeedUpdateInfo(); info.Div = 2; info.FullFileName = updateFile; listUpdateInfo[1] = info; needUpdate = true; } } //虚拟驱动比较 if (HdlGatewayLogic.Current.CheckGatewayHadDriveCode(localGateway) == true) { foreach (var localCode in localGateway.DriveCodeList) { foreach (var tempCode in tempGateway.DriveCodeList) { //防止它放的顺序不样 if (localCode.DriveCode == tempCode.DriveCode && localCode.DriveFwVersion != tempCode.DriveFwVersion) { //虚拟驱动升级固件文件全路径 string updateFile = HdlFirmwareUpdateLogic.Current.GetGatewayDriveCodeFirmwareFile(tempCode); if (System.IO.File.Exists(updateFile) == true) { //如果存在的话 var info = new GatewayNeedUpdateInfo(); info.Div = 3; info.DriveCode = tempCode.DriveCode; info.FullFileName = updateFile; listUpdateInfo.Add(info); needUpdate = true; } } } } } if (listUpdateInfo.Count == 2) { listUpdateInfo.Add(null); } //添加目标缓存 if (needUpdate == true) { dicGateway[localId] = listUpdateInfo; } } return dicGateway; } #endregion #region ■ 从模板文件中获取对象(外部调用)_____ /// /// 从模板文件中,获取设备和网关对象 /// /// 模板文件的全路径 /// ota设备列表 /// 网关列表 public void GetDeviceObjectFromTemplate(string fullFileName, ref List listDevice, ref List listGateway) { var fileData = HdlFileLogic.Current.ReadFileTextContent(fullFileName); if (fileData == null) { return; } var deviceType = string.Empty; var strTempContentData = string.Empty; //根据换行符切分数据文本 string[] arryData = fileData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string strData in arryData) { if (strData == "#START#") { //无附加数据的【数据标题】 strTempContentData = string.Empty; continue; } if (strData.StartsWith("#DeviceInfo START#") == true) { //附加数据:设备对象类型 deviceType = strData.Substring(18); strTempContentData = string.Empty; continue; } try { //设备对象 if (strData == "#DeviceInfo END#") { //反序列化设备 if (deviceType == "OtaDevice" || deviceType == "OtaPanelDevice") { var device = Newtonsoft.Json.JsonConvert.DeserializeObject(strTempContentData); if (device != null) { listDevice.Add(device); } } strTempContentData = string.Empty; continue; } //网关对象数据 else if (strData == "#GatewayInfo END#") { //反序列化设备 var gateway = Newtonsoft.Json.JsonConvert.DeserializeObject(strTempContentData); if (gateway != null) { listGateway.Add(gateway); } strTempContentData = string.Empty; return; } strTempContentData += strData; } catch (Exception ex) { HdlLogLogic.Current.WriteLog(ex, "模板bin文件出问题\r\n" + strTempContentData); strTempContentData = string.Empty; } } } #endregion #region ■ 一般方法___________________________ /// /// 复制模板bin文件到本地的模板文件夹里 /// /// 模板文件的名字(全住宅存放的模板) public void CopyTemplateFileToLocalDirectory(string templateFileName) { string sourceFile = System.IO.Path.Combine(HdlFileNameResourse.AllResidenceTemplateDirectory, templateFileName); this.CopyTemplateFileToLocalDirectory2(sourceFile); } /// /// 复制模板bin文件到本地的模板文件夹里 /// /// 模板文件的全路径 public void CopyTemplateFileToLocalDirectory2(string fullTemplateName) { if (System.IO.File.Exists(fullTemplateName) == false) { return; } //保存的路径 string targetFile = HdlFileNameResourse.LocalTemplateDirectory; targetFile = System.IO.Path.Combine(targetFile, TemplateFileName); try { System.IO.File.Copy(fullTemplateName, targetFile, true); } catch (Exception ex) { HdlLogLogic.Current.WriteLog(ex, "复制模板bin文件失败"); } } /// /// 删除本地全部的模板缓存文件 /// public void DeleteAllLocalFile() { //获取这个路径下面全部的文件 var listFile = HdlFileLogic.Current.GetFileFromDirectory(HdlFileNameResourse.LocalTemplateDirectory, false); ; foreach (var file in listFile) { HdlFileLogic.Current.DeleteFile(file); } } /// /// 获取模板中的设备数 /// /// public int GetTemplateDeviceCount() { return this.modelData.dicDeviceInfo.Count; } /// /// 检测设备模板数和当前设备选择的模板数是否一致 /// /// public bool CheckTemplateDeviceCountAndSelectCountIsEqual() { return this.modelData.dicDeviceInfo.Count == this.modelData.dicDeviceTemplateSelect.Count; } /// /// 获取文件里指定的内容 /// /// 文件文本 /// 开始字符 /// 结束字符 /// private string GetDataFromFileContent(string fileContrnt, string startFlage, string endFlage) { string[] arryValue = fileContrnt.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string modelBaseInfo = string.Empty; bool getData = false; bool success = false; foreach (var strValue in arryValue) { //开始 if (strValue == startFlage) { getData = true; //同一开始字符的东西很多 modelBaseInfo = string.Empty; continue; } //结束 if (strValue == endFlage) { success = true; break; } if (getData == true) { modelBaseInfo += strValue; } } return success == true ? modelBaseInfo : string.Empty; } /// /// 获取模块ID /// /// /// private string GetDeviceModelId(string deviceMac) { var listDevice = HdlDeviceCommonLogic.Current.GetDevicesByMac(deviceMac); foreach (var device in listDevice) { if (device.ModelIdentifier != string.Empty) { return device.ModelIdentifier; } } return string.Empty; } /// /// 获取设备保存的模板对象(考虑有的设备用的是200端点,所以这里最好不用设备对象作为参数) /// /// /// /// public TemplateDeviceDataCommon GetDeviceModelDataClass(string deviceMac, int deviceEpoint, ModelDeviceSaveEnum saveEnum, TemplateDeviceDataCommon newClass) { string mainkey = HdlDeviceCommonLogic.Current.GetDeviceMainKeys(deviceMac, deviceEpoint); //创建存储空间 if (this.modelData.dicDeviceTemplateData.ContainsKey(mainkey) == false) { this.modelData.dicDeviceTemplateData[mainkey] = new List(); } foreach (var data in this.modelData.dicDeviceTemplateData[mainkey]) { //如果是已经存在了的 if (data.DataSaveDiv == saveEnum) { return data; } } //新建一个新的对象 newClass.DataSaveDiv = saveEnum; newClass.DeviceEpoint = deviceEpoint; newClass.DeviceMac = deviceMac; //默认创建一个索引位 newClass.ListReceiveResult.Add(string.Empty); newClass.ListReceiveTopic.Add(string.Empty); newClass.ListSendTopic.Add(string.Empty); this.modelData.dicDeviceTemplateData[mainkey].Add(newClass); return newClass; } /// /// 显示信息框 /// /// 信息类型 /// 信息 /// 单击确认后执行的回调函数 /// 按钮的文本 private void ShowMassage(ShowMsgType msgType, string msg, Action action = null, string buttonText = null) { HdlMessageLogic.Current.ShowMassage(msgType, msg, action, buttonText); } #endregion } }