HaaS轻应用(JavaScript)OTA 远程升级组件

简介: OTA升级是很多嵌入式产品必备的一个功能。HaaS 轻应用提供了完备的OTA解决方案。本案例就是一个升级JavaScript脚本的端云一体化例子,用户可以通过JavaScript脚本实现应用脚本的版本上报,下载,完整性检验和脚本加载。
来源 | HaaS技术社区

1、功能简介

OTA升级是很多嵌入式产品必备的一个功能。HaaS 轻应用提供了完备的OTA解决方案。本案例就是一个升级JavaScript脚本的端云一体化例子,用户可以通过JavaScript脚本实现应用脚本的版本上报,下载,完整性检验和脚本加载;具体流程如下图所示:

image.png

1.1、设备联网

在做脚本升级前确保设备是连网上线的,连网需要加入IOT组件,如果是wifi设备,需要加入netmgr组件进行配网,所以如上代码中,引入了iot组件和netmgr组件

import * as netmgr from 'netmgr';
import * as iot from 'iot';

还需要添加设备的三元组信息:

var productKey = ' ';      /* your productKey */
var deviceName = ' ';    /* your deviceName */ 
var deviceSecret = ' ';   /* your deviceSecret */

通过调用如下代码:

var device = iot.device({
        productKey: productKey,
        deviceName: deviceName,
        deviceSecret: deviceSecret
});

实现设备的上线;

1.2、版本上报

当设备上线后,需要将脚本的版本号报上云端,所以需要事先定义好脚本的版本,如示例代码定义的版本为:

var default_ver = '2.0.0';

由于阿里云IoT物联平台OTA是多模块升级方式,所以还需要定义一个模块名称,如果当前的脚本为设备的主业务,模块名称必须为"default",如示例代码:

var module_name = 'default';

版本号和模块名定义完成后,配合设备名和产品密钥,调用如下代码可实现版本号上报云端:

ota.report({
                device_handle: iotDeviceHandle,
                product_key: productKey,
                device_name: deviceName,
                module_name: module_name,
                version: default_ver
        });

ota.report接口用来将脚本版本号上报云端,入参有5个,第一个为IOT 设备handlem,设备成功连网后,会返回整个对象,第二参数为产品的密钥,第三个参数为设备名称,第四个参数为要上报版本模块的名称;

完成以上调用后,在阿里云物联网平台会看到如下信息:

image.png

上图中的default模块版本即为脚本中填入的版本号,system模块的版本为当前运行JS的OS系统版本;

1.3、脚本上传云端

首先需要做个高版本的js脚本,将步骤2中的JS版本号改成 var default_ver = '3.0.0';,然后创建一个app.json文件,文件内容如下:

{
    "version": "3.0.0",
    "io": {},
    "debugLevel": "DEBUG"
}

此文件主要是JS配套的配置,如设备端的io配置以及JS的版本号(与JS脚本中的版本号要相同);将app.js和app.json放到一个文件夹中,用JS工具打包成app.bin;JS工具用法请参考"命令行工具的pack命令使用";
打包完成后请参考下图完成固件上传到云端:

image.png

1.4、云端触发升级

JS脚本上传完成后,云端触发升级,如下图:

image.png

1.5、获取升级文件信息

当云端触发升级后,设备端会收到云端的发送的脚本信息,具体包括:文件大小、url、模块名称、hash type(md5或sha256)、hash值;对应上面的代码为:

