通过云端API完成OTA升级包上传

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 通过云端API完成OTA升级包上传

物联网设备进行OTA升级,需先在阿里云物联网平台为对应产品添加升级包。控制台操作流程请参考添加升级包


如果希望通过API调用来完成升级包的上传,需按顺序依次调用物联网平台和对象存储OSS的多个接口。本文介绍具体的操作步骤并提供完整的Java代码示例。


准备工作


  • 下载物联网平台云端SDK,最新版本请参考文档
<!--https://mvnrepository.com/artifact/com.aliyun/iot20180120 --><dependency><groupId>com.aliyun</groupId><artifactId>iot20180120</artifactId><version>3.0.7</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>tea-openapi</artifactId><version>0.2.2</version></dependency>


  • 下载对象存储OSS云端SDK,最新版本请参考文档
<!--https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.10.2</version></dependency>


操作步骤


  1. 调用GenerateOTAUploadURL接口

调用GenerateOTAUploadURL接口生成升级包文件上传到对象存储(OSS)的信息。


本接口的返回参数包含:


  • 第2步调用OSS PostObject上传升级包文件的请求参数:KeyOSSAccessKeyIdSignaturePolicy


部分代码示例:

// GenerateOTAUploadURLcom.aliyun.iot20180120.Clientclient=OTAFirmware.createClient("LTAI4FvZ****", "biCR4vJnIq****");
GenerateOTAUploadURLRequestgenerateOTAUploadURLRequest=newGenerateOTAUploadURLRequest()
        .setIotInstanceId("iot-******")
        .setFileSuffix("zip");
RuntimeOptionsruntime=newRuntimeOptions();
GenerateOTAUploadURLResponsegenerateOTAUploadURLResponse=client.generateOTAUploadURLWithOptions(generateOTAUploadURLRequest, runtime);
// 获取OSS表单上传的参数信息StringKey=generateOTAUploadURLResponse.body.data.key;
StringOSSAccessKeyId=generateOTAUploadURLResponse.body.data.OSSAccessKeyId;
StringSignature=generateOTAUploadURLResponse.body.data.signature;
StringPolicy=generateOTAUploadURLResponse.body.data.policy;
StringHost=generateOTAUploadURLResponse.body.data.host;
// 获取IoT创建升级包的urlStringFirmwareUrl=generateOTAUploadURLResponse.body.data.firmwareUrl;


  1. 调用PostObject接口


在第1步的GenerateOTAUploadURL接口返回结果后的1分钟之内,使用OSS的PostObject接口上传升级包文件。


说明  GenerateOTAUploadURL接口返回的参数信息有效期为1分钟,请在1分钟内上传升级包。上传的升级包文件大小不能超过2,000 MB。


部分代码示例:

//待上传的本地升级包路径StringlocalFilePath="D:\****\test.zip";
// PostObjectPostObject(Key, Host, Policy, OSSAccessKeyId, Signature, localFilePath);


  1. 调用CreateOTAFirmware接口


升级包上传完成后,请在60分钟内,调用物联网平台APICreateOTAFirmware接口创建升级包。


如果上传了升级包,但未调用CreateOTAFirmware接口创建升级包,上传的文件将被系统定期自动清理。


部分代码示例:

// CreateOTAFirmwareCreateOTAFirmwareRequestcreateOTAFirmwareRequest=newCreateOTAFirmwareRequest()
        .setIotInstanceId("iot-****")
        .setFirmwareName("API上传固件测试")
        .setDestVersion("1.0")
        .setFirmwareUrl(FirmwareUrl)
        .setProductKey("g8orC****");
CreateOTAFirmwareResponsecreateOTAFirmwareResponse=client.createOTAFirmwareWithOptions(createOTAFirmwareRequest, runtime);


注意事项


  • 上述API接口的完整请求参数、返回数据说明,请到产品API列表中,点击API查看详情,本文不做过多描述。


  • 目前OSS SDK中,仅Java SDK提供了PostObject接口上传示例。如需使用其他开发语言,请自行参考API文档完成表单上传操作。


完整代码示例

