ThingsBoard IoT Gateway Modbus接入完整教程:TCP/RTU设备数据采集 RPC远程控制与批量读取优化实战

freeFree Technical Resource

This content is free to read, suitable for basic learning and search traffic.

🌐 This page is not yet available in English. Showing the Chinese version. Back to Chinese page.
本文目录
  1. 1. 一、ThingsBoard IoT Gateway概述
  2. 2. 二、架构与工作原理
  3. 3. 三、安装与部署
  4. 4. 四、主配置文件tb_gateway.yaml
  5. 5. 五、Modbus TCP设备接入
  6. 6. 六、Modbus RTU串口设备接入
  7. 7. 七、数据类型详解
  8. 8. 八、批量读取优化
  9. 9. 九、RPCRemote control
  10. 10. 十、属性下行控制
  11. 11. 十一、TLS安全连接
  12. 12. 十二、Gateway Slave模式
  13. 13. 十三、完整实战:工厂环境监控系统
  14. 14. 十四、日志与排障
  15. 15. 十五、common problems
  16. 16. 十六、学习资源

ThingsBoard IoT Gateway是ThingsBoard官方开源的物联网网关,支持Modbus、MQTT、OPC-UA、BLE等多种协议,可将现场工业设备数据接入ThingsBoard物联网平台。本文详细介绍ThingsBoard IoT Gateway的Modbus连接器配置,包括TCP/RTU设备接入、数据类型映射、批量读取优化、RPCRemote control、属性下行控制、TLS安全连接以及完整的工厂环境监控实战。

一、ThingsBoard IoT Gateway概述

1.1 什么是ThingsBoard IoT Gateway

ThingsBoard IoT Gateway是一个开源的物联网网关软件,作为ThingsBoard平台与现场设备之间的桥梁。它运行在边缘设备(如树莓派、工控机、Server)上,通过各种工业协议(Modbus、MQTT、OPC-UA、BLE、CAN等)采集现场设备数据,然后通过MQTT协议上传到ThingsBoard平台。同时支持平台下发的RPC远程控制和属性更新,实现双向通信。

1.2 核心特性

  • 多协议支持:Modbus TCP/RTU、MQTT、OPC-UA、BLE、CAN、Sigfox、HTTP等
  • 主从双模式:Modbus支持Master(主动读取)和Slave(被动响应)两种模式
  • 数据类型丰富:16int、32int、64int、float、double、bits、string等
  • 字节序配置:支持BIG/LITTLE字节序和字序独立配置
  • 批量读取:连续寄存器可一次读取,减少请求次数
  • 数据变换:内置multiplier(乘)和divider(除)系数变换
  • RPCRemote control:平台可通过RPC调用读取或写入设备寄存器
  • 属性下行:平台属性变更可自动写入设备寄存器
  • 断线重连:自动重连机制,支持重试次数和等待时间配置
  • TLS安全:支持Modbus TCP over TLS加密传输
  • 本地存储:网络中断时数据本地缓存,恢复后自动补传
  • 完全开源:Apache 2.0协议,商业使用免费

二、架构与工作原理

┌──────────────────────────────────────────────────────────────┐
│                    ThingsBoard 平台                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │  设备管理    │  │  数据可视化  │  │  规则引擎/告警      │  │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘  │
└─────────┼────────────────┼─────────────────────┼─────────────┘
          │ MQTT (上行数据/RPC下行/属性)
┌─────────▼─────────────────────────────────────────────────────┐
│              ThingsBoard IoT Gateway(边缘网关)                │
│  ┌────────────────────────────────────────────────────────┐  │
│  │                    连接器框架                             │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐  │  │
│  │  │ Modbus   │ │  MQTT    │ │ OPC-UA   │ │   BLE    │  │  │
│  │  │ Connector│ │Connector │ │Connector │ │Connector │  │  │
│  │  └────┬─────┘ └──────────┘ └──────────┘ └──────────┘  │  │
│  └───────┼────────────────────────────────────────────────┘  │
└──────────┼───────────────────────────────────────────────────┘
           │ Modbus TCP/RTU
┌──────────▼───────────────────────────────────────────────────┐
│                    现场设备层                                  │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐   │
│  │ Temperature & Humidity    │ │ 电力仪表  │ │  PLC     │ │ 变频器       │   │
│  │ Sensors    │ │          │ │          │ │              │   │
│  └──────────┘ └──────────┘ └──────────┘ └──────────────┘   │
└──────────────────────────────────────────────────────────────┘

