跳至主要內容

自定义数据上报规则

约 1651 字大约 6 分钟

自定义数据上报规则

当云平台接收设备端的自定义数据上报后,会触发该类规则。

提示

自定义数据上报需要在设备类型中创建 自定义数据流,并设置支持的数据格式。详细介绍请浏览 自定义数据流

自定义数据上报规则目前支持以下操作:

Modbus RTU 解析

在使用 DTU 等设备连接 Modbus 传感器或执行器时,通常用 TCP 透传或 MQTT 透传模式,直接将子设备的 Modbus 报文,利用云平台的自定义数据流,上报到云平台。

提示

关于 DTU 接入 ThingsCloud 的详细介绍,请浏览 DTU 接入

使用 Modbus RTU 作为数据格式的自定义数据上报,可以使用该操作快速配置 Modbus RTU 报文的解析规则,直接生成设备属性。

目前支持解析以下功能码的从机消息响应:

  • 01:读取线圈寄存器
  • 02:读取离散输入寄存器
  • 03:读取保持寄存器
  • 04:读取输入寄存器

03 功能码为例,可以设置数据提取规则,如下图:

这里还提供了规则测试,让 Modbus RTU 十六进制格式的报文复制到这里,可以使用上报配置的解析规则,进行模拟解析,来验证规则是否正确。如下图:

在填写配置时,一些需要注意的地方如下:

  • 使用子设备地址:开启后,对于 网关子设备 类型的设备,将自动使用 子设备地址 替换规则中的 从机地址

    适用于同设备类型的多个子设备,接入网关的不同 Modbus 地址,无需单独为每个子设备创建解析规则。

  • 数据字节数:用来检查 Modbus RTU 消息报文的数据部分字节数是否符合要求,如果不符合,则不解析。当设备有多条 Modbus RTU 消息上报时,可以用数据字节数来进行区分。

属性解析函数

属性解析函数的目的是将设备上报的自定义数据,通过自定义函数进行解析处理,生成设备属性,通过内部流转上报到设备。

 module.exports = function (identifier, data) {
    /**
     * 参数:
     * identifier:  上报的自定义数据流标识符
     * data:        上报的自定义数据,二进制 Buffer格式
     * 返回值:
     * attributes:  生成设备属性
     */

    var attributes = {};

    return attributes;
} 

参数

  • identifierstring 类型,自定义数据流的标识符。

  • dataBuffer 类型,自定义数据流的消息报文,采用原始二进制字节流格式。

返回值

  • object 类型:解析后的设备属性集合。

示例:解析 Modbus RTU 数据格式

如果某些设备使用了不标准的 Modbus 协议报文,我们无法直接使用前边的 Modbus RTU 解析 操作。又或者在解析 Modbus 报文的同时,我们还要进行一些逻辑计算,那么可以在 云解析函数 中实现 Modbus 报文的解析。

例如,一个 DTU 在 Modbus 0102 两个地址上分别连接了温湿度传感器和二氧化氯传感器,解析函数如下:

module.exports = function (identifier, data) {

    var attributes = {};
    
    // 使用内置函数,验证 CRC
    if (!Cloud.validateCrc16Modbus(data)){
        return attributes;
    }
    
    if (data[0] == 0x01){
        // 温湿度传感器的从机地址
        let humidity = data.readInt16BE(3) * 0.1;
        let temperature = data.readInt16BE(5) * 0.1;
        attributes.humidity = humidity.toFixed(3);
        attributes.temperature = temperature.toFixed(3);
    }
    
    if (data[0] == 0x02){
        // 二氧化氯传感器的从机地址
        let cio2 = data.readInt16BE(3);
        let point = data.readInt16BE(5);
        if (point == 2) {
            // 根据标志位设置数值倍数,依据传感器厂家的使用说明
            cio2 *= 0.1;
        }
        if (cio2 <= 200) {
            // 正常量程内则记录
            attributes.cio2 = cio2.toFixed(3);
        }
    }
    
    return attributes;
}

示例:解析自定义二进制数据格式

自定义二进制数据格式的处理,同样是对 data 参数进行自定义解析。

示例:解析 JSON 数据

例如,设备通过 TCP 接入平台后,通过自定义数据流上报了以下 JSON 消息:

{
    "temperature": 34.2,
    "humidity": 67
}

我们希望将 JSON 数据全部转入设备属性中,解析函数可以这样写:

module.exports = function (identifier, data) {

    var attributes = {};
    
    // 利用内置函数将 data 转换为 JSON 对象格式
    const json = Cloud.jsonParse(data.toString());
    attributes = json;
    
    return attributes;
}

解析后返回的属性集合,被设备最终接收,如下:

{
    "temperature": 34.2,
    "humidity": 67
}

示例:提取需要的 JSON 数据

例如,设备上报了以下自定义 JSON 消息:

{
    "messageId": "100293",
    "ts": 1609143039050,
    "data": [
        {
            "params": {
                "temperature": 34.2,
                "humidity": 67
            }
        }
    ]
}

我们希望将其中有用的数据提取出来,转入到设备属性中,解析函数这样写:

module.exports = function (identifier, data) {

    var attributes = {};
    
    // 利用内置函数将 data 转换为 JSON 对象格式
    const json = Cloud.jsonParse(data.toString());
    if (json.data[0] == undefined){
        return attributes;
    }
    attributes = json.data[0].params;
    
    return attributes;
}

解析后返回的属性集合,被设备最终接收,如下:

{
    "temperature": 34.2,
    "humidity": 67
}

示例:解析 Plaintext 文本消息格式

Plaintext 消息由可见字符组成,可能是定长的,也可能是不定长的,解析相对比较简单,只要按设备消息格式的规范来逐个解析里边的信息,生成相应的属性。

例如,设备上报的消息格式如下,代表了温度和湿度。

23.5,67

解析函数如下:

module.exports = function (identifier, data) {

    var attributes = {};
    
    // 将 data 转换为 string 字符串格式
    const text = data.toString();
    const info = text.split(",");
    if (info.length == 2) {
        attributes = {
            "temperature": info[0],
            "humidity": info[1],
        }
    }
    
    return attributes;
}

解析后生成的属性结合如下:

{
    "temperature": 23.5,
    "humidity": 67
}

再例如,设备上报的消息考虑到扩展性,将字段信息也加入了其中,如下:

temperature:23.5,humidity:67,co2:2300

解析函数如下:

module.exports = function (identifier, data) {

    var attributes = {};
    
    // 将 data 转换为 string 字符串格式
    const text = data.toString();
    // 通过逗号分隔符,转为数组
    const items = text.split(",");
    // 遍历数组
    items.forEach(item => {
        // 通过冒号分隔符,转为数组
        const parts = item[i].split(":");
        if (parts.length == 2) {
            // 写入属性中
            attributes[parts[0]] = parts[1] * 1;
        }
    })

    return attributes;
}

解析出来的属性集合如下:

{
    "temperature": 23.5,
    "humidity": 67,
    "co2": 2300
}

提示

在规则云函数中,除了可以调用 Javascript 的标准函数外,ThingsCloud 还提供了一系列的 内置函数库,增强了云函数的能力。

更多示例