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