Modbus TCP 数据采集与可视化

最近更新:

介绍

Modbus 是工业自动化中常见的通信协议,可以用于读取 PLC、仪表及其他工业设备的数据。通过 Home Assistant 的 Modbus 集成,开发者可以将寄存器数据转换为传感器实体,并在 Web 页面中展示实时状态和历史变化。

本教程基于 reComputer RK3576 和 Home Assistant Container,演示如何通过 Modbus TCP 读取温度、湿度数据,并创建监控 Dashboard。为方便复现,我们在 RK3576 本机运行一个 Python Modbus TCP 模拟器,不需要额外购买 PLC 或传感器。

实现架构

text
Python Modbus TCP 模拟器
     127.0.0.1:1502
            ↓
     reComputer RK3576
            ↓
 Home Assistant Container
            ↓
 实时温湿度 / 历史曲线

开始使用

硬件准备

  • reComputer RK3576 一台,运行 ARM64 Linux 系统。
  • 一台可通过 SSH 和浏览器访问 RK3576 的 Windows、macOS 或 Linux 电脑。
  • 可访问 RK3576 的局域网。

本示例使用 Modbus TCP,不依赖 RK3576 的 RS485 接口。

软件准备

项目本教程环境
RK3576 系统Armbian / Debian 12 Bookworm(ARM64)
PythonPython 3.11
Home AssistantHome Assistant Container,Docker 部署
Modbus 模拟服务127.0.0.1:1502
Home Assistant WebUI端口 8123

请先完成前一篇《在 reComputer RK3576 上安装 Home Assistant》中的 Docker 部署及首次初始化。检查环境:

bash
python3 --version
sudo docker ps --filter name=homeassistant
sudo docker inspect homeassistant --format '{{.HostConfig.NetworkMode}}'

上述网络模式应为 host。这样 Home Assistant 容器就能访问运行在 RK3576 主机 127.0.0.1:1502 上的模拟器。

创建 Modbus TCP 数据源

步骤 1:编写 Python 模拟器

通过 SSH 登录 RK3576,在终端完整复制以下命令,在当前用户的家目录创建 ~/modbus_demo.py:

bash
cat > ~/modbus_demo.py <<'PY'
import math
import socketserver
import struct
import time


class ModbusHandler(socketserver.BaseRequestHandler):
    def read_exact(self, size):
        data = b""
        while len(data) < size:
            chunk = self.request.recv(size - len(data))
            if not chunk:
                return None
            data += chunk
        return data

    def handle(self):
        try:
            while True:
                header = self.read_exact(7)
                if not header:
                    break

                tid, pid, length, unit = struct.unpack(">HHHB", header)
                if pid != 0 or not 2 <= length <= 254:
                    break

                request = self.read_exact(length - 1)
                if not request:
                    break

                function = request[0]
                if function == 3 and len(request) == 5:
                    address, count = struct.unpack(">HH", request[1:])

                    if count < 1 or count > 2 or address + count > 2:
                        response = bytes([0x83, 2])
                    else:
                        temperature = round(
                            (25 + 2 * math.sin(time.monotonic() / 20)) * 10
                        )
                        humidity = round(
                            (60 + 10 * math.sin(time.monotonic() / 30)) * 10
                        )
                        registers = [temperature, humidity]
                        response = bytes([3, count * 2]) + b"".join(
                            struct.pack(">H", value)
                            for value in registers[address:address + count]
                        )
                else:
                    response = bytes([function | 0x80, 1])

                reply = struct.pack(">HHHB", tid, 0, len(response) + 1, unit) + response
                self.request.sendall(reply)
        except (OSError, ConnectionError):
            pass


class ModbusServer(socketserver.ThreadingTCPServer):
    allow_reuse_address = True
    daemon_threads = True


with ModbusServer(("127.0.0.1", 1502), ModbusHandler) as server:
    print("Modbus TCP server running at 127.0.0.1:1502", flush=True)
    server.serve_forever()
PY

模拟器通过 Modbus 功能码 03 读取 Holding Registers,分别提供:

地址(从 0 开始)内容原始值显示值
0温度约 230–270约 23–27 °C
1湿度约 500–700约 50–70%

Home Assistant 使用 scale: 0.1 将寄存器原始值转换为摄氏度和百分比。数值会随时间变化,便于展示实时监控效果。

步骤 2:运行模拟器

启动模拟器:

bash
nohup python3 ~/modbus_demo.py > ~/modbus_demo.log 2>&1 &

确认程序正在监听:

bash
ss -lntp | grep ':1502'
cat ~/modbus_demo.log

正常情况下应看到 127.0.0.1:1502 监听地址以及:

text
Modbus TCP server running at 127.0.0.1:1502

这是一个演示程序,采用 nohup 在后台运行。RK3576 重新启动后,需要重新运行上述启动命令。启动前可以先检查端口,避免重复运行导致端口占用。

在 Home Assistant 中配置 Modbus TCP

步骤 3:编辑 configuration.yaml

由于本教程使用的是 Home Assistant Container,无需安装 File Editor 插件。直接通过 SSH 编辑挂载在 RK3576 上的配置文件即可。