importcom.aliyun.iot20180120.models.*;
importcom.aliyun.teaopenapi.models.*;
importcom.aliyun.teautil.models.*;
importjavax.activation.MimetypesFileTypeMap;
importjava.io.*;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.util.Iterator;
importjava.util.LinkedHashMap;
importjava.util.Map;
importcom.aliyun.oss.ClientException;
publicclassOTAFirmware {
publicstaticcom.aliyun.iot20180120.ClientcreateClient(StringaccessKeyId, StringaccessKeySecret) throwsException {
Configconfig=newConfig()
                .setAccessKeyId(accessKeyId)
                .setAccessKeySecret(accessKeySecret);
config.endpoint="iot.cn-shanghai.aliyuncs.com";
returnnewcom.aliyun.iot20180120.Client(config);
    }
publicstaticvoidmain(String[] args) throwsException {
// GenerateOTAUploadURLcom.aliyun.iot20180120.Clientclient=OTAFirmware.createClient("LTAI4FvZ8****", "biCR4vJnIqi48****");
GenerateOTAUploadURLRequestgenerateOTAUploadURLRequest=newGenerateOTAUploadURLRequest()
                .setIotInstanceId("iot-****")
                .setFileSuffix("zip");
RuntimeOptionsruntime=newRuntimeOptions();
GenerateOTAUploadURLResponsegenerateOTAUploadURLResponse=client.generateOTAUploadURLWithOptions(generateOTAUploadURLRequest, runtime);
// 获取OSS表单上传的参数信息StringKey=generateOTAUploadURLResponse.body.data.key;
StringOSSAccessKeyId=generateOTAUploadURLResponse.body.data.OSSAccessKeyId;
StringSignature=generateOTAUploadURLResponse.body.data.signature;
StringPolicy=generateOTAUploadURLResponse.body.data.policy;
StringHost=generateOTAUploadURLResponse.body.data.host;
// 获取IoT创建升级包的urlStringFirmwareUrl=generateOTAUploadURLResponse.body.data.firmwareUrl;
//待上传的本地升级包路径StringlocalFilePath="D:\****\test.zip";
// PostObjectPostObject(Key, Host, Policy, OSSAccessKeyId, Signature, localFilePath);
// CreateOTAFirmwareCreateOTAFirmwareRequestcreateOTAFirmwareRequest=newCreateOTAFirmwareRequest()
                .setIotInstanceId("iot-****")
                .setFirmwareName("API上传固件测试")
                .setDestVersion("1.0")
                .setFirmwareUrl(FirmwareUrl)
                .setProductKey("g8or****");
CreateOTAFirmwareResponsecreateOTAFirmwareResponse=client.createOTAFirmwareWithOptions(createOTAFirmwareRequest, runtime);
System.out.println("Success is: "+createOTAFirmwareResponse.body.success);
System.out.println("requestID is: "+createOTAFirmwareResponse.body.requestId);
System.out.println("FirmwareId is: "+createOTAFirmwareResponse.body.data.firmwareId);
    }
privatestaticvoidPostObject(Stringkey, Stringhost, Stringpolicy, StringaccessKeyId, Stringsignature, StringlocalFilePath) throwsException {
StringurlStr=host;
// 设置表单Map。Map<String, String>formFields=newLinkedHashMap<String, String>();
formFields.put("key", key);
formFields.put("Content-Disposition", "attachment;filename="+localFilePath);
formFields.put("OSSAccessKeyId", accessKeyId);
formFields.put("policy", policy);
formFields.put("Signature", signature);
Stringret=formUpload(urlStr, formFields, localFilePath);
System.out.println("Post Object to OSS success");
    }
privatestaticStringformUpload(StringurlStr, Map<String, String>formFields, StringlocalFile) throwsException {
Stringres="";
HttpURLConnectionconn=null;
Stringboundary="9431149156168";
try {
URLurl=newURL(urlStr);
conn= (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(30000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
// 设置MD5值。MD5值由整个Body计算得出。如果希望开启MD5校验,可参考MD5加密设置。// conn.setRequestProperty("Content-MD5", contentMD5);conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary="+boundary);
OutputStreamout=newDataOutputStream(conn.getOutputStream());
// 遍历读取表单Map中的数据,将数据写入到输出流中。if (formFields!=null) {
StringBufferstrBuf=newStringBuffer();
Iterator<Map.Entry<String, String>>iter=formFields.entrySet().iterator();
inti=0;
while (iter.hasNext()) {
Map.Entry<String, String>entry=iter.next();
StringinputName=entry.getKey();
StringinputValue=entry.getValue();
if (inputValue==null) {
continue;
                    }
if (i==0) {
strBuf.append("--").append(boundary).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\""+inputName+"\"\r\n\r\n");
strBuf.append(inputValue);
                    } else {
strBuf.append("\r\n").append("--").append(boundary).append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\""+inputName+"\"\r\n\r\n");
strBuf.append(inputValue);
                    }
i++;
                }
out.write(strBuf.toString().getBytes());
            }
// 读取文件信息,将要上传的文件写入到输出流中。Filefile=newFile(localFile);
Stringfilename=file.getName();
StringcontentType=newMimetypesFileTypeMap().getContentType(file);
if (contentType==null||contentType.equals("")) {
contentType="application/octet-stream";
            }
StringBufferstrBuf=newStringBuffer();
strBuf.append("\r\n").append("--").append(boundary)
                    .append("\r\n");
strBuf.append("Content-Disposition: form-data; name=\"file\"; "+"filename=\""+filename+"\"\r\n");
strBuf.append("Content-Type: "+contentType+"\r\n\r\n");
out.write(strBuf.toString().getBytes());
DataInputStreamin=newDataInputStream(newFileInputStream(file));
intbytes=0;
byte[] bufferOut=newbyte[1024];
while ((bytes=in.read(bufferOut)) !=-1) {
out.write(bufferOut, 0, bytes);
            }
in.close();
byte[] endData= ("\r\n--"+boundary+"--\r\n").getBytes();
out.write(endData);
out.flush();
out.close();
// 读取返回数据。strBuf=newStringBuffer();
BufferedReaderreader=newBufferedReader(newInputStreamReader(conn.getInputStream()));
Stringline=null;
while ((line=reader.readLine()) !=null) {
strBuf.append(line).append("\n");
            }
res=strBuf.toString();
reader.close();
reader=null;
        } catch (ClientExceptione) {
//            System.err.println("Send post request exception: " + e);System.err.println(e.getErrorCode()+" msg="+e.getMessage());
throwe;
        } finally {
if (conn!=null) {
conn.disconnect();
conn=null;
            }
        }
returnres;
    }
}


