在物联网业务场景中,资源受限或配置较低的设备,不适合直接构造JSON数据与物联网平台通信,可将原数据直接透传到物联网平台。物联网平台会调用您提交的数据解析脚本,将设备上行数据解析为物联网平台定义的标准格式(Alink JSON),再进行业务处理。

背景信息

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

iot

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

设备端接入物联网平台

  1. 登录物联网平台控制台
  2. 在左侧导航栏,选择设备管理 > 产品,单击创建产品,创建一个产品:环境监测传感器
    数据格式选择透传/自定义,其他使用默认设置。
  3. 产品创建成功后,单击前往定义物模型,添加物模型,然后发布上线。
    本文提供了示例的物模型TSL内容,您可批量导入,请参见批量添加物模型物模型属性
  4. 在左侧导航栏,选择设备,单击添加设备,在环境监测传感器产品下添加设备:Esensor
    添加设备
    设备创建成功后,获取设备证书信息(ProductKey、DeviceName和DeviceSecret)。
  5. 开发设备端,并测试运行。
    本示例使用物联网平台提供的Node.js SDK开发设备,并设置设备端模拟上报ICA标准物模型数据,测试运行设备端SDK。

    设备端开发更多操作说明,请参见Link SDK

    SDK开发示例代码如下:

    const mqtt = require('aliyun-iot-mqtt');
    // 1. 设备身份信息
    var options = {
        productKey: "g4yf***",
        deviceName: "Esensor",
        deviceSecret: "e14f81***",
        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.上报环境数据
        client.publish(`/sys/${options.productKey}/${options.deviceName}/thing/event/property/post`, getPostData(), { qos: 0 });
    }, 5 * 1000);
    
    function getPostData() {
        const payloadJson = {
            id: Date.now(),
            version: "1.0",
            params: {
                PM25: Math.floor((Math.random() * 1000)),
                temperature: Math.floor((Math.random() * 60) - 10),
                humidity: Math.floor((Math.random() * 100)),
                co2: Math.floor((Math.random() * 10000)),
                hcho: Math.floor((Math.random() * 5)),
                lightLux: Math.floor((Math.random() * 10000))
            },
            method: "thing.event.property.post"
    
        }
        console.log("payloadJson " + JSON.stringify(payloadJson))
        return JSON.stringify(payloadJson);
    }
    设备端成功接入物联网平台后,在物联网平台控制台设备页,该设备状态显示为在线设备在线

    单击设备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"
            }
          }
        }
      ]
    }
  ]
}