IoT 设备离线时,云端下行消息触达方案

在物联网场景中,由于网络不稳定,导致设备间歇性离线状态;电池容量限制,很多 IoT 设备无法做到24小时在线,设备沉睡处于离线状态;这些现状带来一个新的挑战:在设备离线时,云端如何发送控制指令给设备?才能保证设备上线后,按照新的指令执行业务逻辑?

  技 术 解 决 方 案  

面对设备离线场景消息触达诉求,我们有两种通用解决方案:

  • 基于 MQTT 协议 QoS=1 消息

  • 基于 IoT 物联网平台的设备影子功能

方案一、发送QoS=1离线消息

MQTT 协议设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。在这套机制下,提供了三种不同层次服务质量QoS(Quality of Service):

  • QoS=0,至多一次;

  • QoS=1,至少一次;

  • QoS=2,只有一次。

QoS=1 代表,Sender 发送的一条消息,Receiver 至少能收到一次,也就是说 Sender 向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,但是因为重传的原因,Receiver 有可能会收到重复的消息;

当我们采用QoS=1方式发布消息到 IoT 物联网平台,即可保证消息至少到达设备端一次,再结合去重逻辑,重连时保留Session信息来实现离线消息触达。

1.1 设备端配置

设备建立 MQTT 连接时需要配置 CONNECT 参数 CleanSession=0,即保留之前建立的 session 状态,这包括:

  • 客户端的订阅信息;

  • 未完成确认的QoS=1的消息;

  • 未发送给客户端的QoS=1的消息。

Node.js实现CONNECT参数示例:

const options = {
    clientId: `${id}|securemode=3,signmethod=hmacsha1,timestamp=${timestamp}|`,
    username: `${deviceName}&${productKey}`,
    password: "根据文档规则进行 hmacsha1 加密",
    host: `${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com`,
    protocol: "mqtt",
    clean: false, //重连后保持Session
    keepalive: 300
}

1.2 服务端调用

服务端调用 IoT 物联网平台的Pub API ,并指定Qos =1 。完整API 文档参考

https://help.aliyun.com/document_detail/69793.html

Node.js调用Pub API示例:

//1.构建 Pub API 请求报文
const params = {
    TopicFullName: "下行指令的完整 Topic",
    MessageContent: "消息体的 base64 编码",
    ProductKey: "产品 ProductKey",
    IotInstanceId: "实例化 Id",
    Qos: 1 // 设备离线时,IoT平台缓存 7 天
};
//2.发起 Pub API 调用
const response = yield client.request('Pub', params);

方案二设备影子实现离线控制

IoT 物联网平台提供设备影子功能,可以实现离线设备的消息触达,完整消息链路如下如:

2.1 设备端开发

为了实现设备影子功能,IoT 设备端需要做两件事情:

  • 订阅设备影子更新的Topic:/shadow/get/${productKey}/${deviceName} 以便实时获取云端控制指令消息;

  • 设备CONNECT成功后,主动发布Topic和Payload 查询设备影子,用于获取云端最新影子数据。

Node.js 示例代码如下:

const mqtt = require('aliyun-iot-mqtt');


//设备身份三元组+区域
const deviceConfig = {
    "productKey": "产品",
    "deviceName": "设备",
    "deviceSecret": "设备deviceSecret",
    "regionId": "cn-shanghai"
};


//1.建立连接
const client = mqtt.getAliyunIotMqttClient(deviceConfig);
//2.订阅设备影子topic
const getShadow = `/shadow/get/${deviceConfig.productKey}/${deviceConfig.deviceName}`;
client.subscribe(getShadow)


client.on('message', function(topic, message) {
    //收到消息后,显示设备影子中的远程配置参数
    if (topic == getShadow) {
        message = JSON.parse(message);
        console.log(new Date().Format("yyyy-MM-dd HH:mm:ss.S"))
        console.log("\tappConfig.content :", JSON.stringify(message.payload.state.desired.appConfig))
        console.log("\tappConfig.timestamp :", JSON.stringify(message.payload.metadata.desired.appConfig.timestamp))
    }


})
//3.主动获取设备影子中的远程配置参数
const updateShadow = `/shadow/update/${deviceConfig.productKey}/${deviceConfig.deviceName}`;
client.publish(updateShadow, JSON.stringify({method: "get"}), { qos: 1 })

2.2 服务端调用

服务端调用设备影子接口 UpdateDeviceShadow 把新的配置参数保存到设备影子的desired中,接口文档:

https://help.aliyun.com/document_detail/69954.html

Node.js 示例代码如下:

const co = require('co');
const RPCClient = require('@alicloud/pop-core').RPCClient;


const options = {
    accessKey: "你的accessKey",
    accessKeySecret: "你的accessKeySecret",
};


//1.初始化client
const client = new RPCClient({
    accessKeyId: options.accessKey,
    secretAccessKey: options.accessKeySecret,
    endpoint: 'https://iot.cn-shanghai.aliyuncs.com',
    apiVersion: '2018-01-20'
});
//2.desired中appConfig变更
const shadowMessage = {
    method: "update",
    state: {
        desired: {
            appConfig:{
               maxTemperature: 39.5,
            }
        }
    },
    version: Date.now()
}
const params = {
    ProductKey: "你的ProductKey",
    DeviceName: "你的DeviceName",
    ShadowMessage: JSON.stringify(shadowMessage)
};


co(function*() {
    try {
        //3.发起API调用,更新影子中配置参数
        const response = yield client.request('UpdateDeviceShadow', params);
        console.log(JSON.stringify(response));
    } catch (err) {
        console.log(err);
    }
});
2.3 设备影子运行

云端业务系统调用成功后,我们在 IoT 物联网平台的控制台,设备详情>设备影子,查看设备影子信息。具体如下:

在线设备,实时获取更新

设备在线时,设备通过订阅设备影子的Topic实时获得云端配置参数。

离线设备,上线后获取更新

设备离线时,设备影子缓存云端配置参数,设备上线后,主动从云端拉取最新的配置参数。这时配置参数更新的时间会比当前时间早,设备端可以根据这个时间来判断是否要使用新的配置参数。

往期推荐

1、不讲武德,上班摸鱼,监控老板行踪

2、微信小程序 MQTT模拟器

3、自建MQTT集群迁移阿里云IoT实践

4、IoT+TSDB+Quick BI 搭建楼宇环境监控

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值