using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; namespace Shared.Phone.UserCenter { /// /// 设备升级控件 /// public class DeviceFirmwareUpdateControl : RowLayout { #region ■ 变量声明___________________________ /// /// 当前执行状态 /// public UpdateStatuMode UpdateStatu = UpdateStatuMode.None; /// /// 设备新版本的固件信息 /// public FirmwareVersionInfo deviceFirmware = null; /// /// 升级按钮(由外部进行赋值) /// public BottomClickButton btnUpdateButton = null; /// /// 升级是否完成 /// public bool IsFinishUpdate = true; /// /// 前一次的最终状态 /// private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None; /// /// 进度控件 /// private FrameLayout frameBar = null; /// /// 百分比进度 /// private RowBottomBlackView btnProgress = null; /// /// 网关 /// private ZbGateway zbGateway = null; /// /// 升级的设备 /// private List listUpdateDevice = null; #endregion #region ■ 初始化_____________________________ /// /// 网关升级控件 /// /// 列表控件 /// 设备 /// 设备新版本的固件信息 public DeviceFirmwareUpdateControl(VerticalScrolViewLayout listView, List i_listdevice, FirmwareVersionInfo i_deviceFirmware = null) { this.listUpdateDevice = i_listdevice; //设备的版本 this.deviceFirmware = i_deviceFirmware; if (this.deviceFirmware == null) { //拥有200端口这个东西的时候,才会处理 var oTADevice = Common.LocalDevice.Current.GetOTADevice(listUpdateDevice[0].DeviceAddr); if (oTADevice == null || oTADevice.ImgVersion == -1) { return; } this.deviceFirmware = FirmwareUpdateLogic.GetFirmwareMostVersionInfo(FirmwareLevelType.ZigbeeDevice, oTADevice.HwVersion.ToString(), oTADevice.ImgTypeId.ToString(), oTADevice.ImgVersion); } this.Height = ControlCommonResourse.ListViewRowHeight; if (listView != null) { listView.AddChidren(this); var btnTemp = new ButtonCommon(); Common.LocalDevice.Current.SetDeviceBeloneIconToControl(btnTemp, i_listdevice); //初始化控件 this.InitChidrenControl(btnTemp.UnSelectedImagePath); } } /// /// 初始化控件 /// /// 图标 public void InitChidrenControl(string unSelPath) { this.RemoveAll(); //进度 this.frameBar = new FrameLayout(); this.frameBar.Width = 0; this.frameBar.BackgroundColor = UserCenterColor.Current.Green; this.AddChidren(frameBar); //桌布 var frameLayout = new StatuFrameLayout(ControlCommonResourse.ListViewRowHeight, false); frameLayout.Height = ControlCommonResourse.ListViewRowHeight; frameLayout.BackgroundColor = UserCenterColor.Current.Transparent; this.AddChidren(frameLayout); //图标 var btnIcon = new RowLeftIconView(); btnIcon.UnSelectedImagePath = unSelPath; frameLayout.AddChidren(btnIcon, ChidrenBindMode.BindEventOnly); //指定的设备 var btnDevice = new RowTopBlackView(); btnDevice.BackgroundColor = UserCenterColor.Current.Transparent; btnDevice.Text = Common.LocalDevice.Current.GetDeviceMacName(this.listUpdateDevice[0]); frameLayout.AddChidren(btnDevice, ChidrenBindMode.BindEventOnly); //固件信息 this.btnProgress = new RowBottomBlackView(); btnProgress.BackgroundColor = UserCenterColor.Current.Transparent; btnProgress.Text = Common.LocalDevice.Current.AppendVersion(deviceFirmware.FirmwareVersion); frameLayout.AddChidren(btnProgress, ChidrenBindMode.BindEventOnly); } #endregion #region ■ 开始更新___________________________ /// /// 进入执行更新操作准备阶段 /// public void StartUpdateReady() { if (btnUpdateButton.isCanClickUp == false) { return; } if (this.UpdateStatu == UpdateStatuMode.DeviceUpdateReady || this.UpdateStatu == UpdateStatuMode.DeviceUpdating) { //终止升级 this.StopUpdate(); return; } if (this.UpdateStatu == UpdateStatuMode.Wait) { //如果是等待模式,再次点击时,移除列表 string mainkeys = this.listUpdateDevice[0].DeviceAddr; if (FirmwareUpdateResourse.dicDeviceUpdateList.ContainsKey(mainkeys) == true) { FirmwareUpdateResourse.dicDeviceUpdateList.Remove(mainkeys); } //升级 btnUpdateButton.TextID = R.MyInternationalizationString.uLevelUp; btnUpdateButton.SetNotClickStatu(); this.UpdateStatu = UpdateStatuMode.None; return; } //如果它有状态,则表示之前它被什么错误中断了 if (this.UpdateStatu != UpdateStatuMode.None) { //保存起来,后面有用处 this.oldUpdateStatu = this.UpdateStatu; } //进入等待模式 this.UpdateStatu = UpdateStatuMode.Wait; this.btnUpdateButton.TextID = R.MyInternationalizationString.uWaitting; this.btnUpdateButton.SetClickStatu(); string mainkeys2 = this.listUpdateDevice[0].DeviceAddr; FirmwareUpdateResourse.dicDeviceUpdateList[mainkeys2] = this; //执行下一个可更新的固件的更新操作 FirmwareUpdateLogic.DoUpdateNextFirmware(); } /// /// 开始执行更新操作 /// public void DoStartUpdate() { this.btnUpdateButton.isCanClickUp = false; //状态变更 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; Application.RunOnMainThread(() => { this.btnUpdateButton.TextID = R.MyInternationalizationString.uDownLoading; }); //设备固件下载中 string msg = Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoading); this.SetProgressValue(0, msg); this.zbGateway = this.listUpdateDevice[0].Gateway; if (zbGateway == null) { //获取网关信息失败 this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGetGatewayInfoFail)); //显示重新下载模式 this.ShowReDownLoadMode(); this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail; return; } //下载设备文件的进度 zbGateway.ReportAction += this.DownLoadDeviceFileProgress; await System.Threading.Tasks.Task.Delay(1000); //下载设备文件 var result = await this.listUpdateDevice[0].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.CurrentGateWayId != Common.LocalGateway.Current.GetGatewayId(this.zbGateway)) { //不是自己的网关推送,则不处理 return; } 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; } //设置进度 string msg = Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoading); this.SetProgressValue(responData.DownloadPercent, msg); } #endregion #region ■ 设备升级___________________________ /// /// 设置设备升级程序的文件 /// private async void DoSetUpdateDeviceFile() { this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady; Application.RunOnMainThread(() => { this.btnUpdateButton.TextID = R.MyInternationalizationString.uLevelUping; }); await System.Threading.Tasks.Task.Delay(1000); //设备升级中 string msg = Language.StringByID(R.MyInternationalizationString.uDeviceUpdating); this.SetProgressValue(0, msg); //首先指定设备升级的固件 var result = await this.listUpdateDevice[0].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.listUpdateDevice[0].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(); 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.listUpdateDevice[0].DeviceAddr; //控制面板的时候,固定200端口 updateData.DeviceList.Add(deviceInfo); this.zbGateway.ReportAction += this.UpdateDeviceProgress; //执行升级 var upResult = await this.listUpdateDevice[0].StartDeviceUpdateAsync(this.zbGateway, updateData); //别的错误 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; //终止升级 var myResult = await this.listUpdateDevice[0].KillUpdateAsync(this.zbGateway, 200); return; } //可以取消 Application.RunOnMainThread(() => { this.btnUpdateButton.isCanClickUp = true; this.btnUpdateButton.SetNotClickStatu(); }); } /// /// 升级设备的进度 /// /// /// private void UpdateDeviceProgress(string CommadDiv, object objValue) { if (CommadDiv != "DeviceUpgradePercent" || objValue == null) { return; } var tempZb = (ZbGateway)objValue; if (tempZb.CurrentGateWayId != Common.LocalGateway.Current.GetGatewayId(this.zbGateway)) { //不是自己的网关推送,则不处理 return; } //设置进度 var responData = tempZb.oTAScheduleResponData; //检测状态码 if (this.CheckStatusCode(responData) == false) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; new System.Threading.Thread(async () => { //终止升级 var myResult = await this.listUpdateDevice[0].KillUpdateAsync(this.zbGateway, 200); }) { IsBackground = true }.Start(); this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; return; } if (responData.Status == 2) { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; //显示升级完成的信息 this.ShowFinishMsg(); return; } if (responData.Status == 0) { //没什么意义 return; } //设备升级中 this.UpdateStatu = UpdateStatuMode.DeviceUpdating; //设备升级中 string msg = Language.StringByID(R.MyInternationalizationString.uDeviceUpdating); this.SetProgressValue(responData.Percent, msg); } /// /// 检测状态码 /// /// /// private bool CheckStatusCode(ZbGatewayData.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, string appendText = "") { if (value > 100) { //有时候会瞎发什么鬼过来 return; } decimal result = value / 100; Application.RunOnMainThread(() => { //百分比数,取整数部分 int percent = (int)(result * 100); int width = (int)(result * this.Width); this.frameBar.Width = width; if (appendText != string.Empty) { this.btnProgress.Text = percent + "% " + appendText; } else { this.btnProgress.Text = percent + "%"; } }); } /// /// 设定进度值 /// /// 进度值 private void SetProgressValue(string value) { Application.RunOnMainThread(() => { this.btnProgress.Text = value; }); } /// /// 设置错误信息 /// /// private void ShowErrorMsg(string value) { Application.RunOnMainThread(() => { this.btnProgress.Text = value; }); } #endregion #region ■ 同步进度___________________________ /// /// 同步进度 /// public void SynchronizeDeviceProgress() { this.UpdateStatu = UpdateStatuMode.DeviceUpdating; this.IsFinishUpdate = false; this.btnUpdateButton.TextID = R.MyInternationalizationString.uLevelUping; this.btnUpdateButton.isCanClickUp = true; this.btnUpdateButton.SetNotClickStatu(); //设备升级中 string msg = Language.StringByID(R.MyInternationalizationString.uDeviceUpdating); this.SetProgressValue(0, msg); string mainKeys = this.listUpdateDevice[0].DeviceAddr; FirmwareUpdateResourse.dicDeviceUpdateList[mainKeys] = this; this.zbGateway = this.listUpdateDevice[0].Gateway; //同步进度 this.zbGateway.ReportAction += UpdateDeviceProgress; } #endregion #region ■ 终止升级___________________________ /// /// 终止升级 /// private void StopUpdate() { //确认是否要停止升级? string msg = Language.StringByID(R.MyInternationalizationString.uConfirmWantToStopUpdate); var contr = new ConfirmMsgControl(msg); contr.Show(); contr.ResultEventHandler += (sender, result) => { if (result == false || this.UpdateStatu == UpdateStatuMode.UpdateSuccess) { return; } new System.Threading.Thread(async () => { this.zbGateway.ReportAction -= this.UpdateDeviceProgress; //终止升级 var myResult = await this.listUpdateDevice[0].KillUpdateAsync(this.zbGateway, 200); Application.RunOnMainThread(() => { //升级 this.btnUpdateButton.TextID = R.MyInternationalizationString.uLevelUp; //固件信息 string ver = Language.StringByID(R.MyInternationalizationString.uVersionAbbreviation); btnProgress.Text = Common.LocalDevice.Current.AppendVersion(this.deviceFirmware.FirmwareVersion); //清空进度条 this.frameBar.Width = 0; //状态变更 this.IsFinishUpdate = true; this.oldUpdateStatu = UpdateStatuMode.None; this.UpdateStatu = UpdateStatuMode.None; //执行下一个可更新的固件的更新操作 FirmwareUpdateLogic.DoUpdateNextFirmware(); }); }) { IsBackground = true }.Start(); }; } #endregion #region ■ 升级完成提示_______________________ /// /// 显示升级完成的信息 /// private void ShowFinishMsg() { new System.Threading.Thread(() => { System.Threading.Thread.Sleep(3000); //重新刷新缓存 var otaDevice = Common.LocalDevice.Current.GetOTADevice(listUpdateDevice[0].DeviceAddr); Common.LocalDevice.Current.SetAllImageInfoToOtaDevice(otaDevice, this.OtaImageInfoActionBack); System.Threading.Thread.Sleep(1500); int count = 12; while (this.IsFinishUpdate == false && count > 0) { DeviceAttributeLogic.Current.SetFirmwareVersionComand(otaDevice); //等待一下设备信息的反馈 System.Threading.Thread.Sleep(2000); count--; } Application.RunOnMainThread(() => { if (UserCenterResourse.DicActionForm.ContainsKey("DeviceFirmwareInfoForm") == true) { //刷新设备信息界面 ((Device.DeviceFirmwareInfoForm)UserCenterResourse.DicActionForm["DeviceFirmwareInfoForm"]).ShowForm(listUpdateDevice); } //状态变更 this.IsFinishUpdate = true; this.UpdateStatu = UpdateStatuMode.UpdateSuccess; FirmwareUpdateLogic.DoUpdateNextFirmware(); //完成 this.btnUpdateButton.TextID = R.MyInternationalizationString.uFinish; this.btnUpdateButton.isCanClickUp = true; this.btnUpdateButton.SetNotClickStatu(); //设备升级成功! this.SetProgressValue(100, Language.StringByID(R.MyInternationalizationString.uDeviceUpdateSuccess)); }); }) { IsBackground = true }.Start(); } /// /// 获取到了OTA镜像信息回调(100%特定回调) /// /// /// private void OtaImageInfoActionBack(CommonDevice device, CommonDevice.DeviceStatusReportData reportData) { this.IsFinishUpdate = true; } #endregion #region ■ 处理结果提示_______________________ /// /// 显示重新安装的信息 /// private void ShowReSetupMsg() { //状态变更 this.IsFinishUpdate = true; Application.RunOnMainThread(() => { //重新升级 this.btnUpdateButton.TextID = R.MyInternationalizationString.uReLevelUp; this.btnUpdateButton.isCanClickUp = true; this.btnUpdateButton.SetNotClickStatu(); //清空进度条 this.frameBar.Width = 0; //执行下一个升级 FirmwareUpdateLogic.DoUpdateNextFirmware(); }); } /// /// 显示重新下载模式 /// private void ShowReDownLoadMode() { //状态变更 this.IsFinishUpdate = true; Application.RunOnMainThread(() => { this.btnUpdateButton.TextID = R.MyInternationalizationString.uReDownLoad; this.btnUpdateButton.isCanClickUp = true; this.btnUpdateButton.SetNotClickStatu(); //清空进度条 this.frameBar.Width = 0; //执行下一个升级 FirmwareUpdateLogic.DoUpdateNextFirmware(); }); } #endregion } }