备份原有配置:

bash
sudo cp ~/homeassistant/config/configuration.yaml \
  ~/homeassistant/config/configuration.yaml.bak

使用管理员权限打开配置文件:

bash
sudo nano ~/homeassistant/config/configuration.yaml

保留已有配置(例如 default_config:、frontend: 等),将下面内容添加到文件末尾:

yaml
modbus:
  - name: rk3576_demo
    type: tcp
    host: 127.0.0.1
    port: 1502

    sensors:
      - name: RK3576 Room Temperature
        unique_id: rk3576_demo_temperature
        slave: 1
        address: 0
        input_type: holding
        data_type: uint16
        scale: 0.1
        precision: 1
        unit_of_measurement: "°C"
        device_class: temperature
        state_class: measurement
        scan_interval: 5

      - name: RK3576 Room Humidity
        unique_id: rk3576_demo_humidity
        slave: 1
        address: 1
        input_type: holding
        data_type: uint16
        scale: 0.1
        precision: 1
        unit_of_measurement: "%"
        device_class: humidity
        state_class: measurement
        scan_interval: 5

主要参数说明:

参数作用
type: tcp使用 Modbus TCP
host: 127.0.0.1模拟器的本机地址
port: 1502模拟器监听端口
slave: 1Modbus 从站 ID
address: 0 / 1温度 / 湿度寄存器地址
input_type: holding读取 Holding Registers
scale: 0.1将寄存器原始值缩放为实际显示值
scan_interval: 5每 5 秒轮询一次

注意:如果 configuration.yaml 已经包含一个 modbus: 顶层配置,请将新的 hub 合并到已有列表,不要重复声明 modbus:。

按 Ctrl + O、Enter 保存,随后按 Ctrl + X 退出 nano。

步骤 4:检查配置并重启容器

先验证 Home Assistant 配置:

bash
sudo docker exec homeassistant \
  python -m homeassistant --script check_config --config /config

确认检查通过,再重启 Home Assistant:

bash
sudo docker restart homeassistant

在电脑浏览器中访问:

text
http://<RK3576_IP>:8123

查看 Modbus 传感器

步骤 5:确认数据已被读取

在新版 Home Assistant WebUI 中进入 Settings → Tools → States,搜索 rk3576,确认以下传感器存在且显示实际数值:

  • RK3576 Room Temperature
  • RK3576 Room Humidity

也可以通过 Overview → 编辑概览页面 → Favorite entities → Add favorite 把这两个传感器显示在概览页。

确认 RK3576 Modbus 温湿度传感器

创建 Modbus 监控 Dashboard

步骤 6:创建 Dashboard

进入 Settings → Dashboards,点击右下角的 Add dashboard。

在新版界面 Add new dashboard 中填写:

字段内容
TitleRK3576 Modbus Monitoring
Icon可选择温度计图标
URLrk3576-modbus
Admin-only关闭
Add to sidebar开启

点击 Create,从左侧导航栏进入新创建的 Dashboard。

创建 RK3576 Modbus 监控 Dashboard

步骤 7:添加温度与湿度 Gauge 卡片

在 Dashboard 编辑界面,点击 New section 中的 +,选择 Add to dashboard → By card → Gauge。

依次配置两张 Gauge 卡片:

设置项温度 Gauge湿度 Gauge
EntityRK3576 Room TemperatureRK3576 Room Humidity
Minimum00
Maximum50100

分别点击 Save 保存。

添加温度与湿度 Gauge 卡片

步骤 8:添加历史曲线

再次点击 New section 内的 +,选择 By card → History graph。

在 History graph card configuration 中:

  1. 将 Title 设置为 RK3576 Modbus Sensor History。
  2. 将 Hours to show 设置为 1。
  3. 在 Entities (required) 中删除系统默认添加的 Sun 实体。
  4. 点击 Add entity,添加 RK3576 Room Temperature。
  5. 再次点击 Add entity,添加 RK3576 Room Humidity。
  6. 点击 Save,然后在 Dashboard 编辑页面点击 Done。

温度与湿度单位不同,Home Assistant 可能分别展示它们的曲线;也可以按需要分别创建独立曲线卡片。

添加 Modbus 传感器历史曲线

运行结果

本次 RK3576 实机运行得到的 Dashboard 包括温度与湿度 Gauge,以及显示随时间变化的湿度历史曲线。

reComputer RK3576 上的 Home Assistant Modbus TCP 温湿度监控演示

至此,已完成以下链路的验证:

Python Modbus TCP 模拟器 → RK3576 → Home Assistant Container → Web Dashboard。

本教程中的温湿度为模拟数据。如果需要连接实际 PLC、智能电表或 Modbus TCP 传感器,可将 host、port、slave、寄存器地址及数据类型调整为实际设备参数。

总结

通过以上步骤,我们在 reComputer RK3576 上实现了 Modbus TCP 数据读取、实时状态显示及历史曲线可视化。这为使用 RK3576 构建智能家居、本地 IoT 监控和工业网关应用提供了一个易于复现的基础示例。

参考资料

技术支持与产品讨论

如有疑问,可通过 Seeed Studio Forum 交流。