HDL Home App 第二版本 旧平台金堂用 正在使用
chenqiyang
2022-06-22 dc0309e64f02227d8e1468b7326c07955f804612
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlGatewayUpdateLogic.cs
old mode 100755 new mode 100644
@@ -1,1029 +1,1029 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 网关的升级逻辑
    /// </summary>
    public class HdlGatewayUpdateLogic : HdlDeviceUpdateCommonLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// <para>更新状态变化的事件</para>
        /// <para>第一个参数为:</para>
        /// <para>-1:更新异常,后面的值为异常信息的翻译文本</para>
        /// <para> 0:更新状态正常变化,后面的值为状态变更的文本翻译</para>
        /// <para> 1:升级成功</para>
        /// <para> 3:从等待中取消(目前还没有用)</para>
        /// </summary>
        public Action<int, string> UpdateStatuChangedEvent = null;
        /// <summary>
        /// 进度值事件(已经是百分比的值)
        /// </summary>
        public Action<decimal> ProgressEvent = null;
        /// <summary>
        /// 虚拟设备的固件信息
        /// </summary>
        public FirmwareVersionInfo virtualFirmware = null;
        /// <summary>
        /// 协调器新版本的固件信息
        /// </summary>
        public FirmwareVersionInfo coordinatorFirmware = null;
        /// <summary>
        /// 网关新版本的固件信息
        /// </summary>
        public FirmwareVersionInfo gatewayFirmware = null;
        /// <summary>
        /// 前一次的最终状态
        /// </summary>
        private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None;
        /// <summary>
        /// 要升级的网关
        /// </summary>
        private ZbGateway upDatezbGateway = null;
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 网关升级控件
        /// </summary>
        /// <param name="listView">列表控件</param>
        /// <param name="zbGateway">网关</param>
        /// <param name="i_virtualFirmware">虚拟设备的固件信息</param>
        /// <param name="i_coordinatorFirmware">协调器新版本的固件信息</param>
        /// <param name="i_gatewayFirmware">网关新版本的固件信息</param>
        public HdlGatewayUpdateLogic(ZbGateway zbGateway, FirmwareVersionInfo i_virtualFirmware,
            FirmwareVersionInfo i_coordinatorFirmware, FirmwareVersionInfo i_gatewayFirmware)
        {
            this.ClassDiv = 1;
            this.upDatezbGateway = zbGateway;
            this.virtualFirmware = i_virtualFirmware;
            this.coordinatorFirmware = i_coordinatorFirmware;
            this.gatewayFirmware = i_gatewayFirmware;
        }
        #endregion
        #region ■ 开始更新___________________________
        /// <summary>
        /// 进入执行更新操作准备阶段
        /// </summary>
        public void StartUpdateReady()
        {
            if (this.UpdateStatu == UpdateStatuMode.Wait)
            {
                //如果是等待模式,再次点击时,移除列表
                string gwId = this.upDatezbGateway.GwId;
                if (FirmwareUpdateResourse.dicUpdateList.ContainsKey(gwId) == true)
                {
                    FirmwareUpdateResourse.dicUpdateList.Remove(gwId);
                }
                this.UpdateStatu = UpdateStatuMode.None;
                //取消
                this.UpdateStatuChangedEvent?.Invoke(3, "");
                return;
            }
            //如果它有状态,则表示之前它被什么错误中断了
            if (this.UpdateStatu != UpdateStatuMode.None)
            {
                //保存起来,后面有用处
                this.oldUpdateStatu = this.UpdateStatu;
            }
            //进入等待模式
            this.UpdateStatu = UpdateStatuMode.Wait;
            string gwId2 = this.upDatezbGateway.GwId;
            FirmwareUpdateResourse.dicUpdateList[gwId2] = this;
            //等待中…
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uWaitting));
            //执行下一个可更新的固件的更新操作
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        /// <summary>
        /// 开始执行更新操作(FirmwareUpdateLogic调用)
        /// </summary>
        public override void DoStartUpdate()
        {
            //状态变更
            this.IsFinishUpdate = false;
            this.UpdateStatu = UpdateStatuMode.Action;
            //设置拥有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(true);
            //根据状态执行操作
            this.DoAdjustByStatuMode();
        }
        /// <summary>
        /// 根据状态执行操作
        /// </summary>
        private void DoAdjustByStatuMode()
        {
            //首发时,从开始执行
            if (this.oldUpdateStatu == UpdateStatuMode.None)
            {
                //下载虚拟驱动文件
                this.DownLoadVirtualFile();
            }
            //虚拟驱动下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.VirtualDownLoadFail)
            {
                //下载虚拟驱动文件
                this.DownLoadVirtualFile();
            }
            //虚拟驱动更新失败
            else if (this.oldUpdateStatu == UpdateStatuMode.VirtualUpdateFail)
            {
                //执行虚拟驱动更新
                this.DoUpdateVirtual();
            }
            //协调器下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.CoordinatorDownLoadFail)
            {
                //下载虚拟驱动文件(从头再来)
                this.DownLoadVirtualFile();
            }
            //协调器升级失败
            else if (this.oldUpdateStatu == UpdateStatuMode.CoordinatorUpdateFail)
            {
                //执行虚拟驱动更新(从头再来)
                this.DoUpdateVirtual();
            }
            //网关下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.GatewayDownLoadFail)
            {
                //下载虚拟驱动文件(从头再来)
                this.DownLoadVirtualFile();
            }
            //网关升级失败
            else if (this.oldUpdateStatu == UpdateStatuMode.GatewayUpdateFail)
            {
                //执行虚拟驱动更新(从头再来)
                this.DoUpdateVirtual();
            }
            else
            {
                //重新再来
                this.DownLoadVirtualFile();
            }
        }
        #endregion
        #region ■ 虚拟驱动下载_______________________
        /// <summary>
        /// 下载虚拟驱动文件
        /// </summary>
        private async void DownLoadVirtualFile()
        {
            //开启网关下载超时线程
            this.StartDownLoadTimeOutThread();
            //如果虚拟驱动不需要升级,则直接跳转下一步
            if (this.virtualFirmware == null)
            {
                //下载协调器文件
                this.DownLoadCoordinatorFile();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.VirtualDownLoad;
            //虚拟驱动固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoading));
            //下载虚拟驱动文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadVirtualFileProgress;
            //下载虚拟驱动文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.virtualFirmware.DistributedMark, this.virtualFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //虚拟驱动固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualDownLoadFail;
                return;
            }
        }
        /// <summary>
        /// 下载虚拟驱动文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadVirtualFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            //虚拟驱动固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoading));
            if (responData.Status == 2)
            {
                //虚拟驱动固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                //虚拟驱动下载完了之后,下载协调器文件
                this.DownLoadCoordinatorFile();
            }
        }
        #endregion
        #region ■ 虚拟驱动升级_______________________
        /// <summary>
        /// 执行虚拟驱动升级程序
        /// </summary>
        private async void DoUpdateVirtual()
        {
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //开启网关升级虚拟进度线程
            this.StartUpdateVirtualThread();
            //升级中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uLevelUping));
            //如果虚拟驱动不需要升级,则直接跳转下一步
            if (this.virtualFirmware == null)
            {
                //执行协调器升级程序
                this.DoUpdateCoordinator();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.VirtualUpdateReady;
            //升级虚拟驱动的进度
            this.upDatezbGateway.ReportAction += this.UpdateVirtualProgress;
            //虚拟驱动升级
            var result = await this.upDatezbGateway.VirtualDriveUpgradeAsync(this.virtualFirmware.Name, this.virtualFirmware.VirtualCode);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                if ((int)this.UpdateStatu > (int)UpdateStatuMode.VirtualUpdateReady)
                {
                    //虽然你说报错了,但是之后拥有正常操作的话,直接无视这个错误
                    //状态的数值即为操作顺序,状态值大于当前值,即表示可以往下执行
                    return;
                }
                //虚拟驱动升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uVirtualUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualUpdateFail;
            }
        }
        /// <summary>
        /// 升级虚拟驱动的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void UpdateVirtualProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "VirtualDriveUpgrade" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //网关有回应,则超时时间刷新
            this.UpdateTimeOutRefresh();
            //设置进度
            var responData = tempZb.virtualDriveUpgradeResponData;
            if (responData.Flag != 0 && responData.Flag != 2)
            {
                //虚拟驱动升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uVirtualUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualUpdateFail;
            }
            else if (responData.Flag == 0)
            {
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                //虚拟驱动升级完了之后,升级协调器
                this.DoUpdateCoordinator();
            }
            else
            {
                //虚拟驱动升级中
                this.UpdateStatu = UpdateStatuMode.VirtualUpdating;
            }
        }
        #endregion
        #region ■ 协调器下载_________________________
        /// <summary>
        /// 下载协调器文件
        /// </summary>
        private async void DownLoadCoordinatorFile()
        {
            //如果协调器不需要升级,则直接跳转下一步
            if (this.coordinatorFirmware == null)
            {
                //下载网关文件
                this.DownLoadGatewayFile();
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoad;
            //等个1秒
            await Task.Delay(1000);
            //协调器固件下载中
            this.UpdateStatuChangedEvent(0, Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoading));
            this.SetProgressValue(0, 100);
            //下载协调器文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadCoordinatorFileProgress;
            //下载协调器文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.coordinatorFirmware.DistributedMark, this.coordinatorFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //协调器固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoadFail;
                return;
            }
        }
        /// <summary>
        /// 下载协调器文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadCoordinatorFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            this.SetProgressValue(responData.DownloadPercent, 100);
            //协调器固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoading));
            if (responData.Status == 2)
            {
                //协调器固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                //协调器下载完了之后,下载网关文件
                this.DownLoadGatewayFile();
            }
        }
        #endregion
        #region ■ 协调器升级_________________________
        /// <summary>
        /// 执行协调器升级程序
        /// </summary>
        private async void DoUpdateCoordinator()
        {
            //如果协调器不需要升级,则直接跳转下一步
            if (this.coordinatorFirmware == null)
            {
                //执行网关升级程序
                this.DoUpdateGateway();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateReady;
            //升级协调器的进度
            this.upDatezbGateway.ReportAction += this.UpdateCoordinatorProgress;
            //协调器升级
            var result = await this.upDatezbGateway.UpgradeNVAsync(this.coordinatorFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                if ((int)this.UpdateStatu > (int)UpdateStatuMode.CoordinatorUpdateReady)
                {
                    //虽然你说报错了,但是之后拥有正常操作的话,直接无视这个错误
                    //状态的数值即为操作顺序,状态值大于当前值,即表示可以往下执行
                    return;
                }
                //协调器升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uCoordinatorUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateFail;
            }
        }
        /// <summary>
        /// 升级协调器的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void UpdateCoordinatorProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "CordinatorUpgradePercent" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //网关有回应,则超时时间刷新
            this.UpdateTimeOutRefresh();
            //设置进度
            var responData = tempZb.zbGwOperationUpgradeData;
            if (responData.Flag != 0 && responData.Flag != 2)
            {
                //协调器升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uCoordinatorUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateFail;
            }
            else if (responData.Flag == 0)
            {
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                //协调器升级完了之后,升级网关
                this.DoUpdateGateway();
            }
            else
            {
                //协调器升级中
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdating;
            }
        }
        #endregion
        #region ■ 网关下载___________________________
        /// <summary>
        /// 下载网关文件
        /// </summary>
        private async void DownLoadGatewayFile()
        {
            //如果网关不用升级,则直接跳转下一步
            if (this.gatewayFirmware == null)
            {
                //执行虚拟驱动升级程序
                this.DoUpdateVirtual();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.GatewayDownLoad;
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //等个1秒
            await Task.Delay(1000);
            //网关固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoading));
            this.SetProgressValue(0, 100);
            //下载网关文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadGatewayFileProgress;
            //下载网关文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.gatewayFirmware.DistributedMark, this.gatewayFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //网关固件资源下载失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
            }
        }
        /// <summary>
        /// 下载网关文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadGatewayFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            this.SetProgressValue(responData.DownloadPercent, 100);
            if (responData.Status == 2)
            {
                //网关固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                //执行虚拟驱动升级程序
                this.DoUpdateVirtual();
            }
        }
        #endregion
        #region ■ 网关升级___________________________
        /// <summary>
        /// 执行网关升级程序
        /// </summary>
        private async void DoUpdateGateway()
        {
            //如果网关不用升级,则直接跳转下一步
            if (this.gatewayFirmware == null)
            {
                //显示升级完成的信息
                this.ShowFinishMsg();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.GatewayUpdateReady;
            //网关升级
            var result = await this.upDatezbGateway.LinuxUpgradeAsync(this.gatewayFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorMessageBase.Contains("回复超时") == true)
                {
                    //网关升级的时候,有可能它不再回什么信息
                    return;
                }
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //网关升级失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGatewayUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.UpdateStatu = UpdateStatuMode.GatewayUpdateFail;
                return;
            }
            //网关升级中
            this.UpdateStatu = UpdateStatuMode.GatewayUpdating;
            //开启获取网关版本的线程
            this.StartGetGatewayVersionThread();
        }
        #endregion
        #region ■ 升级完成提示_______________________
        /// <summary>
        /// 显示升级完成的信息
        /// </summary>
        private void ShowFinishMsg()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //状态变更
                this.IsFinishUpdate = true;
                System.Threading.Thread.Sleep(2000);
                //设置没有网关正在升级的标识
                HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
                this.UpdateStatu = UpdateStatuMode.UpdateSuccess;
                //执行下一个升级
                HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
                //网关升级成功!
                this.SetProgressValue(100, 100);
                System.Threading.Thread.Sleep(1500);
                this.UpdateStatuChangedEvent?.Invoke(1, Language.StringByID(R.MyInternationalizationString.uGatewayUpdateSuccess));
            });
        }
        #endregion
        #region ■ 处理结果提示_______________________
        /// <summary>
        /// 显示重新安装的信息
        /// </summary>
        private void ShowReSetupMsg()
        {
            //状态变更
            this.IsFinishUpdate = true;
            //设置没有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
            //执行下一个升级
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        /// <summary>
        /// 显示重新下载模式
        /// </summary>
        private void ShowReDownLoadMode()
        {
            //状态变更
            this.IsFinishUpdate = true;
            //设置没有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
            //执行下一个升级
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        #endregion
        #region ■ 设置进度___________________________
        /// <summary>
        /// 设定进度值
        /// </summary>
        /// <param name="value">进度值</param>
        /// <param name="maxValue">最大值</param>
        private void SetProgressValue(decimal value, decimal maxValue)
        {
            if (value > maxValue)
            {
                //有时候会瞎发什么鬼过来
                return;
            }
            decimal result = value / maxValue;
            this.ProgressEvent?.Invoke(result);
        }
        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="value"></param>
        private void ShowErrorMsg(string value)
        {
            this.UpdateStatuChangedEvent?.Invoke(-1, value);
        }
        #endregion
        #region ■ 网关下载超时线程___________________
        /// <summary>
        /// 超时时间设置
        /// </summary>
        private int downLoadTimeOutCount = 30;
        /// <summary>
        /// 开启网关下载超时线程
        /// </summary>
        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.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                        this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                        this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                        //响应超时,升级失败
                        string msg = Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail);
                        //从头再来
                        this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
                        //显示重新下载模式
                        this.ShowReDownLoadMode();
                        //设置错误信息
                        this.ShowErrorMsg(msg);
                        break;
                    }
                }
            });
        }
        /// <summary>
        /// 超时时间刷新
        /// </summary>
        private void DownLoadTimeOutRefresh()
        {
            this.downLoadTimeOutCount = 30;
        }
        #endregion
        #region ■ 网关升级虚拟进度线程_______________
        /// <summary>
        /// 超时时间设置
        /// </summary>
        private int updateTimeOutCount = 60;
        /// <summary>
        /// 开启网关升级虚拟进度线程
        /// </summary>
        private void StartUpdateVirtualThread()
        {
            //获取升级的大致总共时间
            int timeCount = this.GetUpdateTimeCount();
            //网关升级中,剩余时间大约为:
            string msg = Language.StringByID(R.MyInternationalizationString.uGatewaiUpdatingAndRemainingTimeMsg);
            //当前用时
            int nowTimeCount = 0;
            //超时时间设置
            this.updateTimeOutCount = 60;
            HdlThreadLogic.Current.RunThread(() =>
            {
                while (this.IsFinishUpdate == false)
                {
                    System.Threading.Thread.Sleep(1000);
                    nowTimeCount++;
                    //超时
                    updateTimeOutCount--;
                    if (updateTimeOutCount == 0)
                    {
                        //响应超时,升级失败
                        this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail));
                        //从头再来
                        this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
                        //显示重新下载模式
                        this.ShowReDownLoadMode();
                        break;
                    }
                    //剩余时间
                    int remainingTime = timeCount - nowTimeCount;
                    if (remainingTime <= -1)
                    {
                        //时间用完了,直接显示成功
                        this.IsFinishUpdate = true;
                        break;
                    }
                    //设置进度值
                    this.UpdateStatuChangedEvent?.Invoke(0, msg + remainingTime + "s");
                    this.SetProgressValue(nowTimeCount, timeCount);
                }
            });
        }
        /// <summary>
        /// 获取升级的大致总共时间
        /// </summary>
        /// <returns></returns>
        private int GetUpdateTimeCount()
        {
            int timeCount = 0;
            if (this.virtualFirmware != null)
            {
                //虚拟驱动升级
                timeCount += 20;
            }
            if (this.coordinatorFirmware != null)
            {
                //协调器升级
                timeCount += 120;
            }
            if (this.gatewayFirmware != null)
            {
                //网关升级
                timeCount += 50;
                //网关重启
                timeCount += 250;
            }
            return timeCount;
        }
        /// <summary>
        /// 超时时间刷新
        /// </summary>
        private void UpdateTimeOutRefresh()
        {
            this.updateTimeOutCount = 60;
        }
        #endregion
        #region ■ 开启获取网关版本的线程_____________
        /// <summary>
        /// 开启获取网关版本的线程
        /// </summary>
        /// <returns></returns>
        private void StartGetGatewayVersionThread()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //先等个120秒吧,网关升级和网关完全重启需要很长时间
                int count = 12;
                for (int i = 0; i < count; i++)
                {
                    if (this.IsFinishUpdate == true)
                    {
                        //升级完了,因为有错误
                        break;
                    }
                    //这个时候,不应该提示超时
                    this.UpdateTimeOutRefresh();
                    System.Threading.Thread.Sleep(10000);
                }
                while (this.IsFinishUpdate == false)
                {
                    //获取版本
                    var result = HdlGatewayLogic.Current.GetGatewayInfo(this.upDatezbGateway, false, ShowErrorMode.NO);
                    if (result != null)
                    {
                        break;
                    }
                    //这个时候,不应该提示超时
                    this.UpdateTimeOutRefresh();
                    System.Threading.Thread.Sleep(5000);
                }
                //已经能够获取数据
                this.ShowFinishMsg();
            });
        }
        #endregion
        #region ■ 释放缓存___________________________
        /// <summary>
        /// 释放缓存
        /// </summary>
        public override void Dispose()
        {
            this.ProgressEvent = null;
            this.UpdateStatuChangedEvent = null;
        }
        #endregion
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 网关的升级逻辑
    /// </summary>
    public class HdlGatewayUpdateLogic : HdlDeviceUpdateCommonLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// <para>更新状态变化的事件</para>
        /// <para>第一个参数为:</para>
        /// <para>-1:更新异常,后面的值为异常信息的翻译文本</para>
        /// <para> 0:更新状态正常变化,后面的值为状态变更的文本翻译</para>
        /// <para> 1:升级成功</para>
        /// <para> 3:从等待中取消(目前还没有用)</para>
        /// </summary>
        public Action<int, string> UpdateStatuChangedEvent = null;
        /// <summary>
        /// 进度值事件(已经是百分比的值)
        /// </summary>
        public Action<decimal> ProgressEvent = null;
        /// <summary>
        /// 虚拟设备的固件信息
        /// </summary>
        public FirmwareVersionInfo virtualFirmware = null;
        /// <summary>
        /// 协调器新版本的固件信息
        /// </summary>
        public FirmwareVersionInfo coordinatorFirmware = null;
        /// <summary>
        /// 网关新版本的固件信息
        /// </summary>
        public FirmwareVersionInfo gatewayFirmware = null;
        /// <summary>
        /// 前一次的最终状态
        /// </summary>
        private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None;
        /// <summary>
        /// 要升级的网关
        /// </summary>
        private ZbGateway upDatezbGateway = null;
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 网关升级控件
        /// </summary>
        /// <param name="listView">列表控件</param>
        /// <param name="zbGateway">网关</param>
        /// <param name="i_virtualFirmware">虚拟设备的固件信息</param>
        /// <param name="i_coordinatorFirmware">协调器新版本的固件信息</param>
        /// <param name="i_gatewayFirmware">网关新版本的固件信息</param>
        public HdlGatewayUpdateLogic(ZbGateway zbGateway, FirmwareVersionInfo i_virtualFirmware,
            FirmwareVersionInfo i_coordinatorFirmware, FirmwareVersionInfo i_gatewayFirmware)
        {
            this.ClassDiv = 1;
            this.upDatezbGateway = zbGateway;
            this.virtualFirmware = i_virtualFirmware;
            this.coordinatorFirmware = i_coordinatorFirmware;
            this.gatewayFirmware = i_gatewayFirmware;
        }
        #endregion
        #region ■ 开始更新___________________________
        /// <summary>
        /// 进入执行更新操作准备阶段
        /// </summary>
        public void StartUpdateReady()
        {
            if (this.UpdateStatu == UpdateStatuMode.Wait)
            {
                //如果是等待模式,再次点击时,移除列表
                string gwId = this.upDatezbGateway.GwId;
                if (FirmwareUpdateResourse.dicUpdateList.ContainsKey(gwId) == true)
                {
                    FirmwareUpdateResourse.dicUpdateList.Remove(gwId);
                }
                this.UpdateStatu = UpdateStatuMode.None;
                //取消
                this.UpdateStatuChangedEvent?.Invoke(3, "");
                return;
            }
            //如果它有状态,则表示之前它被什么错误中断了
            if (this.UpdateStatu != UpdateStatuMode.None)
            {
                //保存起来,后面有用处
                this.oldUpdateStatu = this.UpdateStatu;
            }
            //进入等待模式
            this.UpdateStatu = UpdateStatuMode.Wait;
            string gwId2 = this.upDatezbGateway.GwId;
            FirmwareUpdateResourse.dicUpdateList[gwId2] = this;
            //等待中…
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uWaitting));
            //执行下一个可更新的固件的更新操作
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        /// <summary>
        /// 开始执行更新操作(FirmwareUpdateLogic调用)
        /// </summary>
        public override void DoStartUpdate()
        {
            //状态变更
            this.IsFinishUpdate = false;
            this.UpdateStatu = UpdateStatuMode.Action;
            //设置拥有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(true);
            //根据状态执行操作
            this.DoAdjustByStatuMode();
        }
        /// <summary>
        /// 根据状态执行操作
        /// </summary>
        private void DoAdjustByStatuMode()
        {
            //首发时,从开始执行
            if (this.oldUpdateStatu == UpdateStatuMode.None)
            {
                //下载虚拟驱动文件
                this.DownLoadVirtualFile();
            }
            //虚拟驱动下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.VirtualDownLoadFail)
            {
                //下载虚拟驱动文件
                this.DownLoadVirtualFile();
            }
            //虚拟驱动更新失败
            else if (this.oldUpdateStatu == UpdateStatuMode.VirtualUpdateFail)
            {
                //执行虚拟驱动更新
                this.DoUpdateVirtual();
            }
            //协调器下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.CoordinatorDownLoadFail)
            {
                //下载虚拟驱动文件(从头再来)
                this.DownLoadVirtualFile();
            }
            //协调器升级失败
            else if (this.oldUpdateStatu == UpdateStatuMode.CoordinatorUpdateFail)
            {
                //执行虚拟驱动更新(从头再来)
                this.DoUpdateVirtual();
            }
            //网关下载失败
            else if (this.oldUpdateStatu == UpdateStatuMode.GatewayDownLoadFail)
            {
                //下载虚拟驱动文件(从头再来)
                this.DownLoadVirtualFile();
            }
            //网关升级失败
            else if (this.oldUpdateStatu == UpdateStatuMode.GatewayUpdateFail)
            {
                //执行虚拟驱动更新(从头再来)
                this.DoUpdateVirtual();
            }
            else
            {
                //重新再来
                this.DownLoadVirtualFile();
            }
        }
        #endregion
        #region ■ 虚拟驱动下载_______________________
        /// <summary>
        /// 下载虚拟驱动文件
        /// </summary>
        private async void DownLoadVirtualFile()
        {
            //开启网关下载超时线程
            this.StartDownLoadTimeOutThread();
            //如果虚拟驱动不需要升级,则直接跳转下一步
            if (this.virtualFirmware == null)
            {
                //下载协调器文件
                this.DownLoadCoordinatorFile();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.VirtualDownLoad;
            //虚拟驱动固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoading));
            //下载虚拟驱动文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadVirtualFileProgress;
            //下载虚拟驱动文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.virtualFirmware.DistributedMark, this.virtualFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //虚拟驱动固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualDownLoadFail;
                return;
            }
        }
        /// <summary>
        /// 下载虚拟驱动文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadVirtualFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            //虚拟驱动固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoading));
            if (responData.Status == 2)
            {
                //虚拟驱动固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVirtualFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                //虚拟驱动下载完了之后,下载协调器文件
                this.DownLoadCoordinatorFile();
            }
        }
        #endregion
        #region ■ 虚拟驱动升级_______________________
        /// <summary>
        /// 执行虚拟驱动升级程序
        /// </summary>
        private async void DoUpdateVirtual()
        {
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //开启网关升级虚拟进度线程
            this.StartUpdateVirtualThread();
            //升级中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uLevelUping));
            //如果虚拟驱动不需要升级,则直接跳转下一步
            if (this.virtualFirmware == null)
            {
                //执行协调器升级程序
                this.DoUpdateCoordinator();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.VirtualUpdateReady;
            //升级虚拟驱动的进度
            this.upDatezbGateway.ReportAction += this.UpdateVirtualProgress;
            //虚拟驱动升级
            var result = await this.upDatezbGateway.VirtualDriveUpgradeAsync(this.virtualFirmware.Name, this.virtualFirmware.VirtualCode);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                if ((int)this.UpdateStatu > (int)UpdateStatuMode.VirtualUpdateReady)
                {
                    //虽然你说报错了,但是之后拥有正常操作的话,直接无视这个错误
                    //状态的数值即为操作顺序,状态值大于当前值,即表示可以往下执行
                    return;
                }
                //虚拟驱动升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uVirtualUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualUpdateFail;
            }
        }
        /// <summary>
        /// 升级虚拟驱动的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void UpdateVirtualProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "VirtualDriveUpgrade" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //网关有回应,则超时时间刷新
            this.UpdateTimeOutRefresh();
            //设置进度
            var responData = tempZb.virtualDriveUpgradeResponData;
            if (responData.Flag != 0 && responData.Flag != 2)
            {
                //虚拟驱动升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uVirtualUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                this.UpdateStatu = UpdateStatuMode.VirtualUpdateFail;
            }
            else if (responData.Flag == 0)
            {
                this.upDatezbGateway.ReportAction -= this.UpdateVirtualProgress;
                //虚拟驱动升级完了之后,升级协调器
                this.DoUpdateCoordinator();
            }
            else
            {
                //虚拟驱动升级中
                this.UpdateStatu = UpdateStatuMode.VirtualUpdating;
            }
        }
        #endregion
        #region ■ 协调器下载_________________________
        /// <summary>
        /// 下载协调器文件
        /// </summary>
        private async void DownLoadCoordinatorFile()
        {
            //如果协调器不需要升级,则直接跳转下一步
            if (this.coordinatorFirmware == null)
            {
                //下载网关文件
                this.DownLoadGatewayFile();
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoad;
            //等个1秒
            await Task.Delay(1000);
            //协调器固件下载中
            this.UpdateStatuChangedEvent(0, Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoading));
            this.SetProgressValue(0, 100);
            //下载协调器文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadCoordinatorFileProgress;
            //下载协调器文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.coordinatorFirmware.DistributedMark, this.coordinatorFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //协调器固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoadFail;
                return;
            }
        }
        /// <summary>
        /// 下载协调器文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadCoordinatorFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            this.SetProgressValue(responData.DownloadPercent, 100);
            //协调器固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoading));
            if (responData.Status == 2)
            {
                //协调器固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCoordinatorFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                //协调器下载完了之后,下载网关文件
                this.DownLoadGatewayFile();
            }
        }
        #endregion
        #region ■ 协调器升级_________________________
        /// <summary>
        /// 执行协调器升级程序
        /// </summary>
        private async void DoUpdateCoordinator()
        {
            //如果协调器不需要升级,则直接跳转下一步
            if (this.coordinatorFirmware == null)
            {
                //执行网关升级程序
                this.DoUpdateGateway();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateReady;
            //升级协调器的进度
            this.upDatezbGateway.ReportAction += this.UpdateCoordinatorProgress;
            //协调器升级
            var result = await this.upDatezbGateway.UpgradeNVAsync(this.coordinatorFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                if ((int)this.UpdateStatu > (int)UpdateStatuMode.CoordinatorUpdateReady)
                {
                    //虽然你说报错了,但是之后拥有正常操作的话,直接无视这个错误
                    //状态的数值即为操作顺序,状态值大于当前值,即表示可以往下执行
                    return;
                }
                //协调器升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uCoordinatorUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateFail;
            }
        }
        /// <summary>
        /// 升级协调器的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void UpdateCoordinatorProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "CordinatorUpgradePercent" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //网关有回应,则超时时间刷新
            this.UpdateTimeOutRefresh();
            //设置进度
            var responData = tempZb.zbGwOperationUpgradeData;
            if (responData.Flag != 0 && responData.Flag != 2)
            {
                //协调器升级失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uCoordinatorUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdateFail;
            }
            else if (responData.Flag == 0)
            {
                this.upDatezbGateway.ReportAction -= this.UpdateCoordinatorProgress;
                //协调器升级完了之后,升级网关
                this.DoUpdateGateway();
            }
            else
            {
                //协调器升级中
                this.UpdateStatu = UpdateStatuMode.CoordinatorUpdating;
            }
        }
        #endregion
        #region ■ 网关下载___________________________
        /// <summary>
        /// 下载网关文件
        /// </summary>
        private async void DownLoadGatewayFile()
        {
            //如果网关不用升级,则直接跳转下一步
            if (this.gatewayFirmware == null)
            {
                //执行虚拟驱动升级程序
                this.DoUpdateVirtual();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.GatewayDownLoad;
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //等个1秒
            await Task.Delay(1000);
            //网关固件下载中
            this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoading));
            this.SetProgressValue(0, 100);
            //下载网关文件的进度
            this.upDatezbGateway.ReportAction += this.DownLoadGatewayFileProgress;
            //下载网关文件
            var result = await this.upDatezbGateway.DownloadFileAsync(this.gatewayFirmware.DistributedMark, this.gatewayFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //网关固件资源下载失败
                this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
            }
        }
        /// <summary>
        /// 下载网关文件的进度
        /// </summary>
        /// <param name="CommadDiv"></param>
        /// <param name="objValue"></param>
        private void DownLoadGatewayFileProgress(string CommadDiv, object objValue)
        {
            if (CommadDiv != "DownloadFileProgress" || objValue == null)
            {
                return;
            }
            var tempZb = (ZbGateway)objValue;
            if (tempZb.GwId != this.upDatezbGateway.GwId)
            {
                //不是自己的网关推送,则不处理
                return;
            }
            //刷新超时时间
            this.DownLoadTimeOutRefresh();
            //设置进度
            var responData = tempZb.downloadFileProgressResponData;
            this.SetProgressValue(responData.DownloadPercent, 100);
            if (responData.Status == 2)
            {
                //网关固件资源下载失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGatewayFirmwareDownLoadFail));
                //显示重新下载模式
                this.ShowReDownLoadMode();
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
            }
            else if (responData.Status == 0)
            {
                this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                //执行虚拟驱动升级程序
                this.DoUpdateVirtual();
            }
        }
        #endregion
        #region ■ 网关升级___________________________
        /// <summary>
        /// 执行网关升级程序
        /// </summary>
        private async void DoUpdateGateway()
        {
            //如果网关不用升级,则直接跳转下一步
            if (this.gatewayFirmware == null)
            {
                //显示升级完成的信息
                this.ShowFinishMsg();
                return;
            }
            this.UpdateStatu = UpdateStatuMode.GatewayUpdateReady;
            //网关升级
            var result = await this.upDatezbGateway.LinuxUpgradeAsync(this.gatewayFirmware.Name);
            if (string.IsNullOrEmpty(result.errorMessageBase) == false)
            {
                if (result.errorMessageBase.Contains("回复超时") == true)
                {
                    //网关升级的时候,有可能它不再回什么信息
                    return;
                }
                if (result.errorResponData != null && result.errorResponData.Error == 2)
                {
                    //因为tcp底层在网络不好的时候,有可能会重发多次,所以这里忽略掉【协调器正在升级或备份/恢复数据】的错误
                    return;
                }
                //网关升级失败
                this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGatewayUpdatingFail));
                //显示重新安装
                this.ShowReSetupMsg();
                this.UpdateStatu = UpdateStatuMode.GatewayUpdateFail;
                return;
            }
            //网关升级中
            this.UpdateStatu = UpdateStatuMode.GatewayUpdating;
            //开启获取网关版本的线程
            this.StartGetGatewayVersionThread();
        }
        #endregion
        #region ■ 升级完成提示_______________________
        /// <summary>
        /// 显示升级完成的信息
        /// </summary>
        private void ShowFinishMsg()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //状态变更
                this.IsFinishUpdate = true;
                System.Threading.Thread.Sleep(2000);
                //设置没有网关正在升级的标识
                HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
                this.UpdateStatu = UpdateStatuMode.UpdateSuccess;
                //执行下一个升级
                HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
                //网关升级成功!
                this.SetProgressValue(100, 100);
                System.Threading.Thread.Sleep(1500);
                this.UpdateStatuChangedEvent?.Invoke(1, Language.StringByID(R.MyInternationalizationString.uGatewayUpdateSuccess));
            });
        }
        #endregion
        #region ■ 处理结果提示_______________________
        /// <summary>
        /// 显示重新安装的信息
        /// </summary>
        private void ShowReSetupMsg()
        {
            //状态变更
            this.IsFinishUpdate = true;
            //设置没有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
            //执行下一个升级
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        /// <summary>
        /// 显示重新下载模式
        /// </summary>
        private void ShowReDownLoadMode()
        {
            //状态变更
            this.IsFinishUpdate = true;
            //设置没有网关正在升级的标识
            HdlGatewayLogic.Current.SetHadGatewayUpdateFlage(false);
            //执行下一个升级
            HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
        }
        #endregion
        #region ■ 设置进度___________________________
        /// <summary>
        /// 设定进度值
        /// </summary>
        /// <param name="value">进度值</param>
        /// <param name="maxValue">最大值</param>
        private void SetProgressValue(decimal value, decimal maxValue)
        {
            if (value > maxValue)
            {
                //有时候会瞎发什么鬼过来
                return;
            }
            decimal result = value / maxValue;
            this.ProgressEvent?.Invoke(result);
        }
        /// <summary>
        /// 设置错误信息
        /// </summary>
        /// <param name="value"></param>
        private void ShowErrorMsg(string value)
        {
            this.UpdateStatuChangedEvent?.Invoke(-1, value);
        }
        #endregion
        #region ■ 网关下载超时线程___________________
        /// <summary>
        /// 超时时间设置
        /// </summary>
        private int downLoadTimeOutCount = 30;
        /// <summary>
        /// 开启网关下载超时线程
        /// </summary>
        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.upDatezbGateway.ReportAction -= this.DownLoadVirtualFileProgress;
                        this.upDatezbGateway.ReportAction -= this.DownLoadCoordinatorFileProgress;
                        this.upDatezbGateway.ReportAction -= this.DownLoadGatewayFileProgress;
                        //响应超时,升级失败
                        string msg = Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail);
                        //从头再来
                        this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
                        //显示重新下载模式
                        this.ShowReDownLoadMode();
                        //设置错误信息
                        this.ShowErrorMsg(msg);
                        break;
                    }
                }
            });
        }
        /// <summary>
        /// 超时时间刷新
        /// </summary>
        private void DownLoadTimeOutRefresh()
        {
            this.downLoadTimeOutCount = 30;
        }
        #endregion
        #region ■ 网关升级虚拟进度线程_______________
        /// <summary>
        /// 超时时间设置
        /// </summary>
        private int updateTimeOutCount = 60;
        /// <summary>
        /// 开启网关升级虚拟进度线程
        /// </summary>
        private void StartUpdateVirtualThread()
        {
            //获取升级的大致总共时间
            int timeCount = this.GetUpdateTimeCount();
            //网关升级中,剩余时间大约为:
            string msg = Language.StringByID(R.MyInternationalizationString.uGatewaiUpdatingAndRemainingTimeMsg);
            //当前用时
            int nowTimeCount = 0;
            //超时时间设置
            this.updateTimeOutCount = 60;
            HdlThreadLogic.Current.RunThread(() =>
            {
                while (this.IsFinishUpdate == false)
                {
                    System.Threading.Thread.Sleep(1000);
                    nowTimeCount++;
                    //超时
                    updateTimeOutCount--;
                    if (updateTimeOutCount == 0)
                    {
                        //响应超时,升级失败
                        this.UpdateStatuChangedEvent?.Invoke(-1, Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail));
                        //从头再来
                        this.UpdateStatu = UpdateStatuMode.GatewayDownLoadFail;
                        //显示重新下载模式
                        this.ShowReDownLoadMode();
                        break;
                    }
                    //剩余时间
                    int remainingTime = timeCount - nowTimeCount;
                    if (remainingTime <= -1)
                    {
                        //时间用完了,直接显示成功
                        this.IsFinishUpdate = true;
                        break;
                    }
                    //设置进度值
                    this.UpdateStatuChangedEvent?.Invoke(0, msg + remainingTime + "s");
                    this.SetProgressValue(nowTimeCount, timeCount);
                }
            });
        }
        /// <summary>
        /// 获取升级的大致总共时间
        /// </summary>
        /// <returns></returns>
        private int GetUpdateTimeCount()
        {
            int timeCount = 0;
            if (this.virtualFirmware != null)
            {
                //虚拟驱动升级
                timeCount += 20;
            }
            if (this.coordinatorFirmware != null)
            {
                //协调器升级
                timeCount += 120;
            }
            if (this.gatewayFirmware != null)
            {
                //网关升级
                timeCount += 50;
                //网关重启
                timeCount += 250;
            }
            return timeCount;
        }
        /// <summary>
        /// 超时时间刷新
        /// </summary>
        private void UpdateTimeOutRefresh()
        {
            this.updateTimeOutCount = 60;
        }
        #endregion
        #region ■ 开启获取网关版本的线程_____________
        /// <summary>
        /// 开启获取网关版本的线程
        /// </summary>
        /// <returns></returns>
        private void StartGetGatewayVersionThread()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //先等个120秒吧,网关升级和网关完全重启需要很长时间
                int count = 12;
                for (int i = 0; i < count; i++)
                {
                    if (this.IsFinishUpdate == true)
                    {
                        //升级完了,因为有错误
                        break;
                    }
                    //这个时候,不应该提示超时
                    this.UpdateTimeOutRefresh();
                    System.Threading.Thread.Sleep(10000);
                }
                while (this.IsFinishUpdate == false)
                {
                    //获取版本
                    var result = HdlGatewayLogic.Current.GetGatewayInfo(this.upDatezbGateway, false, ShowErrorMode.NO);
                    if (result != null)
                    {
                        break;
                    }
                    //这个时候,不应该提示超时
                    this.UpdateTimeOutRefresh();
                    System.Threading.Thread.Sleep(5000);
                }
                //已经能够获取数据
                this.ShowFinishMsg();
            });
        }
        #endregion
        #region ■ 释放缓存___________________________
        /// <summary>
        /// 释放缓存
        /// </summary>
        public override void Dispose()
        {
            this.ProgressEvent = null;
            this.UpdateStatuChangedEvent = null;
        }
        #endregion
    }
}