0


阿里云物联网Iot设备上下线状态数据流转的设置

要想通过物联网平台实现远程监控设备,那么就要建立监控端设备(比如手机)和被监控端设备的数据交互,在阿里云物联网平台完成这个交互功能的方法就是建立两个设备之间的数据流转,对于设备要流转的物模型数据,阿里云网站上已经有详细的示例介绍,但是对于设备上下线状态的数据流转,网站没有进行详细说明,本人经过摸索,整理成此文,予以记录。

一、监控端设备与被监控端设备完成数据交互的过程

第一,在物联网平台创建虚拟设备

在物联网平台建立实际设备(监控设备和被监控设备)相对应的虚拟设备,获得ProductKey、DeviceName、DeviceSecret三要素。此步属于阿里云物联网平台基本操作,阿里云官方网站有详细说明,可以参考:

创建产品 (aliyun.com)

单个创建设备 (aliyun.com)

批量创建设备 (aliyun.com)

第二,将实际设备与虚拟设备连接

在实际设备接入程序内配置相应的虚拟设备三要素,完成实际设备与物联网平台的连接,注意:虚拟设备和实际设备只能一对一连接。阿里云已经有设备的接入程序例程,可以参考:

下载设备端SDK (aliyun.com)

第三,设置数据流转

建立物联网平台内虚拟设备的数据流转,完成被监控实际设备数据上传到Iot虚拟设备->被监控虚拟设备数据流转到监控虚拟设备->监控虚拟设备数据下发到监控实际设备,完成实际设备之间的数据交互。

此步基本操作可以参考:

设置数据流转解析器 (aliyun.com)

设置数据流转解析器又分为3步:配置数据源、配置数据目的、编写解析器脚本程序。这三步中编写脚本程序难度最大,最为关键。阿里云官网上脚本示例都是以物模型数据上报为例的,可以参考:

脚本语法 (aliyun.com)

二、设备状态数据流转的设置

本文以被监控设备状态流转到监控设备为例,被监控虚拟设备名称:LZM1001,监控虚拟设备名称:LZM1002,这两台设备已经在物联网平台创建,并且已经与实际设备进行了连接。另外注意,阿里云物联网平台数据流转有新版和旧版,本文以新版为例。

数据流转设置的入口:物联网平台->规则引擎->云产品流转

第一步、创建数据源

1、在云产品页面,点“数据源”标签

2、点“创建数据源”按钮,给新的数据流转创建一个新的数据源,本例也就是被监控设备与虚拟设备LZM1001相连接的上下线状态

3、在数据源名称栏内取一个名字:本例取名为“设备LZM1001上下线状态” ,数据源描述可先不填。

4、点“确定”按钮,然后可以在数据源页面看到新创建的这条数据源。

5、点数据源“设备LZM1001上下线状态” 后边操作的“查看”,进入数据源详情界面,此时界面内还没有数据源。

6、在数据源详情界面,点“添加Topic”按钮,弹出“添加Topic”对话框。

7、第一个下拉列表框是Topic类型,选择“设备状态变化通知”。

8、第二个下拉列表框是产品名称,选择LZM1001所属的产品。

9、第三个是设备名称,选择“LZM1001”

10、然后点“确定”按钮。

此时可以看到数据源详情里已经有了一条数据源。

第二步、创建数据目的

1、点“数据目的”按钮。

2、点“创建数据目的”按钮,弹出“创建数据目的”对话框。

3、数据目的名称栏内:本例取名“设备LZM1002接收上线线状态”。

4、选择操作下拉列表框选“发布到另一个Topic”。

5、产品下拉列表框选择LZM1002所属的产品。

6、点“确定”按钮,完成创建。

此时可以看到数据目的页面内,已经有了这条新建的数据目的,注意:要记住这条数据目的ID为1017,一会编写解析器脚本会用到。

第三步、创建解析器并关联启动

1、点“解析器”标签,进入创建解析器页面。

2、点“创建解析器”按钮,弹出“创建解析器”对话框。

3、解析器名称栏,本例取名为“设备LZM1001状态发送到LZM1002”。

4、点“确定”按钮,完成创建。

5、在创建解析器页面可以看到这条新建的解析器,点操作栏“查看”,进入解析器详情页面,对解析器进行下一步操作。

6、在解析器详情页面点“数据源”标签,进入“关联数据源”页面。

7、点“关联数据源”按钮。

8、在“关联数据源”对话框,数据源下拉列表框内选择刚刚创建的数据源“设备LZM1001上下线状态”。

9、然后点“确定”按钮。

此时可以看到关联数据源页面内,已经有了一条数据源。

10、点“数据目的”标签。

11、在“数据目的”页面内,点“关联数据目的”按钮。

12、 在“关联数据目的”对话框内,在数据目的选择下拉列表框选择刚刚创建的数据目的“设备LZM1002接收上线线状态”。

13、点“确定”按钮,完成关联。

此时,在数据目的页面,可以看到有了这条数据目的,数据目的ID为1017。

14、点“解析器脚本”标签,进入“编辑脚本”界面。

15、在编辑框内,输入如下代码:

var data = payload("json");

var select = {};
select.put("deviceName", deviceName());
select.put("timestamp", timestamp());
select.put("status", data.status);

writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);

16、点“保存”按钮。

17、点“发布”按钮。

18、点解析器“设备LZM1001状态发送到LZM1002”前的后退箭头,返回到“云产品流转”页面。

19、点击“设备LZM1001状态发送到LZM1002” 这条解析器后边的“启动”按钮,启动云产品流转解析器。

第四步,测试

测试设备:LZM1001为一台真实设备,LZM1002用Android studio AVD代替。进行测试的结果如下:

当设备LZM上线时,LZM1002收到的消息中的msg即为数据流转的内容

devicename:LZM1001

timestamp:1661580931561

status:online

当设备LZM下线时,LZM1002收到的消息中的msg即为数据流转的内容

devicename:LZM1001

timestamp:1661590108538

status:offline

测试结果正确,配置成功!

三、脚本程序的解释

下边对脚本的代码进行一下解释:

第一步、脚本示例,详见脚本语法 (aliyun.com)

以下为阿里云上给出的脚本示例:

示例数据为上报的属性数据,输入数据如下:

{
    "deviceType": "CustomCategory",
    "iotId": "JCp9***",
    "requestId": "1626948228247",
    "checkFailedData": {

    },
    "productKey": "a1o***",
    "gmtCreate": 1626948134445,
    "deviceName": "Device1",
    "items": {
        "Temperature": {
            "value": 38,
            "time": 1626948134319
        },
        "Humidity": {
            "value": 25,
            "time": 1626948134319
        }
    }
}

解析和处理数据的示例如下:

//通过payload函数,获取设备上报的消息内容,并按照JSON格式转换。
var data = payload("json"); 
//筛选出上报的温湿度值。
var h = getOrNull(data, "items", "Humidity", "value");
var t = data.items.Temperature.value;
// 设置温度值大于38时触发规则,转发数据到云数据库RDS。
// RDS表结构为id[自增主键]、deviceName、temperature、humidity、time,在writeRds方法中,可以按column:value的形式,将值写入对应的列。
if (t > 38) { 
    writeRds(1000, {"deviceName":deviceName(), "temperature":t, "time":timestamp(), "humidity":h});  
}

解析处理的数据源必须转换为JSON格式数据,即数组或者嵌套的JSON数据。

第二步、本例脚本

首先看一下设备状态变化的Topic和数据格式,此部分内容可以参考数据格式 (aliyun.com)

1、设备上下线状态Topic

Topic:

/as/mqtt/status/${productKey}/${deviceName}

通过该Topic获取设备的上下线状态。

此句用在数据源关联。

2、设备上下线流转的数据格式

设备上线的数据格式:

{
    "status":"online",
    "iotId":"4z819VQHk6VSLmmBJfrf00107e****",
    "productKey":"al12345****",
    "deviceName":"deviceName1234",
    "time":"2018-08-31 15:32:28.205",
    "utcTime":"2018-08-31T07:32:28.205Z",
    "lastTime":"2018-08-31 15:32:28.195",
    "utcLastTime":"2018-08-31T07:32:28.195Z",
    "clientIp":"192.0.2.1"
}

设备下线的数据格式:

{
    "status":"offline",
    "iotId":"4z819VQHk6VSLmmBJfrf00107e****",
    "offlineReasonCode":427,
    "productKey":"al12345****",
    "deviceName":"deviceName1234",
    "time":"2018-08-31 15:32:28.205",
    "utcTime":"2018-08-31T07:32:28.205Z",
    "lastTime":"2018-08-31 15:32:28.195",
    "utcLastTime":"2018-08-31T07:32:28.195Z",
    "clientIp":"192.0.2.1"
}

上下线的数据格式中,第1条即为上下线的status的键值对。

3、脚本代码

var data = payload("json");

var select = {};
select.put("deviceName", deviceName());
select.put("timestamp", timestamp());
select.put("status", data.status);

writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);

(1)第1行代码:

var data = payload("json");

本例脚本代码第一行与脚本示例第一句一致,将设备状态变化通知上报的数据用payload函数,转成json格式,并将此json格式数据赋值给变量data。payload函数详细解释如下表:
payload(textEncoding)
返回设备发布消息payload的转义数据。textEncoding表示payload的转义字符编码,取值如下:

  • 不传入参数:默认按照UTF-8编码转换为字符串,即payload()等价于payload('utf-8')
  • 'json':将payload数据转换成Map格式变量。如果payload不是JSON格式,则返回异常。
  • 'binary':将payload数据转换成二进制变量进行透传。

(2)第2行代码:

 var select = {};
构建一个名为select的map类型数据,map内存储的对象为键值对,第一列为键名,第二列为键值,select初始化为空。
(3)第3-6行代码:
select.put("deviceName", deviceName());

select.put("timestamp", timestamp());

select.put("status", data.status);
向select内填加三个键值对,分别为设备名deviceName、时间戳timestamp和状态status。
注意键值名为一个标志字段,带双引号,其后的键值是从设备状态变化时上传的消息数据中取出的,所以为一个变量。
devieName和timestamp为设备上下线数据具体内容json之外的部分,所以变量格式为函数形式: deviceName()和timestamp()。

**

而status是json数据的具体内容,所以格式为data.status,此处是关键!

**

  • Map类型基本数据类型支持的函数。 表达式说明[Object]获取指定键(Key)对应的Value。size()获取Map数据中键值对数量。containKey(String)判断Map数据中是否包含指定的键。keySet()获取Map数据中键的集合,返回类型为Array。remove(Object)移除Map数据中指定键对应的键值对。put(Object, Object)在Map数据中添加键值对。putAll(map)在Map数据中批量添加一组Map数据。

(4)第6行:

writeIotTopic(1017, "/sys/gbsp*******/LZM1002/thing/service/property/set", select);

数据转发到另外一个Topic,所用的函数为writeIotTopic,此第一个变量为数据目的ID(此ID一般为某个产品,而不是具体的设备),第二个变量为转发目的的Topic(此变量确定为某个设备),第三个为转发的map格式的数据。

本例中:数据目的ID为1017,就是上文创建的数据目的编号。

Topic包含了产品名称:gbsp*******,设备名称:LZM1002,以及下发格式:set

要发送的数据就是2-5行代码创建的select。

writeIotTopic函数的具体说明如下:
writeIotTopic(destinationId, topic, payload, deviceName)流转数据到另一个Topic。

  • Topic:数据转发目的地Topic,支持以下Topic。 - 自定义Topic:该自定义Topic的设备操作权限需为订阅,即所属设备可订阅这个Topic,获取转发的消息。- 物模型数据下发Topic:/sys/${productKey}/${deviceName}/thing/service/property/set。该Topic为设备接收设置属性值指令的Topic,设备从该Topic接收转发数据,并根据数据内容,设置属性值。用于目的地Topic所属设备根据转发的数据更改属性值的场景。Topic中${productKey}必须与destinationId对应数据目的中设置的产品相同。函数中Topic必须指定具体Topic,不支持使用通配符。更多信息,请参见创建数据目的。注意 目的地Topic所属设备若未订阅该Topic,则收不到转发的消息。 例如使用MQTT.fx工具接入物联网平台的设备A,不会自动订阅设备Topic,若设备B向设备A的Topic:thing/service/property/set转发数据,而设备A未手动订阅该Topic,则设备A收不到设备B转发的消息。设备Topic自动订阅的详细说明,请参见自动订阅Topic说明。
  • deviceName:对于开源MQTT托管形态下产品和设备,及MQTT云网关产品和设备,流转数据到另一个Topic时,需传入该参数。其他业务场景无需传入该参数。 数据格式为Map类型,Key为"deviceName",Value为deviceName(),表示发送该Topic消息的设备名称。更多说明,请参见消息通信说明。

注意 MQTT云网关产品和设备下,流转的数据目的Topic仅支持自定义Topic,且不支持跨产品流转,即仅支持流转到当前产品下的自定义Topic。
开源MQTT托管形态的基础型实例下,仅支持创建一个产品,默认不支持跨产品流转。
数据转发到另一Topic
此段脚本中用的函数具体见:函数列表 (aliyun.com)


本文转载自: https://blog.csdn.net/m0_72963799/article/details/126555344
版权归原作者 m0_72963799 所有, 如有侵权,请联系我们删除。

“阿里云物联网Iot设备上下线状态数据流转的设置”的评论:

还没有评论