ota.on('new', function(res) {
                console.log('length is ' + res.length);
                console.log('module_name is ' + res.module_name);
                console.log('version is ' + res.version);
                console.log('url is ' + res.url);
                console.log('hash is ' + res.hash);
                console.log('hash_type is ' + res.hash_type);

1.6、下载升级文件

通过步骤5设备端已拿到云端即将下发文件的版本号、url、模块名等,用户可根据需求决定是否下载此文件,比如版本比对,发现版本号较当前版本小,可以选择不下载,还可以通过模块名称判断下载的是什么文件,如模块名称为default,则下载的是JS脚本,用户可根据自己需要自己定义; 如用设备需要下载此文件,则通过download方法可实现下载,如示例代码:

ota.download({
                        url: info.url,
                        store_path: info.store_path
                }, function(res) {

下载接口,需要填入的参数有2个,第一参数为文件的URL,第二参数为文件的存储路径,包括存储的文件名称,如示例代码定义的:

var info = {
        url: '',
        store_path: '/data/jsamp/pack.bin',

1.7、校验升级文件

当文件下载完成后,需要验证文件下载的是否完整,需要调用verify验证,如上面示例代码:

ota.verify({
                                        length: info.length,
                                        hash_type: info.hashType,
                                        hash: info.hash,
                                        store_path: info.store_path
                                }, function(res) {

ota.verify入参有4个,分别为,下载文件的长度、云端下发的hash type(md5或sha256)、对应的hash值以及存储已下载文件的路径,这些参数已通过步骤5全部获取,直接填入即可;

1.8、加载升级文件

当步骤7校验成功后,即可实现脚本文件的加载,此时调用upgrade即可实现脚本的重新加载,如上面的示例代码:

ota.upgrade({
                                                        length: info.length,
                                                        store_path: info.store_path,
                                                        install_path: info.install_path
                                                }, function(res)

ota.upgrade有3个入参,第一个为下载文件的长度,第二入参为已下载文件的路径,第三个参数为要安装的路径,如示例代码定义的安装路径:

install_path: '/data/jsamp/',

如果升级成功,脚本会重新加载,上报版本号,云端状态如下图所示:

image.png

2、OTA接口介绍

open(Object option)

属性

类型

必填

描述

iot

Text

传入IOT组件的device handle

report(Object option)

属性

类型

必填

描述

device_handle

Number

传入IOT组件的device handle指针

product_key

String

设备的产品密钥

device_name

String

设备名称

module_name

String

模块名称

version

String

模块的版本号

dowload(Object option, Function callback)

属性

类型

必填

描述

url

String

下载文件的URL

store_path

String

存储下载文件的路径包括文件名称

callback

Function

下载完后的回调函数

verify(Object option, Function callback)

属性

类型

必填

描述

length

String

下载文件的长度

hash_type

String

是md5还是sha256

store_path

String

存储下载文件的路径

callback

Functiom

校验结果的回调函数

upgrade(Object option, Function callback)

属性

类型

必填

描述

length

String

下载文件的长度

store_path

String

存储下载文件的路径

install_path

String

安装脚本的路径

callback

Function

升级成功的回调函数

3、参考代码

 
import * as netmgr from 'netmgr';
import * as iot from 'iot';
import * as appota from 'appota'
 
//此脚本包含了wifi连网功能,仅适合haas100、haaseduk1
 
var productKey = '';      /* your productKey */
var deviceName = '';      /* your deviceName */
var deviceSecret = '';  /* your deviceSecret */
var device;
var module_name = 'default';
var default_ver = '2.0.0';
 
var ota;
var status;
/* download info */
var info = {
        url: '',
        store_path: '/data/jsamp/pack.bin',
        install_path: '/data/jsamp/',
        length: 0,
        hashType: '',
        hash: ''
}
 
function createDevice() {
    device = iot.device({
        productKey: productKey,
        deviceName: deviceName,
        deviceSecret: deviceSecret,
        region: 'cn-shanghai',
    });
 
device.on('connect', function () {
    console.log('(re)connected');
    var iotDeviceHandle = device.getDeviceHandle();
    console.log('get device handle module');
        ota = appota.open(iotDeviceHandle);
        console.log('report default module ver');
        ota.report({
                device_handle: iotDeviceHandle,
                product_key: productKey,
                device_name: deviceName,
                module_name: module_name,
                version: default_ver
        });
        ota.on('new', function(res) {
                console.log('length is ' + res.length);
                console.log('module_name is ' + res.module_name);
                console.log('version is ' + res.version);
                console.log('url is ' + res.url);
                console.log('hash is ' + res.hash);
                console.log('hash_type is ' + res.hash_type);
 
                info.url = res.url;
                info.length = res.length;
                info.module_name = res.module_name;
                info.version = res.version;
                info.hash = res.hash;
                info.hashType = res.hash_type;
 
                ota.download({
                        url: info.url,
                        store_path: info.store_path
                }, function(res) {
                        if (res >= 0) {
                                console.log('download success');
                                console.log('verify start');
                                console.log(info.hashType);
                                ota.verify({
                                        length: info.length,
                                        hash_type: info.hashType,
                                        hash: info.hash,
                                        store_path: info.store_path
                                }, function(res) {
                                        if (res >= 0) {
                                                console.log('verify success');
                                                console.log('upgrade start');
                                                ota.upgrade({
                                                        length: info.length,
                                                        store_path: info.store_path,
                                                        install_path: info.install_path
                                                }, function(res) {
                                                        if (res >= 0) {
                                                                console.log('upgrade success')
                                                        } else {
                                                                console.log('upgrade failed')
                                                        }
                                                })
                                        } else {
                                                console.log('verify failed');
                                        }
                                })
                        } else {
                                console.log('download failed');
                        }
                });
        });
});
}
 
var network = netmgr.openNetMgrClient({
    name: '/dev/wifi0'
});
 
var status;
status = network.getState();
console.log('status is ' + status);
network.connect({
  ssid: '',             //请替换为自己的热点ssid
  password: ''          //请替换为自己热点的密码
});
 
network.on('error', function () {
    console.log('error ...');
});
 
network.on('connect', function () {
    createDevice();
});
相关文章
|
1月前
|
前端开发 机器人 API
前端大模型入门(一):用 js+langchain 构建基于 LLM 的应用
本文介绍了大语言模型(LLM)的HTTP API流式调用机制及其在前端的实现方法。通过流式调用,服务器可以逐步发送生成的文本内容,前端则实时处理并展示这些数据块,从而提升用户体验和实时性。文章详细讲解了如何使用`fetch`发起流式请求、处理响应流数据、逐步更新界面、处理中断和错误,以及优化用户交互。流式调用特别适用于聊天机器人、搜索建议等应用场景,能够显著减少用户的等待时间,增强交互性。
322 2
|
1月前
|
JavaScript 前端开发 API
探索后端技术:Node.js的优势和实际应用
【10月更文挑战第6天】 在当今数字化时代,后端开发是任何成功软件应用的关键组成部分。本文将深入探讨一种流行的后端技术——Node.js,通过分析其核心优势和实际应用案例,揭示其在现代软件开发中的重要性和潜力。
131 2
|
5天前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
|
24天前
|
数据可视化 JavaScript 前端开发
数据可视化进阶:D3.js在复杂数据可视化中的应用
【10月更文挑战第26天】数据可视化是将数据以图形、图表等形式呈现的过程,帮助我们理解数据和揭示趋势。D3.js(Data-Driven Documents)是一个基于JavaScript的库,使用HTML、SVG和CSS创建动态、交互式的数据可视化。它通过数据驱动文档的方式,将数据与DOM元素关联,提供高度的灵活性和定制性,适用于复杂数据的可视化任务。 示例代码展示了如何使用D3.js创建一个简单的柱状图,展示了其基本用法。D3.js的链式调用和回调函数机制使代码简洁易懂,支持复杂的布局和交互逻辑。
64 3
|
1月前
|
机器学习/深度学习 自然语言处理 JavaScript
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
在信息论、机器学习和统计学领域中,KL散度(Kullback-Leibler散度)是量化概率分布差异的关键概念。本文深入探讨了KL散度及其相关概念,包括Jensen-Shannon散度和Renyi散度。KL散度用于衡量两个概率分布之间的差异,而Jensen-Shannon散度则提供了一种对称的度量方式。Renyi散度通过可调参数α,提供了更灵活的散度度量。这些概念不仅在理论研究中至关重要,在实际应用中也广泛用于数据压缩、变分自编码器、强化学习等领域。通过分析电子商务中的数据漂移实例,展示了这些散度指标在捕捉数据分布变化方面的独特优势,为企业提供了数据驱动的决策支持。
74 2
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
|
1月前
|
JavaScript 测试技术 API
跟随通义灵码一步步升级vue2(js)项目到vue3版本
Vue 3 相较于 Vue 2 在性能、特性和开发体验上都有显著提升。本文介绍了如何利用通义灵码逐步将 Vue 2 项目升级到 Vue 3,包括备份项目、了解新特性、选择升级方式、升级依赖、迁移组件和全局 API、调整测试代码等步骤,并提供了注意事项和常见问题的解决方案。
|
29天前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
31 1
|
1月前
|
JavaScript 前端开发 API
Vue.js:打造高效前端应用的最佳选择
【10月更文挑战第9天】Vue.js:打造高效前端应用的最佳选择
21 2
|
1月前
|
设计模式 JavaScript 前端开发
探索JavaScript中的闭包:从基础概念到实际应用
在本文中,我们将深入探讨JavaScript中的一个重要概念——闭包。闭包是一种强大的编程工具,它允许函数记住并访问其所在作用域的变量,即使该函数在其作用域之外被调用。通过详细解析闭包的定义、创建方法以及实际应用场景,本文旨在帮助读者不仅理解闭包的理论概念,还能在实际开发中灵活运用这一技巧。
|
1月前
|
缓存 JavaScript 前端开发
深入了解JavaScript的闭包:概念与应用
【10月更文挑战第8天】深入了解JavaScript的闭包:概念与应用
下一篇
无影云桌面