通过云端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
相关文章
|
6月前
|
前端开发 小程序 API
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
【微信小程序】-- 使用 npm 包 - API Promise化(四十二)
|
3月前
|
JSON API 数据处理
Winform管理系统新飞跃:无缝集成SqlSugar与Web API,实现数据云端同步的革新之路!
【8月更文挑战第3天】在企业应用开发中,常需将Winform桌面应用扩展至支持Web API调用,实现数据云端同步。本文通过实例展示如何在已有SqlSugar为基础的Winform系统中集成HTTP客户端调用Web API。采用.NET的`HttpClient`处理请求,支持异步操作。示例包括创建HTTP辅助类封装请求逻辑及在Winform界面调用API更新UI。此外,还讨论了跨域与安全性的处理策略。这种方法提高了系统的灵活性与扩展性,便于未来的技术演进。
243 2
|
5月前
|
Java 程序员 API
JavaSE——常用API(1/3)-包、String概述、String常用方法(length、charAt、遍历字符串、toCharArray......)
JavaSE——常用API(1/3)-包、String概述、String常用方法(length、charAt、遍历字符串、toCharArray......)v
37 0
|
6月前
|
Java 数据库连接 API
Java 学习路线:基础知识、数据类型、条件语句、函数、循环、异常处理、数据结构、面向对象编程、包、文件和 API
Java 是一种广泛使用的、面向对象的编程语言,始于1995年,以其跨平台性、安全性和可靠性著称,应用于从移动设备到数据中心的各种场景。基础概念包括变量(如局部、实例和静态变量)、数据类型(原始和非原始)、条件语句(if、else、switch等)、函数、循环、异常处理、数据结构(如数组、链表)和面向对象编程(类、接口、继承等)。深入学习还包括包、内存管理、集合框架、序列化、网络套接字、泛型、流、JVM、垃圾回收和线程。构建工具如Gradle、Maven和Ant简化了开发流程,Web框架如Spring和Spring Boot支持Web应用开发。ORM工具如JPA、Hibernate处理对象与数
153 3
|
6月前
|
存储 Oracle Java
Java 包和 API 深度解析:组织代码,避免命名冲突
Java 中的包 用于将相关的类分组在一起。可以将其视为文件目录中的一个文件夹。我们使用包来避免名称冲突,并编写更易于维护的代码。 包分为两类: 内置包(来自 Java API 的包) 用户定义的包(创建自己的包)
361 2
|
存储 前端开发 JavaScript
使用python3.7+Vue.js2.0+Django2.0.4异步前端通过api上传文件到七牛云云端存储
之前一篇文章是通过普通js+tornado来上传七牛云:[使用Tornado配合七牛云存储api来异步切分上传文件](https://v3u.cn/a_id_123),本次使用vue+django来进行异步上传,因为毕竟vue.js才是目前的前端的主流。
使用python3.7+Vue.js2.0+Django2.0.4异步前端通过api上传文件到七牛云云端存储
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
Error:(3, 29) java: 程序包org.junit.jupiter.api不存在
|
JavaScript API
调用物联网平台云端api时的签名js实现
调用物联网平台云端api时的签名js实现。
311 0
|
API Python
调用物联网平台云端api时的签名python3实现
调用物联网平台云端api时的签名python3实现。
215 0
|
4天前
|
JSON API 数据格式
淘宝 / 天猫官方商品 / 订单订单 API 接口丨商品上传接口对接步骤
要对接淘宝/天猫官方商品或订单API,需先注册淘宝开放平台账号,创建应用获取App Key和App Secret。之后,详细阅读API文档,了解接口功能及权限要求,编写认证、构建请求、发送请求和处理响应的代码。最后,在沙箱环境中测试与调试,确保API调用的正确性和稳定性。

热门文章

最新文章