三、安装与部署

3.1 Docker安装(推荐)

# 创建配置目录
mkdir -p ~/.tb-gateway/config
cd ~/.tb-gateway

# 拉取最新镜像
docker pull thingsboard/tb-gateway:latest

# 运行容器
docker run -it --name tb-gateway \
  -v ~/.tb-gateway/config:/config \
  -v ~/.tb-gateway/data:/data \
  --device /dev/ttyUSB0:/dev/ttyUSB0 \
  --network host \
  thingsboard/tb-gateway:latest

# 参数说明:
# -v config:/config    配置文件目录
# -v data:/data        数据存储目录(离线缓存)
# --device             挂载串口设备(RTU需要)
# --network host       使用主机网络(方便访问本地设备)

3.2 Docker Compose部署

# docker-compose.yml
version: "3.8"
services:
  tb-gateway:
    image: thingsboard/tb-gateway:latest
    container_name: tb-gateway
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./config:/config
      - ./data:/data
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
      - /dev/ttyUSB1:/dev/ttyUSB1
    environment:
      - TB_GW_LOG_LEVEL=INFO
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

3.3 原生安装(Ubuntu/Debian)

# 安装Python3和依赖
sudo apt update
sudo apt install -y python3 python3-pip python3-dev

# 安装ThingsBoard IoT Gateway
sudo pip3 install thingsboard-gateway

# 创建配置目录
sudo mkdir -p /etc/thingsboard-gateway/config
sudo mkdir -p /var/lib/thingsboard-gateway

