OTA 相关能力包括升级通知的接收、升级进度上报、升级请求以及升级应答信息的接收。本文介绍 OTA 升级的操作流程,并对各功能配置进行说明。完整的示例代码详见samples/ota/ota.go。
设备初始化。
首先,我们需要对设备进行初始化。调用arenal.CreateDeviceWithConfig
方法,传递DeviceOption
即可对设备进行初始化。DeviceOption
有两种创建方式:
方式一:自行填写内容。
d := arenal.CreateDeviceWithConfig(arenal.DeviceOption{ Name: "xxx", ProductKey: "xxxxxxxxx", Region: arenal.RegionBoe, VerifyMode: arenal.VerifyModeDynamicNoPreRegistered, FilePath: "", ModuleConfig: map[string]arenal.ModuleInfo{ "default":arenal.ModuleInfo{ ModuleKey: "default", Version: "1.0", }, }, UserDefineTopicQosMap: map[string]byte{ "sys/topic/demo":1, }, }) if ok := d.Init(); !ok { log.Error("device init failed") }
方式二:使用 YAML 文件配置,文件结构详见示例代码samples
下的config_template.yaml。
使用arenal.InitOptionWithConfigFile
方法,传递 YAML 文件所在路径即可生成对应的DeviceOption
。
deviceOption,err := arenal.InitOptionWithConfigFile("config/config.yaml") if err != nil{ fmt.Printf("error is : %s",err.Error()) return } d := arenal.CreateDeviceWithConfig(*deviceOption) if ok := d.Init(); !ok { log.Error("device init failed") }
配置升级通知接收器(可选)。
调用设备提供的SetOTANotifyHandler
方法,传递固定结构的 function 即可。每当通知消息到来时,就会进入该 function。默认情况下,会直接发起升级请求,对目标模块进行升级。
// 配置OTA升级通知Handler,设备支持OTA功能必须进行实现 d.SetOTANotifyHandler(func(message arenal.OTANotifyPayload) { // 此处实现接收到升级通知时,需要进行的操作 messageStr, _ := json.Marshal(message) fmt.Println(fmt.Sprintf("Receive Message Success!message = %v", string(messageStr))) // 进行某项OTA升级前,需要先调用OTAUpgradeRequest申请更新包url,平台返回会直接进入OTAReplyPayload进行处理 // 需要主动填写需要更新的module,如果有可用更新,则会通过Reply返回更新信息;若OTAUpgradeRequest参数otaJobID为空,表示请求最新的升级任务,建议不指定 code := d.OTAUpgradeRequest(message.Data.Module, "", message.DeviceIdentification) if code != arenal.SuccessCode { // 错误处理 log.Error("upgrade Request failed") } })
配置差分还原算法(可选,如果存在差分包必须进行配置)。调用设备提供的SetDiffAlgorithm
方法,传递固定结构的 function。
// 如果存在差分包的情况,必须准备好对应的反差分算法,否则可能会导致安装失败 var diffAlgorithm arenal.DiffAlgorithm diffAlgorithm = func(diffFileName string) arenal.DiffAlgorithmResult { //具体的生成整包流程 return arenal.DiffAlgorithmResult{ IsSuccess: true, ResDesc: "", TargetFilePath: diffFileName, } } d.SetDiffAlgorithm(diffAlgorithm)
配置安装包安装流程(支持 OTA 升级的设备,必须配置)。调用设备提供的SetInstallAlgorithm
方法,传递固定结构的 function。
// 需要提前准备好安装包烧写流程 var InstallAlgorithm arenal.InstallAlgorithm InstallAlgorithm = func(module, filename string) arenal.InstallAlgorithmResult { // 这里传递的参数为最终的整包路径,如果不是差分,则为下载路径,是差分则为反差分算法形成的整包路径 log.Infof("installing:filename:%s", filename) time.Sleep(10 * time.Second) return arenal.InstallAlgorithmResult{ IsSuccess: true, ResDesc: "", DeviceVersion: tmpVersion, NeedReboot: false, } } d.SetInstallAlgorithm(InstallAlgorithm)
配置 OTA 升级请求应答消息接收器(可选)。
调用设备提供的SetOTAReplyHandler
方法,传递固定结构的 function,平台下发的升级任务信息将在该接收器中进行处理。默认情况下,会直接触发设备升级,根据传递的模块信息、安装包信息等内容进行 OTA 升级。
// 建议初始化升级任务->下载->安装,也可以自定义升级流程,例如稍后下载/达到某个外界条件时安装,但初始化升级任务是必要步骤 d.SetOTAReplyHandler(func(message arenal.OTAReplyPayload) { messageStr, _ := json.Marshal(message) fmt.Println(fmt.Sprintf("receive message success!message = %v", string(messageStr))) tmpVersion = message.Data.DestVersion // 5.1 升级任务初始化。 code, otaMetadata := d.InitOTAJob(message.DeviceIdentification, message.Data) if code != arenal.SuccessCode { // 错误处理 log.Infof("no available OTA job was found for the OTA reply message,code:%d,otaMetadata:%v", code, otaMetadata) return } // 5.2 下载流程。 code = d.OTADownload(otaMetadata.OTAModuleName) if code != arenal.SuccessCode { // 错误处理 log.Errorf("OTA download failed,code:%d,otaMetadata:%v", code, otaMetadata) } // 5.3 安装流程。 code = d.OTAInstall(otaMetadata.OTAModuleName) if code != arenal.SuccessCode { // 错误处理 log.Errorf("OTA install failed,code:%d,otaMetadata:%v", code, otaMetadata) } })
主动请求升级包信息。调用设备提供的OTAUpgradeRequest
方法。
code := d.OTAUpgradeRequest("default", "") if code != arenal.SuccessCode { // 错误处理 log.Error("upgrade Request failed") }