运行结果


在控制台的监控运维-OTA升级的升级包列表中,可以看到上传成功的升级包。

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
1月前
|
前端开发 小程序 API
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
|
26天前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
90 3
|
2月前
|
存储 Oracle Java
Java 包和 API 深度解析:组织代码,避免命名冲突
Java 中的包 用于将相关的类分组在一起。可以将其视为文件目录中的一个文件夹。我们使用包来避免名称冲突,并编写更易于维护的代码。 包分为两类: 内置包(来自 Java API 的包) 用户定义的包(创建自己的包)
308 2
|
JavaScript API
调用物联网平台云端api时的签名js实现
调用物联网平台云端api时的签名js实现。
225 0
|
API Python
调用物联网平台云端api时的签名python3实现
调用物联网平台云端api时的签名python3实现。
168 0
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
|
SQL 存储 自然语言处理
【Mysql】耗时7200秒整理的mysql笔记!常用API汇总!包教包会!
⭐Hi~ o( ̄▽ ̄)ブ大家好我是雪人,今天分享出我的Mysql整理笔记!⭐耗时7200秒整理的资料直接拿走!⭐适合新手入门与API查阅观看!⭐本文包含以下内容:Mysql安装,SQL语句分类汇总,约束,mysql数据类型,事务,忘记ROOT密码等…
82 1
|
Java 分布式数据库 API
HbaseJAVA开发API导入jar包以及实现操作命令
HbaseJAVA开发API导入jar包以及实现操作命令
354 0
HbaseJAVA开发API导入jar包以及实现操作命令
|
10天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
17天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。