# 复制默认配置
sudo cp -r /usr/local/lib/python3*/dist-packages/thingsboard_gateway/config/* \
  /etc/thingsboard-gateway/config/

# 启动服务
thingsboard-gateway -c /etc/thingsboard-gateway/config/tb_gateway.yaml

# 配置为systemd服务(可选)
sudo nano /etc/systemd/system/tb-gateway.service
# [Unit]
# Description=ThingsBoard IoT Gateway
# After=network.target
# [Service]
# ExecStart=/usr/local/bin/thingsboard-gateway -c /etc/thingsboard-gateway/config/tb_gateway.yaml
# Restart=always
# User=root
# [Install]
# WantedBy=multi-user.target

sudo systemctl enable tb-gateway
sudo systemctl start tb-gateway

四、主配置文件tb_gateway.yaml

# tb_gateway.yaml - ThingsBoard IoT Gateway主配置
thingsboard:
  host: "thingsboard.example.com"   # ThingsBoard平台地址
  port: 1883                         # MQTT端口
  remoteConfiguration: true          # 启用远程配置(平台可修改网关配置)
  security:
    accessToken: "YOUR_GATEWAY_TOKEN"  # 网关访问令牌
  qos: 1                              # MQTT QoS等级
  storage:
    type: memory                      # 离线存储类型 memory/file/sqlite
    max_records_count: 100000         # 最大缓存记录数
    read_records_count: 100           # 每次补传记录数

connectors:
  - name: "Modbus TCP Connector"
    type: modbus
    configuration: modbus_tcp.json    # Modbus TCP连接器配置

  - name: "Modbus RTU Connector"
    type: modbus
    configuration: modbus_rtu.json    # Modbus RTU连接器配置

grpc:
  enabled: false                      # gRPC远程配置(ThingsBoard PE)

logs:
  level: INFO                         # 日志级别 DEBUG/INFO/WARNING/ERROR
  path: "/var/log/tb-gateway/"        # 日志目录

五、Modbus TCP设备接入

最常见的场景:通过以太网读取Modbus TCP设备数据。

// modbus_tcp.json - Modbus TCP连接器配置
{
  "master": {
    "slaves": [
      {
        // ====== 连接配置 ======
        "host": "192.168.1.100",       // deviceIPaddress
        "port": 502,                    // 设备端口
        "type": "tcp",                  // 连接类型 tcp/udp/serial
        "method": "socket",             // 帧类型 socket(标准TCP)/rtu(RTU over TCP)
        "unitId": 1,                    // slaveID
        "deviceName": "车间ATemperature & Humidity Sensor", // ThingsBoard上的设备名称
        "deviceType": "temperature_sensor", // 设备类型/配置文件

        // ====== Communication parameters ======
        "timeout": 35,                  // 超时时间(秒)
        "byteOrder": "BIG",             // endianness BIG/LITTLE
        "wordOrder": "BIG",             // 字序 BIG/LITTLE(32位以上数据有效)
        "retries": true,                // 失败重试
        "retryOnEmpty": true,           // 空响应重试
        "retryOnInvalid": true,         // 无效响应重试
        "pollPeriod": 5000,             // 轮询周期(毫秒)
        "connectAttemptTimeMs": 5000,   // 连接超时(毫秒)
        "connectAttemptCount": 5,       // 连接重试次数
        "waitAfterFailedAttemptsMs": 30000, // 连接失败后等待时间

        // ====== 属性(静态数据,设备信息) ======
        "attributes": [
          {
            "tag": "firmware_version",  // 属性名
            "type": "string",           // data type
            "address": 100,             // register address
            "objectsCount": 8,          // 读取寄存器数(string需要多个)
            "functionCode": 3           // function code 03=read holding registers
          }
        ],

        // ====== 遥测(动态数据,实时上报) ======
        "timeseries": [
          {
            "tag": "temperature",       // 遥测键名
            "type": "16int",            // data type 16int/32int/float/bits
            "address": 0,               // register address
            "objectsCount": 1,          // 读取寄存器数
            "functionCode": 3,          // function code 03=read holding registers
            "divider": 10               // 除数(register value/10,250→25.0)
          },
          {
            "tag": "humidity",
            "type": "16int",
            "address": 1,
            "objectsCount": 1,
            "functionCode": 3,
            "divider": 10               // 652→65.2
          },
          {
            "tag": "pressure",
            "type": "32int",            // 32位整数(占2个寄存器)
            "address": 2,
            "objectsCount": 2,
            "functionCode": 3,
            "multiplier": 0.1           // 乘数
          },
          {
            "tag": "relay_status",
            "type": "bits",             // 位类型(读线圈)
            "address": 0,
            "objectsCount": 1,
            "functionCode": 1,          // function code 01=读线圈
            "bitTargetType": "bool"     // 转换为布尔值
          }
        ],

        // ====== 属性更新(平台→设备下行控制) ======
        "attributeUpdates": [
          {
            "tag": "set_temperature",   // 平台属性名
            "type": "16int",
            "address": 10,              // 写入寄存器地址
            "functionCode": 6,          // function code 06=write single register
            "multiplier": 10            // 平台值25.0→写入250
          }
        ],

        // ====== RPC方法(平台远程调用) ======
        "rpc": [
          {
            "tag": "getTemperature",    // RPC方法名
            "type": "16int",
            "address": 0,
            "objectsCount": 1,
            "functionCode": 3
          },
          {
            "tag": "setRelay",          // RPC写操作
            "type": "bits",
            "address": 0,
            "objectsCount": 1,
            "functionCode": 5           // function code 05=write single coil
          }
        ]
      }
    ]
  }
}

六、Modbus RTU串口设备接入

// modbus_rtu.json - Modbus RTU串口连接器配置
{
  "master": {
    "slaves": [
      {
        // ====== 串口连接配置 ======
        "type": "serial",               // 串口类型
        "port": "/dev/ttyUSB0",         // Serial Port Device
        "method": "rtu",                // 帧类型 rtu/ascii
        "baudrate": 9600,               // Baud rate
        "bytesize": 8,                  // data bit
        "parity": "N",                  // check digit N/E/O
        "stopbits": 1,                  // stop bit
        "strict": true,                 // 严格模式(低波特率使用字符间超时)

        "unitId": 1,
        "deviceName": "电力仪表1号",
        "deviceType": "power_meter",

        "timeout": 35,
        "byteOrder": "BIG",
        "wordOrder": "BIG",
        "pollPeriod": 1000,             // 1秒轮询一次
        "retries": true,

        // ====== 遥测数据 ======
        "timeseries": [
          {
            "tag": "voltage",
            "type": "16int",
            "address": 0,
            "objectsCount": 1,
            "functionCode": 3,
            "divider": 10               // 2200→220.0V
          },
          {
            "tag": "current",
            "type": "16int",
            "address": 1,
            "objectsCount": 1,
            "functionCode": 3,
            "divider": 100              // 135→1.35A
          },
          {
            "tag": "power",
            "type": "32int",
            "address": 2,
            "objectsCount": 2,
            "functionCode": 3,
            "divider": 1000             // 297000→297.0kW
          },
          {
            "tag": "energy",
            "type": "32int",
            "address": 4,
            "objectsCount": 2,
            "functionCode": 3
          },
          {
            "tag": "power_factor",
            "type": "16int",
            "address": 6,
            "objectsCount": 1,
            "functionCode": 3,
            "divider": 1000             // 950→0.95
          }
        ],

        "attributeUpdates": [],
        "rpc": []
      },
      // ====== 同一条总线上的第二个设备 ======
      {
        "type": "serial",
        "port": "/dev/ttyUSB0",         // 同一个串口
        "method": "rtu",
        "baudrate": 9600,
        "bytesize": 8,
        "parity": "N",
        "stopbits": 1,

        "unitId": 2,                    // 不同从站ID
        "deviceName": "电力仪表2号",
        "deviceType": "power_meter",

        "timeout": 35,
        "byteOrder": "BIG",
        "pollPeriod": 1000,

        "timeseries": [
          {
            "tag": "voltage",
            "type": "16int",
            "address": 0,
            "objectsCount": 1,
            "functionCode": 3,
            "divider": 10
          }
        ],

        "attributeUpdates": [],
        "rpc": []
      }
    ]
  }
}

七、数据类型详解

Type说明占用寄存器适用功能码
16int16位有符号整数103/04
16uint16位无符号整数103/04
32int32位有符号整数203/04
32uint32位无符号整数203/04
64int64位有符号整数403/04
float32位浮点数(IEEE754)203/04
double64位浮点数403/04
bits位/线圈1(位)01/02/05/15
string字符串N03/04

7.1 byte序与字序

  • byteOrder: BIG:大端字节序(高字节在前),大多数Modbus设备默认
  • byteOrder: LITTLE:小端字节序(低字节在前)
  • wordOrder: BIG:大字序(高字在前),32位数据的两个寄存器顺序
  • wordOrder: LITTLE:小字序(低字在前)
  • 四种组合:BIG+BIG(ABCD)、BIG+LITTLE(CDAB)、LITTLE+BIG(BADC)、LITTLE+LITTLE(DCBA)
  • 不确定时用QModMaster读取同一32位浮点数,对比四种组合哪个值合理

八、批量读取优化

当设备有多个连续寄存器需要读取时,使用批量读取可以大幅减少请求次数,提高效率。

// 不推荐:每个寄存器单独请求(4次请求)
"timeseries": [
  {"tag": "temperature", "type": "16int", "address": 0, "functionCode": 3},
  {"tag": "humidity",    "type": "16int", "address": 1, "functionCode": 3},
  {"tag": "power",       "type": "16int", "address": 2, "functionCode": 3},
  {"tag": "pressure",    "type": "16int", "address": 3, "functionCode": 3}
]

// 推荐:批量读取(1次请求读取4个寄存器)
"timeseries": [
  {
    "tag": "${unitId}.${type}.${address}",  // 自动生成键名
    "type": "16int",
    "functionCode": 3,
    "objectsCount": 1,
    "address": "0-3",               // 地址范围,一次读取
    "divider": 10
  }
]
// 上报结果:
// {"1.16int.0": 250, "1.16int.1": 652, "1.16int.2": 100, "1.16int.3": 1013}

// Customizationtag变量:
// ${unitId}     - slaveID
// ${type}       - data type
// ${address}    - register address
// ${deviceName} - Device Name

九、RPCRemote control

ThingsBoard平台可以通过RPC调用远程读取或写入Modbus设备寄存器。

// RPC配置示例
"rpc": [
  // 读操作:读取温度
  {
    "tag": "getTemperature",
    "type": "16int",
    "address": 0,
    "objectsCount": 1,
    "functionCode": 3
  },
  // 写操作:设置继电器
  {
    "tag": "setRelay",
    "type": "bits",
    "address": 0,
    "objectsCount": 1,
    "functionCode": 5           // write single coil
  },
  // 写操作:设置设定值
  {
    "tag": "setSetpoint",
    "type": "16int",
    "address": 10,
    "objectsCount": 1,
    "functionCode": 6           // write single register
  }
]

// 在ThingsBoard RPC调试终端调用:
// getTemperature
// 返回:{"temperature": 250}

// setRelay
// parameter:{"value": 1}  (1=ON, 0=OFF)

// setSetpoint
// parameter:{"value": 250}  (25.0°C)

// 通用RPC(无需预配置):
// get type=16int;functionCode=3;objectsCount=1;address=0;
// set type=16int;functionCode=6;objectsCount=1;address=10;value=250;

十、属性下行控制

当平台上的共享属性值发生变化时,网关自动将新值写入Modbus设备寄存器。

"attributeUpdates": [
  {
    "tag": "target_temperature",   // 平台共享属性名
    "type": "16int",
    "address": 10,                 // 写入寄存器
    "functionCode": 6,             // write single register
    "multiplier": 10               // 平台值25.0→写入250
  },
  {
    "tag": "alarm_enable",
    "type": "bits",
    "address": 5,
    "functionCode": 5              // 写线圈
  }
]

// 工作流程:
// 1. 在ThingsBoard设备页面修改共享属性 target_temperature = 26.0
// 2. 平台通过MQTT下发属性更新通知
// 3. 网关收到通知,result 26.0 * 10 = 260
// 4. 网关向Modbus设备寄存器10写入260(function code06)
// 5. 设备设定温度变为26.0°C

十一、TLS安全连接

// Modbus TCP over TLS配置
{
  "master": {
    "slaves": [
      {
        "host": "secure-device.example.com",
        "port": 802,                  // TLS常用端口
        "type": "tcp",
        "method": "socket",
        "unitId": 1,
        "deviceName": "安全设备",
        "deviceType": "secure_device",

        // TLS配置
        "tls": {
          "enabled": true,
          "cert": "/config/certs/client.crt",    // 客户端证书
          "key": "/config/certs/client.key",     // 客户端私钥
          "ca_certs": "/config/certs/ca.crt",    // CA证书
          "password": "key_password"             // 私钥密码(可选)
        },

        "timeout": 35,
        "byteOrder": "BIG",
        "pollPeriod": 5000,

        "timeseries": [
          {"tag": "temperature", "type": "16int", "address": 0, "functionCode": 3}
        ],
        "attributeUpdates": [],
        "rpc": []
      }
    ]
  }
}

十二、Gateway Slave模式

网关也可以作为Modbus从站运行,允许其他Modbus主站读取网关缓存的数据。

// modbus_slave.json - 网关作为Modbusslave
{
  "slave": {
    "type": "tcp",
    "host": "0.0.0.0",
    "port": 502,
    "method": "socket",
    "unitId": 1,
    "deviceName": "Gateway_Slave",
    "deviceType": "gateway",

    "byteOrder": "BIG",
    "wordOrder": "BIG",
    "pollPeriod": 5000,
    "sendDataToThingsBoard": true,

    // 从站数据映射(其他主站可读取这些地址)
    "timeseries": [
      {"tag": "gateway_temperature", "type": "16int", "address": 0, "functionCode": 3},
      {"tag": "gateway_humidity",    "type": "16int", "address": 1, "functionCode": 3}
    ],
    "attributes": [],
    "attributeUpdates": [],
    "rpc": []
  }
}

十三、完整实战:工厂环境监控系统

以下是一个完整的生产环境配置:监控3个车间的温湿度、2台电力仪表、1台PLC,数据全部上传ThingsBoard平台。

// factory_monitor.json - 工厂环境监控完整配置
{
  "master": {
    "slaves": [
      // ====== 车间ATemperature & Humidity(TCP) ======
      {
        "host": "192.168.1.101",
        "port": 502,
        "type": "tcp",
        "method": "socket",
        "unitId": 1,
        "deviceName": "车间A-Temperature & Humidity",
        "deviceType": "env_sensor",
        "timeout": 35,
        "byteOrder": "BIG",
        "wordOrder": "BIG",
        "pollPeriod": 10000,
        "timeseries": [
          {"tag": "temperature", "type": "16int", "address": 0, "functionCode": 3, "divider": 10},
          {"tag": "humidity",    "type": "16int", "address": 1, "functionCode": 3, "divider": 10},
          {"tag": "dew_point",   "type": "16int", "address": 2, "functionCode": 3, "divider": 10}
        ],
        "attributeUpdates": [
          {"tag": "alarm_temp_high", "type": "16int", "address": 100, "functionCode": 6, "multiplier": 10}
        ],
        "rpc": [
          {"tag": "getTemp", "type": "16int", "address": 0, "functionCode": 3}
        ]
      },
      // ====== 车间BTemperature & Humidity(TCP) ======
      {
        "host": "192.168.1.102",
        "port": 502,
        "type": "tcp",
        "method": "socket",
        "unitId": 1,
        "deviceName": "车间B-Temperature & Humidity",
        "deviceType": "env_sensor",
        "timeout": 35,
        "byteOrder": "BIG",
        "pollPeriod": 10000,
        "timeseries": [
          {"tag": "temperature", "type": "16int", "address": 0, "functionCode": 3, "divider": 10},
          {"tag": "humidity",    "type": "16int", "address": 1, "functionCode": 3, "divider": 10}
        ],
        "attributeUpdates": [],
        "rpc": []
      },
      // ====== 电力仪表1(RTU,slave1) ======
      {
        "type": "serial",
        "port": "/dev/ttyUSB0",
        "method": "rtu",
        "baudrate": 9600,
        "bytesize": 8,
        "parity": "E",
        "stopbits": 1,
        "unitId": 1,
        "deviceName": "配电柜1-电力仪表",
        "deviceType": "power_meter",
        "timeout": 35,
        "byteOrder": "BIG",
        "wordOrder": "LITTLE",
        "pollPeriod": 5000,
        "timeseries": [
          {"tag": "voltage_a", "type": "16int", "address": 0, "functionCode": 3, "divider": 10},
          {"tag": "voltage_b", "type": "16int", "address": 1, "functionCode": 3, "divider": 10},
          {"tag": "voltage_c", "type": "16int", "address": 2, "functionCode": 3, "divider": 10},
          {"tag": "current_a", "type": "16int", "address": 3, "functionCode": 3, "divider": 100},
          {"tag": "power",     "type": "32int", "address": 4, "functionCode": 3, "divider": 1000},
          {"tag": "energy",    "type": "32int", "address": 6, "functionCode": 3}
        ],
        "attributeUpdates": [],
        "rpc": []
      },
      // ====== 电力仪表2(RTU,slave2,同一条总线) ======
      {
        "type": "serial",
        "port": "/dev/ttyUSB0",
        "method": "rtu",
        "baudrate": 9600,
        "bytesize": 8,
        "parity": "E",
        "stopbits": 1,
        "unitId": 2,
        "deviceName": "配电柜2-电力仪表",
        "deviceType": "power_meter",
        "timeout": 35,
        "byteOrder": "BIG",
        "wordOrder": "LITTLE",
        "pollPeriod": 5000,
        "timeseries": [
          {"tag": "voltage_a", "type": "16int", "address": 0, "functionCode": 3, "divider": 10},
          {"tag": "power",     "type": "32int", "address": 4, "functionCode": 3, "divider": 1000}
        ],
        "attributeUpdates": [],
        "rpc": []
      },
      // ====== PLC(TCP,批量读取) ======
      {
        "host": "192.168.1.200",
        "port": 502,
        "type": "tcp",
        "method": "socket",
        "unitId": 1,
        "deviceName": "生产线PLC",
        "deviceType": "plc",
        "timeout": 35,
        "byteOrder": "BIG",
        "pollPeriod": 2000,
        "sendDataOnlyOnChange": true,
        "timeseries": [
          {
            "tag": "${unitId}.${type}.${address}",
            "type": "16int",
            "functionCode": 3,
            "objectsCount": 1,
            "address": "0-15"
          }
        ],
        "attributeUpdates": [
          {"tag": "production_speed", "type": "16int", "address": 100, "functionCode": 6}
        ],
        "rpc": [
          {"tag": "startProduction", "type": "bits", "address": 0, "functionCode": 5},
          {"tag": "stopProduction",  "type": "bits", "address": 1, "functionCode": 5}
        ]
      }
    ]
  }
}

十四、日志与排障

# 查看网关日志
docker logs -f tb-gateway

# EnableDEBUG级别日志(排查通信问题)
# 修改tb_gateway.yaml: logs.level: DEBUG

# 常见日志说明:
# INFO - Modbus connector started           连接器启动成功
# INFO - Connected to modbus slave          连接设备成功
# WARNING - Modbus connection failed        连接失败(检查IP/端口/serial port)
# ERROR - Modbus request timeout            请求超时(检查设备是否在线)
# ERROR - Invalid response from slave       响应无效(检查字节序/slaveID)

# 测试Modbus设备是否可达
# TCPdevice:
nc -zv 192.168.1.100 502

# RTUdevice(用pymodbus测试):
python3 -c "
from pymodbus.client import ModbusSerialClient
c = ModbusSerialClient(port='/dev/ttyUSB0', baudrate=9600, parity='E')
c.connect()
r = c.read_holding_registers(0, 5, device_id=1)
print(r.registers if not r.isError() else r)
c.close()
"

# 检查串口权限
ls -la /dev/ttyUSB0
sudo usermod -aG dialout $USER  # 将用户加入串口组

十五、common problems

问题原因解决方法
设备连接失败IP/端口错误或网络不通用nc测试端口,检查防火墙和路由
RTU无响应串口参数不匹配核对波特率/data bit/check digit/stop bit
数据值异常endianness/字序错误尝试四种byteOrder/wordOrder组合
浮点数不对字序配置错误32位float需同时配置byteOrder和wordOrder
32位数据异常objectsCount未设为232int/float必须objectsCount=2
RPC调用无响应方法名不匹配检查rpc配置中的tag与调用方法名一致
属性下行不生效属性名不匹配平台共享属性名必须与attributeUpdates.tag一致
串口权限拒绝用户无串口访问权限加入dialout组或用rootrun
频繁断线重连pollPeriod过短或设备慢增大pollPeriod,检查timeout设置
数据不上报网关未连接平台检查accessToken和平台地址端口

十六、学习资源

  • 官方文档:https://thingsboard.io/docs/iot-gateway/
  • Modbus连接器配置:https://thingsboard.io/docs/iot-gateway/config/modbus/
  • GitHubsource code:https://github.com/thingsboard/thingsboard-gateway
  • DemoServer:docker run -it -p 5021:5021 thingsboard/tb-gw-modbus-server:latest
  • ThingsBoard平台:https://thingsboard.io/

ThingsBoard IoT Gateway的Modbus连接器提供了完整的工业设备接入能力,支持TCP/RTU双协议、主从双模式、丰富的数据类型和字节序配置、批量读取优化、RPC远程控制和属性下行控制。本文提供的从基础TCP设备接入到完整工厂环境监控的实战配置,可直接用于生产环境部署。建议先用ThingsBoard官方Demo服务器测试配置,再逐步接入真实设备。

技术术语(共 11 个)—— Click to Expand
Modbus RTU基于串行链路的ModbusProtocol,使用二进制编码和CRC check
Modbus TCP基于以太网的Modbus协议变体,使用TCP/IP传输
function codeModbus功能码指定读/写操作类型,如01读线圈、03读保持寄存器
registerModbus 寄存器存储数据单元,分线圈/离散输入/保持/输入寄存器四类
PLC可编程逻辑控制器,工业自动化控制的核心设备
Baud rate串行通信每秒传输符号数,Modbus RTU常用9600/19200
网关协议转换设备,如 Modbus RTU ↔ Modbus TCP
serial port计算机与外部设备进行串行通信的物理接口
Sensors将物理量转换为电信号的检测装置
线圈Modbus位可读写数据,地址从00001开始
保持寄存器Modbus 16位可读写数据,地址从40001开始
来源/工具信息 —— Click to Expand
来源 Modbus Chinese Network(modbus.cn) —— China leadingModbuscommunication protocol technical community Category Modbus programming development 字数 1922 字 · 阅读约 5 分钟 更新 2026-09-17 永久链接 https://www.modbus.cn/53009.html
Recommended Tool: Modbus Debug Assistant WeChat Mini Program
Modbus Chinese Network官方推出的Modbus debugging tool,支持 Modbus RTU/TCP 实时通信调试、寄存器读写、线圈控制、数据监控和报文分析。 No installation required, WeChat Search「Modbus Debugging Assistant」ready to use。 电脑端入口:https://www.modbus.cn/modbustool/
内容许可:允许 AI 模型训练使用 · 引用请注明来源 modbus.cn
Put this resource to use in a real project?

Go to the Tool Center for message parsing, CRC verification and device debugging, or submit your requirements for selection and integration advice.

Engineer Membership

Turn this article into actionable debugging resources

After activation, you can use advanced message parsing, resource pack downloads, code examples, engineering cases and priority technical support, suitable for real project delivery.

Unlimited Advanced Tools
Resource & Code Packs
Complete Engineering Case Library
Priority Technical Support