using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; namespace Shared.Phone.UserCenter { /// /// 中央空调的升级逻辑 /// public class HdlACZbGatewayUpdateLogic : 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 CommonDevice deviceAc = null; /// /// 前一次的最终状态 /// private UpdateStatuMode oldUpdateStatu = UpdateStatuMode.None; /// /// 固件的byte数组 /// private byte[] deviceFirmwareByte = null; #endregion #region ■ 初始化_____________________________ /// /// HDL设备升级,以下为两个重要事件 /// UpdateStatuChangedEvent:更新状态变化的事件 /// ProgressEvent:进度值事件 /// StartUpdateReady():设备开始执行升级的函数,在调用这个之前,请先实现上面两个方法 /// /// 设备 /// 设备的固件信息 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 ■ 开始更新___________________________ /// /// 进入执行更新操作准备阶段 /// 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(); } /// /// 开始执行更新操作 /// public override void DoStartUpdate() { //状态变更 this.IsFinishUpdate = false; this.UpdateStatu = UpdateStatuMode.Action; //根据状态执行操作 this.DoAdjustByStatuMode(); } /// /// 根据状态执行操作 /// 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 ■ 校验版本___________________________ /// /// 校验版本 /// 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 = 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 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 ■ 设备升级___________________________ /// /// 执行设备升级操作 /// 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 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(); 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 ■ 分包结束___________________________ /// /// 发送结束命令 /// 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 ■ 设置进度___________________________ /// /// 设定进度值 /// /// 进度值 /// maxValue private void SetProgressValue(decimal value, decimal maxValue) { this.ProgressEvent?.Invoke(value / maxValue); } /// /// 设置错误信息 /// /// private void ShowErrorMsg(string value) { this.UpdateStatuChangedEvent?.Invoke(-1, value); } #endregion #region ■ 升级完成提示_______________________ /// /// 显示升级完成的信息 /// private void ShowFinishMsg() { //状态变更 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 ■ 释放缓存___________________________ /// /// 释放缓存 /// public override void Dispose() { this.ProgressEvent = null; this.UpdateStatuChangedEvent = null; } #endregion } }