old mode 100755
new mode 100644
| | |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Text;
|
| | | using ZigBee.Device;
|
| | |
|
| | | namespace Shared.Phone.UserCenter
|
| | | {
|
| | | /// <summary>
|
| | | /// 中央空调的升级逻辑
|
| | | /// </summary>
|
| | | public class HdlACZbGatewayUpdateLogic : HdlDeviceUpdateCommonLogic
|
| | | {
|
| | | #region ■ 变量声明___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// <para>更新状态变化的事件</para>
|
| | | /// <para>第一个参数为:</para>
|
| | | /// <para>-1:更新异常,后面的值为异常信息的翻译文本</para>
|
| | | /// <para> 0:更新状态正常变化,后面的值为状态变更的文本翻译</para>
|
| | | /// <para> 1:升级成功</para>
|
| | | /// <para> 2:主动终止升级(中央空调木允许终止)</para>
|
| | | /// <para> 3:从等待中取消(目前还没有用)</para>
|
| | | /// </summary>
|
| | | public Action<int, string> UpdateStatuChangedEvent = null;
|
| | | /// <summary>
|
| | | /// 进度值事件
|
| | | /// </summary>
|
| | | public Action<decimal> ProgressEvent = null;
|
| | | /// <summary>
|
| | | /// 设备新版本的固件信息(多个设备升级时,应该会需要公开这个对象)
|
| | | /// </summary>
|
| | | public FirmwareVersionInfo deviceFirmware = null;
|
| | | /// <summary>
|
| | | /// 网关
|
| | | /// </summary>
|
| | | private ZbGateway zbGateway = null;
|
| | | /// <summary>
|
| | | /// 升级的设备
|
| | | /// </summary>
|
| | | private OTADevice otaDevice = null;
|
| | | /// <summary>
|
| | | /// 设备对象
|
| | | /// </summary>
|
| | | private AC deviceAc = null;
|
| | | /// <summary>
|
| | | /// 前一次的最终状态
|
| | | /// </summary>
|
| | | private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None;
|
| | | /// <summary>
|
| | | /// 固件的byte数组
|
| | | /// </summary>
|
| | | private byte[] deviceFirmwareByte = null;
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 初始化_____________________________
|
| | |
|
| | | /// <summary>
|
| | | /// <para>HDL设备升级,以下为两个重要事件</para>
|
| | | /// <para>UpdateStatuChangedEvent:更新状态变化的事件</para>
|
| | | /// <para>ProgressEvent:进度值事件</para>
|
| | | /// <para>StartUpdateReady():设备开始执行升级的函数,在调用这个之前,请先实现上面两个方法</para>
|
| | | /// </summary>
|
| | | /// <param name="i_deviceAc">设备</param>
|
| | | /// <param name="i_deviceFirmware">设备的固件信息</param>
|
| | | public HdlACZbGatewayUpdateLogic(AC i_deviceAc, FirmwareVersionInfo i_deviceFirmware)
|
| | | {
|
| | | this.ClassDiv = 2;
|
| | | this.deviceAc = i_deviceAc;
|
| | | this.otaDevice = Common.LocalDevice.Current.GetOTADevice(i_deviceAc.DeviceAddr);
|
| | | this.deviceFirmware = i_deviceFirmware;
|
| | | this.zbGateway = i_deviceAc.Gateway;
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 开始更新___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// 进入执行更新操作准备阶段
|
| | | /// </summary>
|
| | | public void StartUpdateReady()
|
| | | {
|
| | | 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();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 开始执行更新操作
|
| | | /// </summary>
|
| | | public override void DoStartUpdate()
|
| | | {
|
| | | //状态变更
|
| | | this.IsFinishUpdate = false;
|
| | | this.UpdateStatu = UpdateStatuMode.Action;
|
| | | //根据状态执行操作
|
| | | this.DoAdjustByStatuMode();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 根据状态执行操作
|
| | | /// </summary>
|
| | | private void DoAdjustByStatuMode()
|
| | | {
|
| | | //先这样写吧,有可能以后会分情况
|
| | | //首发时,从开始执行
|
| | | if (this.oldUpdateStatu == UpdateStatuMode.None)
|
| | | {
|
| | | //执行校验版本
|
| | | this.DoCheckVersion();
|
| | | }
|
| | | //设备下载失败
|
| | | else if (this.oldUpdateStatu == UpdateStatuMode.DeviceDownLoadFail)
|
| | | {
|
| | | //执行校验版本
|
| | | this.DoCheckVersion();
|
| | | }
|
| | | //设备升级失败
|
| | | else if (this.oldUpdateStatu == UpdateStatuMode.DeviceUpdateFail)
|
| | | {
|
| | | //执行校验版本
|
| | | this.DoCheckVersion();
|
| | | }
|
| | | else
|
| | | {
|
| | | //重新再来
|
| | | this.DoCheckVersion();
|
| | | }
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 校验版本___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// 校验版本
|
| | | /// </summary>
|
| | | private async void DoCheckVersion()
|
| | | {
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady;
|
| | | //检测设备版本
|
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uCheckDeviceVersion));
|
| | | //设置初始值
|
| | | this.SetProgressValue(0, 100);
|
| | |
|
| | | await System.Threading.Tasks.Task.Delay(1000);
|
| | |
|
| | | //下载固件资源
|
| | | var pra = new { RequestVersion = Common.CommonPage.RequestVersion, DistributedMark = this.deviceFirmware.DistributedMark };
|
| | | this.deviceFirmwareByte = await Common.CommonPage.Instance.RequestHttpsZigbeeBytesResultAsync("FirmwareMana/DownloadPlatformUploadFirmware", Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(pra)));
|
| | | if (this.deviceFirmwareByte == null)
|
| | | {
|
| | | //设备固件资源下载失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoadFail));
|
| | |
|
| | | //显示重新下载模式
|
| | | this.ShowReDownLoadMode();
|
| | |
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail;
|
| | | return;
|
| | | }
|
| | |
|
| | | //数据偏移量,每个分包偏移量+(1-43)
|
| | | string offset = string.Empty;
|
| | | //一次发送的数据长度
|
| | | int dataLength = -1;
|
| | | //接收网关的透传数据
|
| | | Action<string, object> receiveAction = (comand, pushData) =>
|
| | | {
|
| | | string receiveData = ((CommonDevice.ClientDataPassthroughResponseData)pushData).PassData;
|
| | | if (receiveData.Length < 6)
|
| | | {
|
| | | return;
|
| | | }
|
| | | try
|
| | | {
|
| | | var command = receiveData[4].ToString() + receiveData[5].ToString() + receiveData[2].ToString() + receiveData[3].ToString();
|
| | | if (command == "025c")
|
| | | {
|
| | | offset = receiveData.Substring(10, 8);
|
| | | dataLength = Convert.ToInt32(receiveData.Substring(18, 2), 16);
|
| | | }
|
| | | }
|
| | | catch { }
|
| | | };
|
| | | this.zbGateway.ReportAction += receiveAction;
|
| | |
|
| | | //读取空调模块版本
|
| | | var result = await HdlDeviceAirConditionerLogic.Current.ReadACFirewareVersionAsync(deviceAc);
|
| | | if (result == null || result.readACFirewareVersionResponData == null || result.readACFirewareVersionResponData.Status != 0)
|
| | | {
|
| | | //获取空调模块版本失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGetAirConditionerModelVersionFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | | //发送升级通知
|
| | | var result2 = await HdlDeviceAirConditionerLogic.Current.UpggradeACNotificationAsync(deviceAc, result.readACFirewareVersionResponData.FirewareVersion, this.deviceFirmwareByte.Length);
|
| | | if (result2.responseData == null)
|
| | | {
|
| | | //发送升级命令失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uSendUpdateComandFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | | else if (result2.responseData.status == 1)
|
| | | {
|
| | | //版本号相同,升级失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVersionIsEqualAndUpdateFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | | else if (result2.responseData.status != 0)
|
| | | {
|
| | | //校验版本号失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCheckVersionFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | |
|
| | | int timeOut = 0;
|
| | | //等待接收偏移量
|
| | | while (dataLength == -1)
|
| | | {
|
| | | timeOut++;
|
| | | if (timeOut >= 30)
|
| | | {
|
| | | //响应超时,检测设备版本失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndCheckDeviceVersionFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | | await System.Threading.Tasks.Task.Delay(1000);
|
| | | //设置进度值
|
| | | this.SetProgressValue(timeOut, 30);
|
| | | }
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | |
|
| | | //执行设备升级操作
|
| | | this.DoSetUpdateDevice(offset, dataLength);
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 设备升级___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// 执行设备升级操作
|
| | | /// </summary>
|
| | | private async void DoSetUpdateDevice(string i_offset, int i_dataLength)
|
| | | {
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady;
|
| | | //设备正在升级…
|
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uDeviceUpdating));
|
| | | //设置初始值
|
| | | this.SetProgressValue(0, 100);
|
| | |
|
| | | await System.Threading.Tasks.Task.Delay(1000);
|
| | |
|
| | | //发送数据的索引
|
| | | int startIndex = 0;
|
| | | int allDataLength = this.deviceFirmwareByte.Length;
|
| | | int timeOut = 0;
|
| | | //是否接收到成功命令
|
| | | bool receiveSuccess = false;
|
| | |
|
| | | //接收网关的透传数据
|
| | | bool hadReceive = true;
|
| | | Action<string, object> receiveAction = (comand, pushData) =>
|
| | | {
|
| | | if (comand != "DeviceRequestAcUpdateData")
|
| | | {
|
| | | return;
|
| | | }
|
| | | string receiveData = ((CommonDevice.ClientDataPassthroughResponseData)pushData).PassData;
|
| | | if (receiveData.Length < 6)
|
| | | {
|
| | | return;
|
| | | }
|
| | | try
|
| | | {
|
| | | var command = receiveData[4].ToString() + receiveData[5].ToString() + receiveData[2].ToString() + receiveData[3].ToString();
|
| | | if (command == "025c")
|
| | | {
|
| | | i_offset = receiveData.Substring(10, 8);
|
| | | i_dataLength = Convert.ToInt32(receiveData.Substring(18, 2), 16);
|
| | | hadReceive = true;
|
| | | timeOut = 0;
|
| | | //设置进度值
|
| | | this.SetProgressValue(startIndex, allDataLength);
|
| | | }
|
| | | else if (command == "025e")
|
| | | {
|
| | | //成功 设置进度值直接100%
|
| | | this.SetProgressValue(allDataLength, allDataLength);
|
| | | receiveSuccess = true;
|
| | | timeOut = 0;
|
| | | }
|
| | | }
|
| | | catch { }
|
| | | };
|
| | | this.zbGateway.ReportAction += receiveAction;
|
| | |
|
| | | //最后一次需要等待回复结果才往下走
|
| | | while (startIndex < allDataLength)
|
| | | {
|
| | | if (receiveSuccess == true)
|
| | | {
|
| | | //已经接收到成功的命令
|
| | | break;
|
| | | }
|
| | | if (hadReceive == false)
|
| | | {
|
| | | timeOut++;
|
| | | if (timeOut >= 1500)
|
| | | {
|
| | | //响应超时,升级失败
|
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail));
|
| | | //显示重新安装
|
| | | this.ShowReSetupMsg();
|
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail;
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | | //发送失败给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1);
|
| | | return;
|
| | | }
|
| | | await System.Threading.Tasks.Task.Delay(50);
|
| | | continue;
|
| | | }
|
| | | hadReceive = false;
|
| | | //因为偏移量是高位在前,所以倒过来
|
| | | string Myoffset = string.Empty;
|
| | | for (int i = 6; i >= 0; i = i - 2)
|
| | | {
|
| | | Myoffset += i_offset.Substring(i, 2);
|
| | | }
|
| | | startIndex = Convert.ToInt32(Myoffset, 16) - i_dataLength;
|
| | |
|
| | | //获取一次能够发送的byte
|
| | | var listData = new List<byte>();
|
| | | for (; startIndex < allDataLength; startIndex++)
|
| | | {
|
| | | listData.Add(this.deviceFirmwareByte[startIndex]);
|
| | | if (listData.Count == i_dataLength)
|
| | | {
|
| | | break;
|
| | | }
|
| | | }
|
| | | //发送透传数据
|
| | | var sendData = new HdlDeviceAirConditionerLogic.SendUpgradeData() { dataLength = i_dataLength, offset = i_offset };
|
| | | sendData.databytes = listData.ToArray();
|
| | | HdlDeviceAirConditionerLogic.Current.UpgradeAsync(deviceAc, sendData);
|
| | | }
|
| | | this.zbGateway.ReportAction -= receiveAction;
|
| | |
|
| | | //发送结束命令
|
| | | this.DoSendFinishComand();
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 分包结束___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// 发送结束命令
|
| | | /// </summary>
|
| | | private async void DoSendFinishComand()
|
| | | {
|
| | | //正在发送升级完成的命令
|
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uSendingFinishUpdateComand));
|
| | |
|
| | | //发送成功命令给设备
|
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 0);
|
| | |
|
| | | //等个两秒钟吧
|
| | | await System.Threading.Tasks.Task.Delay(2000);
|
| | |
|
| | | //显示升级完成的信息
|
| | | this.ShowFinishMsg();
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 设置进度___________________________
|
| | |
|
| | | /// <summary>
|
| | | /// 设定进度值
|
| | | /// </summary>
|
| | | /// <param name="value">进度值</param>
|
| | | /// <param name="maxValue">maxValue</param>
|
| | | private void SetProgressValue(decimal value, decimal maxValue)
|
| | | {
|
| | | this.ProgressEvent?.Invoke(value / maxValue);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 设置错误信息
|
| | | /// </summary>
|
| | | /// <param name="value"></param>
|
| | | private void ShowErrorMsg(string value)
|
| | | {
|
| | | this.UpdateStatuChangedEvent?.Invoke(-1, value);
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 升级完成提示_______________________
|
| | |
|
| | | /// <summary>
|
| | | /// 显示升级完成的信息
|
| | | /// </summary>
|
| | | private void ShowFinishMsg()
|
| | | {
|
| | | //状态变更
|
| | | this.IsFinishUpdate = true;
|
| | | //升级完成
|
| | | this.UpdateStatu = UpdateStatuMode.UpdateFinish;
|
| | |
|
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
|
| | |
|
| | | //设备升级成功!
|
| | | this.UpdateStatuChangedEvent?.Invoke(1, Language.StringByID(R.MyInternationalizationString.uDeviceUpdateSuccess));
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | #region ■ 处理结果提示_______________________
|
| | |
|
| | | /// <summary>
|
| | | /// 显示重新安装的信息
|
| | | /// </summary>
|
| | | private void ShowReSetupMsg()
|
| | | {
|
| | | //状态变更
|
| | | this.IsFinishUpdate = true;
|
| | | //执行下一个升级
|
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 显示重新下载模式
|
| | | /// </summary>
|
| | | private void ShowReDownLoadMode()
|
| | | {
|
| | | //状态变更
|
| | | this.IsFinishUpdate = true;
|
| | | //执行下一个升级
|
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware();
|
| | | }
|
| | |
|
| | | #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 ZigBee.Device; |
| | | |
| | | namespace Shared.Phone.UserCenter |
| | | { |
| | | /// <summary> |
| | | /// 中央空调的升级逻辑 |
| | | /// </summary> |
| | | public class HdlACZbGatewayUpdateLogic : HdlDeviceUpdateCommonLogic |
| | | { |
| | | #region ■ 变量声明___________________________ |
| | | |
| | | /// <summary> |
| | | /// <para>更新状态变化的事件</para> |
| | | /// <para>第一个参数为:</para> |
| | | /// <para>-1:更新异常,后面的值为异常信息的翻译文本</para> |
| | | /// <para> 0:更新状态正常变化,后面的值为状态变更的文本翻译</para> |
| | | /// <para> 1:升级成功</para> |
| | | /// <para> 2:主动终止升级(中央空调木允许终止)</para> |
| | | /// <para> 3:从等待中取消(目前还没有用)</para> |
| | | /// </summary> |
| | | public Action<int, string> UpdateStatuChangedEvent = null; |
| | | /// <summary> |
| | | /// 进度值事件 |
| | | /// </summary> |
| | | public Action<decimal> ProgressEvent = null; |
| | | /// <summary> |
| | | /// 设备新版本的固件信息(多个设备升级时,应该会需要公开这个对象) |
| | | /// </summary> |
| | | public FirmwareVersionInfo deviceFirmware = null; |
| | | /// <summary> |
| | | /// 网关 |
| | | /// </summary> |
| | | private ZbGateway zbGateway = null; |
| | | /// <summary> |
| | | /// 升级的设备 |
| | | /// </summary> |
| | | private OTADevice otaDevice = null; |
| | | /// <summary> |
| | | /// 设备对象 |
| | | /// </summary> |
| | | private CommonDevice deviceAc = null; |
| | | /// <summary> |
| | | /// 前一次的最终状态 |
| | | /// </summary> |
| | | private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None; |
| | | /// <summary> |
| | | /// 固件的byte数组 |
| | | /// </summary> |
| | | private byte[] deviceFirmwareByte = null; |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 初始化_____________________________ |
| | | |
| | | /// <summary> |
| | | /// <para>HDL设备升级,以下为两个重要事件</para> |
| | | /// <para>UpdateStatuChangedEvent:更新状态变化的事件</para> |
| | | /// <para>ProgressEvent:进度值事件</para> |
| | | /// <para>StartUpdateReady():设备开始执行升级的函数,在调用这个之前,请先实现上面两个方法</para> |
| | | /// </summary> |
| | | /// <param name="i_deviceAc">设备</param> |
| | | /// <param name="i_deviceFirmware">设备的固件信息</param> |
| | | public HdlACZbGatewayUpdateLogic(CommonDevice i_deviceAc, FirmwareVersionInfo i_deviceFirmware) |
| | | { |
| | | this.ClassDiv = 2; |
| | | this.deviceAc = i_deviceAc; |
| | | this.otaDevice = Common.LocalDevice.Current.GetOTADevice(i_deviceAc.DeviceAddr); |
| | | this.deviceFirmware = i_deviceFirmware; |
| | | this.zbGateway = i_deviceAc.Gateway; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 开始更新___________________________ |
| | | |
| | | /// <summary> |
| | | /// 进入执行更新操作准备阶段 |
| | | /// </summary> |
| | | public void StartUpdateReady() |
| | | { |
| | | 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(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 开始执行更新操作 |
| | | /// </summary> |
| | | public override void DoStartUpdate() |
| | | { |
| | | //状态变更 |
| | | this.IsFinishUpdate = false; |
| | | this.UpdateStatu = UpdateStatuMode.Action; |
| | | //根据状态执行操作 |
| | | this.DoAdjustByStatuMode(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据状态执行操作 |
| | | /// </summary> |
| | | private void DoAdjustByStatuMode() |
| | | { |
| | | //先这样写吧,有可能以后会分情况 |
| | | //首发时,从开始执行 |
| | | if (this.oldUpdateStatu == UpdateStatuMode.None) |
| | | { |
| | | //执行校验版本 |
| | | this.DoCheckVersion(); |
| | | } |
| | | //设备下载失败 |
| | | else if (this.oldUpdateStatu == UpdateStatuMode.DeviceDownLoadFail) |
| | | { |
| | | //执行校验版本 |
| | | this.DoCheckVersion(); |
| | | } |
| | | //设备升级失败 |
| | | else if (this.oldUpdateStatu == UpdateStatuMode.DeviceUpdateFail) |
| | | { |
| | | //执行校验版本 |
| | | this.DoCheckVersion(); |
| | | } |
| | | else |
| | | { |
| | | //重新再来 |
| | | this.DoCheckVersion(); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 校验版本___________________________ |
| | | |
| | | /// <summary> |
| | | /// 校验版本 |
| | | /// </summary> |
| | | private async void DoCheckVersion() |
| | | { |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady; |
| | | //检测设备版本 |
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uCheckDeviceVersion)); |
| | | //设置初始值 |
| | | this.SetProgressValue(0, 100); |
| | | |
| | | await System.Threading.Tasks.Task.Delay(1000); |
| | | |
| | | //下载固件资源 |
| | | if (this.deviceFirmware.ImagType != "-100") |
| | | { |
| | | var pra = new { RequestVersion = Common.CommonPage.RequestVersion, DistributedMark = this.deviceFirmware.DistributedMark }; |
| | | this.deviceFirmwareByte = Common.CommonPage.Instance.RequestHttpsZigbeeBytesResultAsync("FirmwareMana/DownloadPlatformUploadFirmware", Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(pra))); |
| | | } |
| | | else |
| | | { |
| | | //取本地模板 |
| | | this.deviceFirmwareByte = HdlFileLogic.Current.ReadFileByteContent(this.deviceFirmware.Name); |
| | | } |
| | | if (this.deviceFirmwareByte == null) |
| | | { |
| | | //设备固件资源下载失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uDeviceFirmwareDownLoadFail)); |
| | | |
| | | //显示重新下载模式 |
| | | this.ShowReDownLoadMode(); |
| | | |
| | | this.UpdateStatu = UpdateStatuMode.DeviceDownLoadFail; |
| | | return; |
| | | } |
| | | |
| | | //数据偏移量,每个分包偏移量+(1-43) |
| | | string offset = string.Empty; |
| | | //一次发送的数据长度 |
| | | int dataLength = -1; |
| | | //接收网关的透传数据 |
| | | Action<string, object> receiveAction = (comand, pushData) => |
| | | { |
| | | string receiveData = ((CommonDevice.ClientDataPassthroughResponseData)pushData).PassData; |
| | | if (receiveData.Length < 6) |
| | | { |
| | | return; |
| | | } |
| | | try |
| | | { |
| | | var command = receiveData[4].ToString() + receiveData[5].ToString() + receiveData[2].ToString() + receiveData[3].ToString(); |
| | | if (command == "025c") |
| | | { |
| | | offset = receiveData.Substring(10, 8); |
| | | dataLength = Convert.ToInt32(receiveData.Substring(18, 2), 16); |
| | | } |
| | | } |
| | | catch { } |
| | | }; |
| | | this.zbGateway.ReportAction += receiveAction; |
| | | |
| | | //读取空调模块版本 |
| | | var result = await HdlDeviceAirConditionerLogic.Current.ReadACFirewareVersionAsync(deviceAc); |
| | | if (result == null || result.readACFirewareVersionResponData == null || result.readACFirewareVersionResponData.Status != 0) |
| | | { |
| | | //获取空调模块版本失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uGetAirConditionerModelVersionFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | //发送升级通知 |
| | | var result2 = await HdlDeviceAirConditionerLogic.Current.UpggradeACNotificationAsync(deviceAc, result.readACFirewareVersionResponData.FirewareVersion, this.deviceFirmwareByte.Length); |
| | | if (result2.responseData == null) |
| | | { |
| | | //发送升级命令失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uSendUpdateComandFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | else if (result2.responseData.status == 1) |
| | | { |
| | | //版本号相同,升级失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uVersionIsEqualAndUpdateFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | else if (result2.responseData.status != 0) |
| | | { |
| | | //校验版本号失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uCheckVersionFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | |
| | | int timeOut = 0; |
| | | //等待接收偏移量 |
| | | while (dataLength == -1) |
| | | { |
| | | timeOut++; |
| | | if (timeOut >= 30) |
| | | { |
| | | //响应超时,检测设备版本失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndCheckDeviceVersionFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | await System.Threading.Tasks.Task.Delay(1000); |
| | | //设置进度值 |
| | | this.SetProgressValue(timeOut, 30); |
| | | } |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | |
| | | //执行设备升级操作 |
| | | this.DoSetUpdateDevice(offset, dataLength); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 设备升级___________________________ |
| | | |
| | | /// <summary> |
| | | /// 执行设备升级操作 |
| | | /// </summary> |
| | | private async void DoSetUpdateDevice(string i_offset, int i_dataLength) |
| | | { |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateReady; |
| | | //设备正在升级… |
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uDeviceUpdating)); |
| | | //设置初始值 |
| | | this.SetProgressValue(0, 100); |
| | | |
| | | await System.Threading.Tasks.Task.Delay(1000); |
| | | |
| | | //发送数据的索引 |
| | | int startIndex = 0; |
| | | int allDataLength = this.deviceFirmwareByte.Length; |
| | | int timeOut = 0; |
| | | //是否接收到成功命令 |
| | | bool receiveSuccess = false; |
| | | |
| | | //接收网关的透传数据 |
| | | bool hadReceive = true; |
| | | Action<string, object> receiveAction = (comand, pushData) => |
| | | { |
| | | if (comand != "DeviceRequestAcUpdateData") |
| | | { |
| | | return; |
| | | } |
| | | string receiveData = ((CommonDevice.ClientDataPassthroughResponseData)pushData).PassData; |
| | | if (receiveData.Length < 6) |
| | | { |
| | | return; |
| | | } |
| | | try |
| | | { |
| | | var command = receiveData[4].ToString() + receiveData[5].ToString() + receiveData[2].ToString() + receiveData[3].ToString(); |
| | | if (command == "025c") |
| | | { |
| | | i_offset = receiveData.Substring(10, 8); |
| | | i_dataLength = Convert.ToInt32(receiveData.Substring(18, 2), 16); |
| | | hadReceive = true; |
| | | timeOut = 0; |
| | | //设置进度值 |
| | | this.SetProgressValue(startIndex, allDataLength); |
| | | } |
| | | else if (command == "025e") |
| | | { |
| | | //成功 设置进度值直接100% |
| | | this.SetProgressValue(allDataLength, allDataLength); |
| | | receiveSuccess = true; |
| | | timeOut = 0; |
| | | } |
| | | } |
| | | catch { } |
| | | }; |
| | | this.zbGateway.ReportAction += receiveAction; |
| | | |
| | | //最后一次需要等待回复结果才往下走 |
| | | while (startIndex < allDataLength) |
| | | { |
| | | if (receiveSuccess == true) |
| | | { |
| | | //已经接收到成功的命令 |
| | | break; |
| | | } |
| | | if (hadReceive == false) |
| | | { |
| | | timeOut++; |
| | | if (timeOut >= 1500) |
| | | { |
| | | //响应超时,升级失败 |
| | | this.ShowErrorMsg(Language.StringByID(R.MyInternationalizationString.uResponseTimeoutsAndUpdateFail)); |
| | | //显示重新安装 |
| | | this.ShowReSetupMsg(); |
| | | this.UpdateStatu = UpdateStatuMode.DeviceUpdateFail; |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | //发送失败给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 1); |
| | | return; |
| | | } |
| | | await System.Threading.Tasks.Task.Delay(50); |
| | | continue; |
| | | } |
| | | hadReceive = false; |
| | | //因为偏移量是高位在前,所以倒过来 |
| | | string Myoffset = string.Empty; |
| | | for (int i = 6; i >= 0; i = i - 2) |
| | | { |
| | | Myoffset += i_offset.Substring(i, 2); |
| | | } |
| | | startIndex = Convert.ToInt32(Myoffset, 16) - i_dataLength; |
| | | |
| | | //获取一次能够发送的byte |
| | | var listData = new List<byte>(); |
| | | for (; startIndex < allDataLength; startIndex++) |
| | | { |
| | | listData.Add(this.deviceFirmwareByte[startIndex]); |
| | | if (listData.Count == i_dataLength) |
| | | { |
| | | break; |
| | | } |
| | | } |
| | | //发送透传数据 |
| | | var sendData = new HdlDeviceAirConditionerLogic.SendUpgradeData() { dataLength = i_dataLength, offset = i_offset }; |
| | | sendData.databytes = listData.ToArray(); |
| | | HdlDeviceAirConditionerLogic.Current.UpgradeAsync(deviceAc, sendData); |
| | | } |
| | | this.zbGateway.ReportAction -= receiveAction; |
| | | |
| | | //发送结束命令 |
| | | this.DoSendFinishComand(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 分包结束___________________________ |
| | | |
| | | /// <summary> |
| | | /// 发送结束命令 |
| | | /// </summary> |
| | | private async void DoSendFinishComand() |
| | | { |
| | | //正在发送升级完成的命令 |
| | | this.UpdateStatuChangedEvent?.Invoke(0, Language.StringByID(R.MyInternationalizationString.uSendingFinishUpdateComand)); |
| | | |
| | | //发送成功命令给设备 |
| | | HdlDeviceAirConditionerLogic.Current.SendFinishAsync(deviceAc, 0); |
| | | |
| | | //等个两秒钟吧 |
| | | await System.Threading.Tasks.Task.Delay(2000); |
| | | |
| | | //显示升级完成的信息 |
| | | this.ShowFinishMsg(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 设置进度___________________________ |
| | | |
| | | /// <summary> |
| | | /// 设定进度值 |
| | | /// </summary> |
| | | /// <param name="value">进度值</param> |
| | | /// <param name="maxValue">maxValue</param> |
| | | private void SetProgressValue(decimal value, decimal maxValue) |
| | | { |
| | | this.ProgressEvent?.Invoke(value / maxValue); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置错误信息 |
| | | /// </summary> |
| | | /// <param name="value"></param> |
| | | private void ShowErrorMsg(string value) |
| | | { |
| | | this.UpdateStatuChangedEvent?.Invoke(-1, value); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 升级完成提示_______________________ |
| | | |
| | | /// <summary> |
| | | /// 显示升级完成的信息 |
| | | /// </summary> |
| | | private void ShowFinishMsg() |
| | | { |
| | | //状态变更 |
| | | this.IsFinishUpdate = true; |
| | | //升级完成 |
| | | this.UpdateStatu = UpdateStatuMode.UpdateFinish; |
| | | |
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); |
| | | |
| | | //设备升级成功! |
| | | this.UpdateStatuChangedEvent?.Invoke(1, Language.StringByID(R.MyInternationalizationString.uDeviceUpdateSuccess)); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 处理结果提示_______________________ |
| | | |
| | | /// <summary> |
| | | /// 显示重新安装的信息 |
| | | /// </summary> |
| | | private void ShowReSetupMsg() |
| | | { |
| | | //状态变更 |
| | | this.IsFinishUpdate = true; |
| | | //执行下一个升级 |
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 显示重新下载模式 |
| | | /// </summary> |
| | | private void ShowReDownLoadMode() |
| | | { |
| | | //状态变更 |
| | | this.IsFinishUpdate = true; |
| | | //执行下一个升级 |
| | | HdlFirmwareUpdateLogic.DoUpdateNextFirmware(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 释放缓存___________________________ |
| | | |
| | | /// <summary> |
| | | /// 释放缓存 |
| | | /// </summary> |
| | | public override void Dispose() |
| | | { |
| | | this.ProgressEvent = null; |
| | | this.UpdateStatuChangedEvent = null; |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | } |