云端解析设备透传数据

在物联网业务场景中,对于低配置且资源受限或者对网络流量有要求的设备,不适合直接构造JSON数据与物联网平台通信,可将原数据透传到物联网平台。物联网平台提供数据解析功能,可以根据您提交的脚本,先将数据在设备自定义格式和JSON格式之间转换,再进行业务处理。

背景信息

数据解析流程图如下所示。

iot

本文以环境数据采集设备为例,为您介绍数据解析具体操作步骤。

设备端接入物联网平台

  1. 登录物联网平台控制台

  2. 实例概览页签的全部环境下,找到对应的实例,单击实例卡片。

  3. 在左侧导航栏,选择设备管理 > 产品,单击创建产品,创建一个产品:环境监测传感器

    数据格式选择透传/自定义,其他使用默认设置。参数详细说明,请参见创建产品

  4. 产品创建成功后,单击前往定义物模型,添加物模型,然后发布上线。

    本文提供了示例的物模型TSL内容,您可批量导入,请参见批量添加物模型物模型属性

  5. 在左侧导航栏,选择设备,单击添加设备,在环境监测传感器产品下添加设备:Esensor

    设备创建成功后,获取设备证书信息(ProductKey、DeviceName和DeviceSecret)。

  6. 开发设备端,并测试运行。

    本示例使用物联网平台提供的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

编写数据解析脚本

在物联网平台控制台,编辑、提交脚本,并模拟数据解析。

  1. 在物联网平台控制台对应实例下的左侧导航栏,选择设备管理 > 产品

  2. 产品页面,单击产品对应的查看

  3. 产品详情页面,单击消息解析页签。

  4. 消息解析页签下的编辑脚本输入框中,输入数据解析脚本。

    根据设备数据协议内容编写解析脚本。本示例中的设备数据消息体结构如下表所示。

    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;
    }
  5. 测试数据解析。

    1. 选择模拟类型为设备上报数据

    2. 模拟输入下的输入框中,输入一个模拟数据。

      模拟数据可使用测试运行设备端后,在日志服务页面,查看到的设备端上报数据的Hex格式内容。例如:0xaa1fc800003710ff0005d76b15001c013400ad04ffff0400ffff18003000ff2e

    3. 单击执行

      右侧运行结果栏显示解析结果如下图所示。

      设备上报数据
  6. 确认脚本能正确解析数据后,单击提交,将脚本提交到物联网平台。

调试设备上报数据

脚本提交后,再次运行设备端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"
            }
          }
        }
      ]
    }
  ]
}