using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; namespace Shared.Phone.UserCenter { /// /// HDL设备升级的逻辑 /// public class HdlDeviceUpdateLogic : HdlDeviceUpdateCommonLogic { #region ■ 变量声明___________________________ /// /// 更新状态变化的事件 /// 第一个参数为: /// -1:更新异常,后面的值为异常信息的翻译文本 /// 0:更新状态正常变化,后面的值为状态变更的文本翻译 /// 1:升级成功 /// 2:主动终止升级 /// 3:从等待中取消(目前还没有用) /// public Action UpdateStatuChangedEvent = null; /// /// 进度值事件 /// public Action ProgressEvent = null; /// /// 设备新版本的固件信息(多个设备升级时,应该会需要公开这个对象) /// public FirmwareVersionInfo deviceFirmware = null; /// /// 网关 /// private ZbGateway zbGateway = null; /// /// 升级的设备 /// private OTADevice otaDevice = null; /// /// 前一次的最终状态 /// private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None; #endregion #region ■ 初始化_____________________________ /// /// HDL设备升级,以下为两个重要事件 /// UpdateStatuChangedEvent:更新状态变化的事件 /// ProgressEvent:进度值事件 /// StartUpdateReady():设备开始执行升级的函数(再次调用,内部条件达成时,可以选择终止升级),在调用这个之前,请先实现上面两个方法 /// /// 设备 /// 设备的固件信息 public HdlDeviceUpdateLogic(OTADevice i_otaDevice, FirmwareVersionInfo i_deviceFirmware) { this.ClassDiv = 2; this.otaDevice = i_otaDevice; this.deviceFirmware = i_deviceFirmware; this.zbGateway = i_otaDevice.Gateway; } #endregion #region ■ 开始更新___________________________ /// /// 进入执行更新操作准备阶段(再次调用,内部条件达成时,可以选择终止升级) /// public void StartUpdateReady() { if (this.UpdateStatu == UpdateStatuMode.DeviceUpdateReady || this.UpdateStatu == UpdateStatuMode.DeviceUpdating) { //终止升级 this.StopUpdate(); return; } if (this.UpdateStatu == UpdateStatuMode.Wait) { //如果是等待模式,再次点击时,移除列表 if (FirmwareUpdateResourse.dicUpdateList.ContainsKey(otaDevice.DeviceAddr) == true) { FirmwareUpdateResourse.dicUpdateList.Remove(otaDevice.DeviceAddr); } //取消 this.UpdateStatu = UpdateStatuMode.None; this.UpdateStatuChangedEvent?.Invoke(3, ""); return; } //如果它有状态,则表示之前它被什么错误中断了 if (this.UpdateStatu != UpdateStatuMode.None) { //保存起来,后面有用处 this.oldUpdateStatu = this.UpdateStatu; } //进入等待模式 this.UpdateStatu = UpdateStatuMode.Wait; FirmwareUpdateResourse.dicUpdateList[otaDevice.DeviceAddr] = this; //等待中… this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uWaitting)); //执行下一个可更新的固件的更新操作 HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); } /// /// 开始执行更新操作(FirmwareUpdateLogic调用) /// public override void DoStartUpdate() { //状态变更 this.IsFinishUpdate = false; this.UpdateStatu = UpdateStatuMode.Action; //根据状态执行操作 this.DoAdjustByStatuMode(); } /// /// 根据状态执行操作 /// private void DoAdjustByStatuMode() { //首发时,从开始执行 if (this.oldUpdateStatu == UpdateStatuMode.None) { //下载设备文件 this.DownLoadDeviceFile(); } //设备下载失败 else if (this.oldUpdateStatu == UpdateStatuMode.DeviceDownLoadFail) { //下载设备文件 this.DownLoadDeviceFile(); } //设备升级失败 else if (this.oldUpdateStatu == UpdateStatuMode.DeviceUpdateFail) { //执行设置设备升级程序的文件 this.DoSetUpdateDeviceFile(); } else { //重新再来 this.DownLoadDeviceFile(); } } #endregion #region ■ 设备下载___________________________ /// /// 下载设备文件 /// private async void DownLoadDeviceFile() { this.UpdateStatu = UpdateStatuMode.DeviceDownLoad; //设备固件正在下载… this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoading)); //设置初始值 this.SetProgressValue(0); //开启设备下载超时线程 this.StartDownLoadTimeOutThread(); //下载设备文件的进度 zbGateway.ReportAction += this.DownLoadDeviceFileProgress; await System.Threading.Tasks.Task.Delay(1000); //下载设备文件 var result = await this.otaDevice.DownloadFileAsync(zbGateway, this.deviceFirmware.DistributedMark, this.deviceFirmware.Name); if (string.IsNullOrEmpty(result.errorMessageBase) == false) { //设备固件资源下载失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoadFail)); //显示重新下载模式 this.ShowReDownLoadMode(); zbGateway.ReportAction -= this.DownLoadDeviceFileProgress; this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail; return; } } /// /// 下载设备文件的进度 /// /// /// private void DownLoadDeviceFileProgress(string CommadDiv, object objValue) { if (CommadDiv != "DownloadFileProgress" || objValue == null) { return; } var tempZb = (ZbGateway)objValue; if (tempZb.GwId != this.zbGateway.GwId) { //不是自己的网关推送,则不处理 return; } //刷新超时时间 this.DownLoadTimeOutRefresh(); var responData = tempZb.downloadFileProgressResponData; if (responData.Status == 2) { //设备固件资源下载失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoadFail)); //显示重新下载模式 this.ShowReDownLoadMode(); zbGateway.ReportAction -= this.DownLoadDeviceFileProgress; this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail; return; } else if (responData.Status == 0) { zbGateway.ReportAction -= this.DownLoadDeviceFileProgress; //显示执行更新模式 this.DoSetUpdateDeviceFile(); return; } //设置进度 this.SetProgressValue(responData.DownloadPercent); } #endregion #region ■ 设备升级___________________________ /// /// 设置设备升级程序的文件 /// private async void DoSetUpdateDeviceFile() { this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady; //设备正在升级… this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uDeviceUpdating)); //设置初始值 this.SetProgressValue(0); await System.Threading.Tasks.Task.Delay(1000); //首先指定设备升级的固件 var result = await this.otaDevice.UpgradeDeviceAsync(this.zbGateway, this.deviceFirmware.Name); if (result.otaSetImageData != null && result.otaSetImageData.Result == 1) { //升级文件丢失!请重新下载! this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uLostUpdateFileAndReDownLoad)); //显示重新下载模式 this.ShowReDownLoadMode(); this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail; return; } else if (result.otaSetImageData != null && result.otaSetImageData.Result == 2) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; //判断当前设备是不是在升级中 string nowMainkeys = this.otaDevice.DeviceAddr; foreach (var devi in result.otaSetImageData.DeviceList) { string mainkeys = devi.MacAddr; if (mainkeys == nowMainkeys) { //它自己就在升级中 ,直接同步 this.SynchronizeDeviceProgress(); return; } } //当前有节点设备正在升级中,请稍后再试 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uHadDeviceUpdatingAndDoAgain)); //显示重新安装 this.ShowReSetupMsg(); this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; return; } else if (string.IsNullOrEmpty(result.errorMessageBase) == false) { //设备升级失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceUpdatingFail)); //显示重新安装 this.ShowReSetupMsg(); this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; return; } //执行设备升级程序 this.DoUpdateDevice(); } /// /// 执行设备升级程序 /// private async void DoUpdateDevice() { //执行升级 var updateData = new CommonDevice.StartUpdateData(); var deviceInfo = new CommonDevice.OTADeviceList(); deviceInfo.MacAddr = this.otaDevice.DeviceAddr; //控制面板的时候,固定200端口 updateData.DeviceList.Add(deviceInfo); this.zbGateway.ReportAction += this.UpdateDeviceProgress; //执行升级 var upResult = await this.otaDevice.StartDeviceUpdateAsync(this.zbGateway, updateData); //设备升级中 this.UpdateStatu = UpdateStatuMode.DeviceUpdating; //开启设备升级超时线程 this.StartUpdateTimeOutThread(); //别的错误 if (upResult.startUpdateDeviceData == null || upResult.startUpdateDeviceData.Result == 1) { //设备升级失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceUpdatingFail)); //显示重新安装 this.ShowReSetupMsg(); this.zbGateway.ReportAction -= this.UpdateDeviceProgress; this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; //终止升级 await this.otaDevice.KillUpdateAsync(this.zbGateway, 200); return; } } /// /// 升级设备的进度 /// /// /// private void UpdateDeviceProgress(string CommadDiv, object objValue) { if (CommadDiv != "DeviceUpgradePercent" || objValue == null) { return; } var tempZb = (ZbGateway)objValue; if (tempZb.GwId != this.zbGateway.GwId) { //不是自己的网关推送,则不处理 return; } //刷新超时时间 this.UpdateTimeOutRefresh(); //设置进度 var responData = tempZb.oTAScheduleResponData; //检测状态码 if (this.CheckStatusCode(responData) == false) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; HdlThreadLogic.Current.RunThread(async () => { //终止升级 await this.otaDevice.KillUpdateAsync(this.zbGateway, 200); }); this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; return; } if (responData.Status == 2) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; //显示升级完成的信息 this.ShowFinishMsg(); return; } if (responData.Status == 0) { //没什么意义 return; } //设置进度值 this.SetProgressValue(responData.Percent); } /// /// 检测状态码 /// /// /// private bool CheckStatusCode(CommonDevice.OTAScheduleResponData statusData) { if (statusData == null) { return true; } if (statusData.Status == 3) { //响应超时,升级失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail)); //显示重新安装 this.ShowReSetupMsg(); return false; } else if (statusData.Status == 150) { //无效的升级固件 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uErrorUpdateFirmwareFile)); //显示重新安装 this.ShowReSetupMsg(); return false; } else if (statusData.Status == 153) { //升级固件不足 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uUpdateFirmwareFileNotEnough)); //显示重新安装 this.ShowReSetupMsg(); return false; } else if (statusData.Status == 149) { //升级操作被终止 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uUpdatedWasStoped)); //显示重新安装 this.ShowReSetupMsg(); return false; } return true; } #endregion #region ■ 设置进度___________________________ /// /// 设定进度值 /// /// 进度值 private void SetProgressValue(decimal value) { if (value > 100) { //有时候会瞎发什么鬼过来 return; } this.ProgressEvent?.Invoke(value); } /// /// 设置错误信息 /// /// private void ShowErrorMsg(string value) { this.UpdateStatuChangedEvent?.Invoke(-1, value); } #endregion #region ■ 同步进度___________________________ /// /// 同步进度 /// private void SynchronizeDeviceProgress() { this.UpdateStatu = UpdateStatuMode.DeviceUpdating; this.IsFinishUpdate = false; //设备正在升级… this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uDeviceUpdating)); this.SetProgressValue(0); FirmwareUpdateResourse.dicUpdateList[otaDevice.DeviceAddr] = this; //同步进度 this.zbGateway.ReportAction += UpdateDeviceProgress; } #endregion #region ■ 终止升级___________________________ /// /// 终止升级 /// private void StopUpdate() { //确认是否要停止升级? string msg = Language.StringByID(R.MyInternationalizationString.uConfirmWantToStopUpdate); var contr = new ShowMsgControl(ShowMsgType.Confirm, msg); contr.ConfirmClickEvent += async () => { if (this.UpdateStatu != UpdateStatuMode.DeviceUpdateReady && this.UpdateStatu != UpdateStatuMode.DeviceUpdating) { return; } this.zbGateway.ReportAction -= this.UpdateDeviceProgress; //终止升级 var myResult = await this.otaDevice.KillUpdateAsync(this.zbGateway, 200); //状态变更 this.IsFinishUpdate = true; this.oldUpdateStatu = UpdateStatuMode.None; this.UpdateStatu = UpdateStatuMode.None; //执行下一个可更新的固件的更新操作 HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); this.UpdateStatuChangedEvent?.Invoke(2, ""); }; contr.Show(); } #endregion #region ■ 升级完成提示_______________________ /// /// 显示升级完成的信息 /// private void ShowFinishMsg() { //升级成功 this.UpdateStatu = UpdateStatuMode.UpdateSuccess; HdlThreadLogic.Current.RunThread(() => { System.Threading.Thread.Sleep(3000); //重新刷新缓存 HdlDeviceImageInfoLogic.Current.SetAllImageInfoToOtaDevice(otaDevice, (device, reportData) => { this.IsFinishUpdate = true; }); System.Threading.Thread.Sleep(1500); int count = 12; while (this.IsFinishUpdate == false && count > 0) { HdlDeviceImageInfoLogic.Current.SetFirmwareVersionComand(otaDevice); //等待一下设备信息的反馈 System.Threading.Thread.Sleep(2000); count--; } //移除事件 HdlDeviceImageInfoLogic.Current.RemoveDeviceFirmwareVersionThread(otaDevice); //设置进度值直接为100% this.ProgressEvent?.Invoke(100); //状态变更 this.IsFinishUpdate = true; //升级完成 this.UpdateStatu = UpdateStatuMode.UpdateFinish; HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); //设备升级成功! this.UpdateStatuChangedEvent?.Invoke(1, Language.StringByID(R.MyInternationalizationString.uDeviceUpdateSuccess)); }); } #endregion #region ■ 处理结果提示_______________________ /// /// 显示重新安装的信息 /// private void ShowReSetupMsg() { //状态变更 this.IsFinishUpdate = true; //执行下一个升级 HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); } /// /// 显示重新下载模式 /// private void ShowReDownLoadMode() { //状态变更 this.IsFinishUpdate = true; //执行下一个升级 HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); } #endregion #region ■ 设备下载超时线程___________________ /// /// 超时时间设置 /// private int downLoadTimeOutCount = 30; /// /// 开启设备下载超时线程 /// private void StartDownLoadTimeOutThread() { this.downLoadTimeOutCount = 30; HdlThreadLogic.Current.RunThread(() => { while (true) { var value = this.UpdateStatu.ToString(); if (value.EndsWith("DownLoad") == false) { //执行完成下载操作 break; } System.Threading.Thread.Sleep(1000); this.downLoadTimeOutCount--; if (this.downLoadTimeOutCount < 0) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; Application.RunOnMainThread(() => { //从头再来 this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail; //显示重新下载模式 this.ShowReDownLoadMode(); //响应超时,升级失败 string msg = Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail); this.ShowErrorMsg(msg); }); break; } } }); } /// /// 超时时间刷新 /// private void DownLoadTimeOutRefresh() { this.downLoadTimeOutCount = 30; } #endregion #region ■ 设备升级超时线程___________________ /// /// 升级超时时间设置 /// private int UpdateTimeOutCount = 60; /// /// 开启设备升级超时线程 /// private void StartUpdateTimeOutThread() { this.UpdateTimeOutCount = 60; HdlThreadLogic.Current.RunThread(() => { while (true) { var value = this.UpdateStatu.ToString(); if (this.UpdateStatu != UpdateStatuMode.DeviceUpdateReady || this.UpdateStatu != UpdateStatuMode.DeviceUpdating) { //执行完成升级操作 break; } System.Threading.Thread.Sleep(1000); this.UpdateTimeOutCount--; if (this.UpdateTimeOutCount < 0) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; Application.RunOnMainThread(() => { //从头再来 this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail; //显示重新下载模式 this.ShowReDownLoadMode(); //响应超时,升级失败 string msg = Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail); this.ShowErrorMsg(msg); }); break; } } }); } /// /// 升级超时时间刷新 /// private void UpdateTimeOutRefresh() { this.UpdateTimeOutCount = 60; } #endregion #region ■ 释放缓存___________________________ /// /// 释放缓存 /// public override void Dispose() { this.ProgressEvent = null; this.UpdateStatuChangedEvent = null; } #endregion } }