在物联网业务场景中,对于低配置且资源受限或者对网络流量有要求的设备,不适合直接构造JSON数据与物联网平台通信,可将原数据透传到物联网平台。物联网平台提供数据解析功能,可以根据您提交的脚本,先将数据在设备自定义格式和JSON格式之间转换,再进行业务处理。
背景信息
数据解析流程图如下所示。
本文以环境数据采集设备为例,为您介绍数据解析具体操作步骤。
设备端接入物联网平台
登录物联网平台控制台。
在实例概览页签的全部环境下,找到对应的实例,单击实例卡片。
在左侧导航栏,选择环境监测传感器。 ,单击创建产品,创建一个产品:
数据格式选择透传/自定义,其他使用默认设置。参数详细说明,请参见创建产品。
产品创建成功后,单击前往定义物模型,添加物模型,然后发布上线。
在左侧导航栏,选择设备,单击添加设备,在环境监测传感器产品下添加设备:Esensor。
设备创建成功后,获取设备证书信息(ProductKey、DeviceName和DeviceSecret)。
开发设备端,并测试运行。
本示例使用物联网平台提供的Node.js SDK开发设备,并设置设备端模拟上报消息,测试运行设备端SDK。开发方法,请参见设备接入和上报数据。
设备端开发更多操作说明,请参见设备接入Link SDK。
SDK开发示例代码如下:
const mqtt = require('aliyun-iot-mqtt'); // 1. 设备身份信息 var options = { productKey: "g18lk****", deviceName: "Esensor", deviceSecret: "c39fe9dc32f97bfd753******b", host: "iot******.mqtt.iothub.aliyuncs.com" }; // 1. 建立连接 const client = mqtt.getAliyunIotMqttClient(options); // 2. 监听云端指令 client.subscribe(`/${options.productKey}/${options.deviceName}/user/get`) client.on('message', function(topic, message) { console.log("topic " + topic) console.log("message " + message) }) setInterval(function() { // 3.上报环境数据 const payloadArray = new Buffer.from([0xaa,0x1f,0xc8,0x00,0x00,0x37,0x10,0xff,0x00,0x05,0xd7,0x6b,0x15,0x00,0x1c,0x01,0x34,0x00,0xad,0x04,0xff,0xff,0x04,0x00,0xff,0xff,0x18,0x00,0x30,0x00,0xff,0x2e]) client.publish(`/sys/${options.productKey}/${options.deviceName}/thing/model/up_raw`, payloadArray, { qos: 0 }); }, 5 * 1000);
设备端成功接入物联网平台后,在物联网平台控制台对应实例下的设备页面,该设备状态显示为在线。
单击设备Esensor操作栏的查看,单击物模型数据。如下图所示,因产品数据格式为透传/自定义,模拟上报的标准物模型数据不能在运行状态页签显示。
在
页面的云端运行日志页签下,查看该设备的设备到云消息中对应的Hex格式消息内容。本示例中,Hex格式消息内容为:
0xaa1fc800003710ff0005d76b15001c013400ad04ffff0400ffff18003000ff2e
。
编写数据解析脚本
在物联网平台控制台,编辑、提交脚本,并模拟数据解析。
在物联网平台控制台对应实例下的左侧导航栏,选择 。
在产品页面,单击产品对应的查看。
在产品详情页面,单击消息解析页签。
在消息解析页签下的编辑脚本输入框中,输入数据解析脚本。
根据设备数据协议内容编写解析脚本。本示例中的设备数据消息体结构如下表所示。
Byte
说明
备注
12
PM2.5值低字节
返回:PM2.5值,取值范围0~999ug/m3。
13
PM2.5值高字节
14
温度值*10低字节
返回:温度值,取值范围-10°C~50°C。
15
温度值*10高字节
16
湿度值低字节
返回:湿度值,取值范围0~99%。
17
湿度值高字节
18
二氧化碳含量低字节
返回:二氧化碳含量,取值范围0~9999mg/m3。
19
二氧化碳含量高字节
22
甲醛含量*100低字节
返回:甲醛含量,取值范围0~9.99。
23
甲醛含量*100高字节
28
照度值低字节
返回:照度值,单位lux。
29
照度值高字节
示例中的环境采集设备只有数据上报功能,因此只需要编写上行数据解析函数rawDataToProtocol,无需实现protocolToRawData。可以将透传后的数据转发到属性、服务或事件。本示例中将数据转发到属性。
var PROPERTY_REPORT_METHOD = 'thing.event.property.post'; //上行数据,自定义格式转物模型JSON格式。 function rawDataToProtocol(bytes) { var uint8Array = new Uint8Array(bytes.length); for (var i = 0; i < bytes.length; i++) { uint8Array[i] = bytes[i] & 0xff; } var dataView = new DataView(uint8Array.buffer, 0); var jsonMap = new Object(); //属性上报method。 jsonMap['method'] = PROPERTY_REPORT_METHOD; //协议版本号,固定字段,取值1.0。 jsonMap['version'] = '1.0'; //表示该次请求的ID。 jsonMap['id'] = new Date().getTime(); var params = {}; //12、13对应产品属性中PM2.5。 params['PM25'] = (dataView.getUint8(13)*256+dataView.getUint8(12)); //14、15对应产品属性中temperature。 params['temperature'] = (dataView.getUint8(15)*256+dataView.getUint8(14))/10; //16、17对应产品属性中humidity。 params['humidity'] = (dataView.getUint8(17)*256+dataView.getUint8(16)); //18、19对应产品属性中co2。 params['co2'] = (dataView.getUint8(19)*256+dataView.getUint8(18)); //22、23对应产品属性中甲醛hcho。 params['hcho'] = (dataView.getUint8(23)*256+dataView.getUint8(22))/100; //28、29对应产品属性中光照lightLux。 params['lightLux'] = (dataView.getUint8(29)*256+dataView.getUint8(28)); jsonMap['params'] = params; return jsonMap; } //下行指令,物模型JSON格式转自定义格式。 function protocolToRawData(json) { var payloadArray = [1];//此设备只有上报数据功能,无法接收云端指令。 return payloadArray; } //将设备自定义Topic数据转换为JSON格式数据。 function transformPayload(topic, rawData) { var jsonObj = {} return jsonObj; }
测试数据解析。
选择模拟类型为设备上报数据。
在模拟输入下的输入框中,输入一个模拟数据。
模拟数据可使用测试运行设备端后,在日志服务页面,查看到的设备端上报数据的Hex格式内容。例如:
0xaa1fc800003710ff0005d76b15001c013400ad04ffff0400ffff18003000ff2e
。单击执行 。
右侧运行结果栏显示解析结果如下图所示。
确认脚本能正确解析数据后,单击提交,将脚本提交到物联网平台。
调试设备上报数据
脚本提交后,再次运行设备端SDK脚本进行调试验证。
设备端向物联网平台上报数据后,物联网平台会调用脚本进行数据解析。您可在
页面的云端运行日志页签下,查看设备上报数据进行数据解析的日志。解析后的数据将显示在设备对应设备详情页面的
页签下。附:物模型TSL
{
"schema": "https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json",
"profile": {
"version": "1.0",
"productKey": "g4****"
},
"properties": [
{
"identifier": "lightLux",
"name": "光照强度",
"accessMode": "rw",
"required": false,
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10000",
"unit": "Lux",
"unitName": "照度",
"step": "0.1"
}
}
},
{
"identifier": "PM25",
"name": "PM25",
"accessMode": "rw",
"required": false,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "1000",
"unit": "μg/m³",
"unitName": "微克每立方米",
"step": "1"
}
}
},
{
"identifier": "hcho",
"name": "甲醛",
"accessMode": "rw",
"desc": "HCHOValue",
"required": false,
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10",
"unit": "ppm",
"unitName": "百万分率",
"step": "0.1"
}
}
},
{
"identifier": "co2",
"name": "二氧化碳",
"accessMode": "rw",
"required": false,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "10000",
"unit": "mg/m³",
"unitName": "毫克每立方米",
"step": "1"
}
}
},
{
"identifier": "humidity",
"name": "湿度",
"accessMode": "rw",
"required": false,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "%",
"unitName": "百分比",
"step": "1"
}
}
},
{
"identifier": "temperature",
"name": "温度",
"accessMode": "rw",
"desc": "电机工作温度",
"required": false,
"dataType": {
"type": "float",
"specs": {
"min": "-10",
"max": "50",
"unit": "℃",
"step": "0.1"
}
}
}
],
"events": [
{
"identifier": "post",
"name": "post",
"type": "info",
"required": true,
"desc": "属性上报",
"method": "thing.event.property.post",
"outputData": [
{
"identifier": "lightLux",
"name": "光照强度",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10000",
"unit": "Lux",
"unitName": "照度",
"step": "0.1"
}
}
},
{
"identifier": "PM25",
"name": "PM25",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "1000",
"unit": "μg/m³",
"unitName": "微克每立方米",
"step": "1"
}
}
},
{
"identifier": "hcho",
"name": "甲醛",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10",
"unit": "ppm",
"unitName": "百万分率",
"step": "0.1"
}
}
},
{
"identifier": "co2",
"name": "二氧化碳",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "10000",
"unit": "mg/m³",
"unitName": "毫克每立方米",
"step": "1"
}
}
},
{
"identifier": "humidity",
"name": "湿度",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "%",
"unitName": "百分比",
"step": "1"
}
}
},
{
"identifier": "temperature",
"name": "温度",
"dataType": {
"type": "float",
"specs": {
"min": "-10",
"max": "50",
"unit": "℃",
"step": "0.1"
}
}
}
]
}
],
"services": [
{
"identifier": "set",
"name": "set",
"required": true,
"callType": "async",
"desc": "属性设置",
"method": "thing.service.property.set",
"inputData": [
{
"identifier": "lightLux",
"name": "光照强度",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10000",
"unit": "Lux",
"unitName": "照度",
"step": "0.1"
}
}
},
{
"identifier": "PM25",
"name": "PM25",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "1000",
"unit": "μg/m³",
"unitName": "微克每立方米",
"step": "1"
}
}
},
{
"identifier": "hcho",
"name": "甲醛",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10",
"unit": "ppm",
"unitName": "百万分率",
"step": "0.1"
}
}
},
{
"identifier": "co2",
"name": "二氧化碳",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "10000",
"unit": "mg/m³",
"unitName": "毫克每立方米",
"step": "1"
}
}
},
{
"identifier": "humidity",
"name": "湿度",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "%",
"unitName": "百分比",
"step": "1"
}
}
},
{
"identifier": "temperature",
"name": "温度",
"dataType": {
"type": "float",
"specs": {
"min": "-10",
"max": "50",
"unit": "℃",
"step": "0.1"
}
}
}
],
"outputData": []
},
{
"identifier": "get",
"name": "get",
"required": true,
"callType": "async",
"desc": "属性获取",
"method": "thing.service.property.get",
"inputData": [
"lightLux",
"PM25",
"hcho",
"co2",
"humidity",
"temperature"
],
"outputData": [
{
"identifier": "lightLux",
"name": "光照强度",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10000",
"unit": "Lux",
"unitName": "照度",
"step": "0.1"
}
}
},
{
"identifier": "PM25",
"name": "PM25",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "1000",
"unit": "μg/m³",
"unitName": "微克每立方米",
"step": "1"
}
}
},
{
"identifier": "hcho",
"name": "甲醛",
"dataType": {
"type": "float",
"specs": {
"min": "0",
"max": "10",
"unit": "ppm",
"unitName": "百万分率",
"step": "0.1"
}
}
},
{
"identifier": "co2",
"name": "二氧化碳",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "10000",
"unit": "mg/m³",
"unitName": "毫克每立方米",
"step": "1"
}
}
},
{
"identifier": "humidity",
"name": "湿度",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "%",
"unitName": "百分比",
"step": "1"
}
}
},
{
"identifier": "temperature",
"name": "温度",
"dataType": {
"type": "float",
"specs": {
"min": "-10",
"max": "50",
"unit": "℃",
"step": "0.1"
}
}
}
]
}
]
}