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
}
}