node-red-contrib-symi-modbus 2.10.27
Node-RED Modbus节点,支持TCP/串口通信、多主站独立运行、串口自动搜索、多设备轮询、可选MQTT集成(支持纯本地模式和MQTT模式)、Home Assistant自动发现、HomeKit网桥、可视化控制看板、自定义协议转换和物理开关面板双向同步(支持Symi/Clowire/LF拉斐品牌),工控机长期稳定运行
node-red-contrib-symi-modbus
Node-RED的Modbus继电器控制节点,支持TCP/串口通信和MQTT集成。
功能特性
- 多协议支持:
- Modbus TCP(标准Modbus TCP)
- Modbus RTU over TCP(TCP转RS485网关)
- Telnet ASCII(推荐用于TCP转RS485网关)
- Modbus RTU(串口直连)
- Symi开关支持:自动识别并处理Symi私有协议按键事件,无需额外配置
- 多设备轮询:最多支持10台Modbus从站设备同时轮询
- 32路继电器:每台设备支持32个线圈(继电器通道)
- 智能轮询:从站上报时自动暂停轮询,优先处理数据,完成后继续轮询
- 灵活配置:可自定义轮询间隔(100-10000ms,默认200ms)、线圈范围、从站地址
- MQTT集成:自动生成Home Assistant兼容的MQTT发现消息
- 实时状态:实时监控和控制继电器状态
- 主从模式:提供主站节点和从站控制节点
- 稳定可靠:完整的内存管理和错误处理,适合工控机长期稳定运行
节点列表
本插件包含以下核心节点:
| 节点名称 | 功能描述 |
|---|---|
| Modbus主站 | 核心调度中心,负责协议解析、多设备轮询和状态管理。 |
| 从站开关 | 监听物理面板(Symi/Clowire/LF拉斐)按键事件并联动继电器,支持LED同步。 |
| HomeKit网桥 | 一键将所有 Modbus 继电器接入 Apple HomeKit,支持自定义名称。 |
| 控制看板 | 在 Node-RED 编辑器内直接控制和查看所有继电器的实时状态。 |
| Mesh透传 | 适配 Symi 蓝牙 Mesh 网关,支持窗帘、杜亚电机及各种子设备。 |
| 继电器输出 | 灵活的联动节点,支持按键触发、延时控制和多种动作逻辑。 |
| Modbus调试 | 实时监控原始 485 总线报文,方便现场调试和协议分析。 |
| 自定义协议 | 支持通过 JavaScript 编写自定义协议转换逻辑。 |
| 配置节点 | 包含串口配置、MQTT配置和Modbus服务器配置。 |
快速开始
1. 安装
通过npm安装(推荐)
cd ~/.node-red
npm install node-red-contrib-symi-modbus
node-red-restart
通过Node-RED界面安装
- 点击右上角菜单 - 设置 - 节点管理
- 搜索
node-red-contrib-symi-modbus - 点击安装
2. 配置MQTT服务器
- 拖拽任意节点到流程画布
- 双击节点,找到"MQTT服务器"字段
- 点击编辑按钮,填写MQTT服务器信息:
- MQTT Broker:
mqtt://localhost:1883(或你的MQTT服务器地址) - 用户名/密码: 按需填写
- 基础主题:
modbus/relay(默认)
- MQTT Broker:
3. 配置主站节点
- 拖拽 Modbus主站 节点到流程画布
- 配置连接参数:
- 串口模式(直连RS485设备):
- 连接类型:
串口 - 串口路径:
/dev/ttyUSB0(Linux/Mac) 或COM1(Windows) - 波特率:
9600(默认) - 数据位:
8 - 停止位:
1 - 校验位:
无
- 连接类型:
- TCP模式(通过TCP转RS485网关):
- 连接类型:
TCP/IP - TCP模式:
Telnet ASCII(推荐,适用于大多数TCP转RS485网关) - TCP主机:
192.168.2.110 - TCP端口:
1031 - 其他模式:
RTU over TCP:适用于支持Modbus RTU over TCP的网关Modbus TCP:适用于标准Modbus TCP设备
- 连接类型:
- 串口模式(直连RS485设备):
- 配置从站设备:
- 从站地址:
10(默认,可添加多个,如10、11、12、13) - 线圈范围:
0-31 - 轮询间隔:
200ms(默认,支持100-10000ms)
- 从站地址:
- 启用MQTT并选择MQTT服务器配置
- 部署流程
4. 配置RS-485连接配置节点(用于从站开关)
如果需要物理开关面板控制,首先创建RS-485连接配置:
- 点击右上角菜单 - 配置节点
- 添加新的 serial-port-config 配置节点
- 选择连接类型:
- 串口模式(本地RS-485总线):
- 连接类型:
串口 - 串口路径:
/dev/ttyUSB0(可点击"搜索"按钮自动发现) - 波特率:
9600 - 数据位:
8 - 停止位:
1 - 校验位:
无 (N)
- 连接类型:
- TCP模式(通过TCP转RS485网关):
- 连接类型:
TCP网关 - TCP主机:
192.168.2.110 - TCP端口:
1031
- 连接类型:
- 串口模式(本地RS-485总线):
- 保存配置
5. 配置从站开关节点
使用物理开关面板控制继电器:
- 拖拽 从站开关 节点到流程画布
- 选择刚创建的RS-485连接配置
- 配置开关面板信息:
- 面板品牌:
Symi/Clowire(克伦威尔)/LF(拉斐) - 开关ID: 物理面板地址 (0-255)
- 按钮编号: 按键编号 (1-8)
- 按钮类型:
开关按钮:Symi 面板下,按下=开,释放=关(有独立开/关码),适合直接映射单个继电器场景按钮:Clowire 推荐使用,以及 Symi 场景键;每次按下都触发一次 Toggle,由指示灯和继电器状态共同决定“当前是开还是关”
- 面板品牌:
- 配置映射到的继电器:
- 目标从站地址:
10 - 目标线圈编号:
0
- 目标从站地址:
- 部署流程
LF(拉斐)485 弱电开关
- 串口:9600 8N1,指令间隔 ≥50ms(由
serial-port-config写入队列保证) - 面板地址:1–42(出厂默认 2),开关 ID 填十进制地址
- 按键上报(主动发送 8 字节):
[地址][03][00][02][绝对键值][按键掩码][CRC] - 指示灯控制:写寄存器
0x1008一次写入完整 bitmask(变背光产品高字节 BIT8=1,节点自动处理) - RCU 模式:首次 LED 控制自动写
0x1003=0x0006并保存0x100F - 多键同步:同面板 8 个从站开关节点共享状态,只发一条
0x1008帧(复用写入队列 / 200ms 防抖 / 面板级去重)
面板地址 1 · 变背光 · 单键亮(测试码):
| 操作 | Hex |
|---|---|
| 按键1亮 | 01 06 10 08 01 01 CC 98 |
| 按键2亮 | 01 06 10 08 01 02 8C 99 |
| 按键3亮 | 01 06 10 08 01 04 0C 9B |
| 按键4亮 | 01 06 10 08 01 08 0C 9E |
| 按键5亮 | 01 06 10 08 01 10 0C 94 |
| 按键6亮 | 01 06 10 08 01 20 0C 80 |
| 按键7亮 | 01 06 10 08 01 40 0C A8 |
| 按键8亮 | 01 06 10 08 01 80 0C F8 |
| 全灭 | 01 06 10 08 00 00 0C C8 |
单键灭(0x1008 写剩余 bitmask,非逐键单独灭指令):
| 操作 | Hex |
|---|---|
| 仅灭当前唯一亮键(全灭) | 01 06 10 08 00 00 0C C8 |
| 灭键1、键2仍亮 | 01 06 10 08 01 02 8C 99 |
| 灭键2、键1+3仍亮 | 01 06 10 08 01 05 CD 5B |
| 键1+3亮 | 01 06 10 08 01 05 CD 5B |
| 键1–4全亮 | 01 06 10 08 01 0F 4D 5C |
修改面板地址:广播 FF 06 10 00 00 [新地址] [CRC],再向新地址发 XX 06 10 0F 00 FE [CRC] 保存。
6. 进阶功能配置
HomeKit 接入
- 拖拽 HomeKit网桥 节点。
- 选择关联的 Modbus主站。
- 在节点属性中,你可以为每一路继电器命名(如“客厅灯”),这些名称将同步显示在 iPhone 的家庭 App 中。
- 部署后,使用 iPhone 扫描节点显示的二维码或输入 Pin码(默认
031-45-154)即可完成接入。
网页控制看板
- 拖拽 控制看板 节点。
- 选择关联的 Modbus主站。
- 部署后,在 Node-RED 编辑器中双击该节点,即可看到一个直观的控制界面,支持实时查看状态和点击控制。
Mesh 窗帘/电机控制
- 拖拽 Mesh透传 节点。
- 选择对应的 RS-485配置节点(连接到蓝牙 Mesh 网关)。
- 节点会自动发现网关下的子设备,选择目标窗帘或杜亚电机。
- 配置 控制逻辑(仅窗帘类型显示):
- 循环 (开-停-关-停):单键依次 打开→暂停→关闭→暂停。
- 打开/关闭:单键在 开/关 之间切换,到顶/到底后再次按键必为 关/开。
- 可选绑定 按键触发:
- 使用
从站开关或继电器输出节点,面板品牌选择 Symi / Clowire,按钮类型选择 场景按钮,并与 Mesh 窗帘节点的switchId/buttonNumber保持一致 - Clowire 按键在内部统一按“场景模式”处理:每次物理按键都会触发一次事件,不会因为
value=false被忽略
- 使用
- 状态与按键记忆:窗帘上报的位置(0%/100%)会更新节点内部状态;下次同一按键按下时,会根据“到顶/到底”正确执行 关/开 或 暂停,无需额外配置。
- 运动过程中(收到中间百分比,未到 0%/100%),再次按键一律发送 暂停,不会发生错误翻转
- 只有在电机真正上报到端点(Mesh 0x06 / 杜亚 0x04 的 0% / 100%)时,才会记为“开着/关着”,下一次按键才直接翻转为 关/开
- 支持杜亚 485 电机:勾选“启用解析”、填写电机地址(高位-低位),可同时控制 Mesh 窗帘与杜亚电机并双向同步位置。
核心特性说明
Symi开关自动识别
主站节点自动支持两种控制方式,无需额外配置:
方式1:Modbus RTU轮询(标准)
- 主站定期轮询从站线圈状态
- 通过MQTT或Node-RED流程控制继电器
- 适用于所有Modbus RTU设备
方式2:Symi私有协议(自动)
- 自动识别Symi开关按键事件(协议格式:
7E [地址] 03 0F ...) - 自动应答并控制对应继电器(协议格式:
7E [地址] 04 0F ...) - 映射规则:
- 设备地址1 → 从站10
- 设备地址2 → 从站11
- 设备地址3 → 从站12
- 设备地址4 → 从站13
- 通道号1-8 → 线圈0-7
按钮类型说明:
1. 开关按钮(推荐)
- 控制方式:按键有独立的开/关状态
- LED反馈:面板LED指示灯精确同步开关状态
- 适用场景:
- 灯光开关(客厅灯、卧室灯等)
- 插座开关(电器控制)
- 窗帘开关(电动窗帘)
- 任何需要明确开/关状态的场景
- 技术特点:
- 使用SET协议(0x03)发送LED反馈
- 使用原始设备地址确保LED精确反馈
- 支持物理按键和Home Assistant远程控制
- 面板LED完美同步,响应速度快
2. 场景按钮
- 控制方式:每次按下toggle切换状态(开→关→开)
- LED反馈:根据当前状态显示LED(开=亮,关=灭)
- 适用场景:
- 场景触发(回家模式、离家模式等)
- 一键全开/全关
- 需要状态指示的场景按钮
- 技术特点:
- 使用REPORT协议(0x04)发送LED反馈
- 使用原始设备地址确保LED精确反馈
- 支持物理按键和Home Assistant远程控制
- 200ms防抖,避免重复触发
两种模式对比:
| 特性 | 开关按钮 | 场景按钮 |
|---|---|---|
| 控制方式 | 开/关独立 | Toggle切换 |
| LED反馈协议 | SET (0x03) | REPORT (0x04) |
| 按键事件 | 独立开/关码 | 统一触发码 |
| LED同步 | ✓ 完美同步 | ✓ 完美同步 |
| HA远程控制 | ✓ 支持 | ✓ 支持 |
| 推荐场景 | 灯光/插座 | 场景触发 |
配置说明:
- RS-485连接:选择串口配置节点(波特率9600,8N1)
- MQTT服务器:选择MQTT配置节点(连接Home Assistant等)
- 面板配置:
- 面板品牌:选择Symi
- 按钮类型:开关按钮或场景按钮
- 开关ID:物理面板的RS-485地址(0-255)
- 按钮编号:面板上的按键序号(1-8)
- 继电器映射:
- 从站地址:Modbus继电器地址(10-247)
- 继电器路数:继电器通道(1-32路)
使用示例:
示例1:客厅灯光开关
- 面板:开关ID=2,按键1(开关按钮)
- 继电器:从站10,1路
- 效果:按下面板按键,客厅灯开/关,面板LED同步状态
示例2:全开场景
- 面板:开关ID=2,按键8(场景按钮)
- 继电器:从站10,32路
- 效果:按下面板按键,触发全开场景
智能轮询机制
主站轮询时,从站开关可以同时使用。当从站开关上报数据到服务器后:
- 自动暂停轮询:主站检测到写入操作,立即暂停轮询
- 优先处理数据:处理从站上报的数据(写入Modbus继电器)
- 继续轮询:数据处理完成后(100ms延迟),自动恢复轮询
- 日志记录:记录轮询暂停时长和跳过的轮询次数
这种机制确保:
- 主站轮询不会与从站写入冲突
- 从站上报的数据得到优先处理
- 系统响应迅速,状态同步及时
MQTT自动发现
启用MQTT后,自动生成Home Assistant兼容的Discovery配置:
- 唯一性保证:每个实体使用稳定的
unique_id,避免重复生成 - 设备分组:同一从站的所有继电器自动分组到一个设备下
- 状态持久化:使用
retain=true确保状态持久化 - 在线状态:自动发布设备可用性状态
配置持久化
所有节点配置自动保存到Node-RED的flows文件中:
- 从站地址、线圈范围、轮询间隔
- MQTT服务器配置
- 开关面板映射关系
部署后配置永久生效,重启Node-RED后自动恢复。
长期稳定运行
针对工控机24/7长期运行优化:
- 内存管理:自动清理缓存,释放无用对象
- 事件监听器清理:关闭时移除所有监听器,防止内存泄漏
- 智能日志限流:错误日志10分钟输出一次,避免日志刷屏
- 智能重连机制:
- Modbus连接断开自动重连(指数退避:5秒→10秒→20秒...最大60秒)
- MQTT连接断开自动重连(支持多地址fallback)
- 串口拔插自动检测并重连
- TCP网络故障自动恢复
- 连接前彻底清理旧实例,避免资源泄漏
- 互斥锁机制:防止读写冲突导致的数据异常
- Keep-Alive心跳:TCP连接启用30秒心跳检测
技术规格
Modbus协议
- 协议类型:Modbus TCP / Modbus RTU
- 底层库:modbus-serial ^8.0.23(内部封装serialport,支持TCP和串口)
- 功能码支持:0x01(读线圈)、0x05(写单个线圈)、0x0F(写多个线圈)
- 从站地址范围:1-247(建议从10开始)
- 线圈数量:每台设备32个(0-31)
- 最大设备数:10台同时轮询
- 轮询间隔:默认200ms(建议300-500ms,支持100-10000ms)
- 串口配置:9600 8-N-1(波特率9600,8数据位,无校验,1停止位)
- 超时设置:5000ms(TCP和串口通用)
兼容性
- Node.js: >= 14.0.0
- Node-RED: >= 2.0.0
- MQTT Broker: Mosquitto / EMQX / Any MQTT 3.1.1/5.0
- Home Assistant: 2024.x+(MQTT Discovery标准)
- 操作系统: Windows / Linux / macOS / HassOS
Home Assistant集成
自动发现
启用MQTT后,设备自动出现在Home Assistant中:
- 实体ID:
switch.relay_{从站地址}_{线圈编号} - 设备名称:
Modbus继电器-{从站地址} - 自动分组: 同一从站的所有继电器分组到一个设备
MQTT主题结构
状态主题: modbus/relay/{从站}/{线圈}/state
命令主题: modbus/relay/{从站}/{线圈}/set
可用性主题: modbus/relay/{从站}/availability
发现主题: homeassistant/switch/modbus_relay_{从站}_{线圈}/config
故障排除
串口连接失败
Linux:
# 查看串口设备
ls -l /dev/ttyUSB* /dev/ttyS*
# 添加用户到dialout组(需要重新登录)
sudo usermod -a -G dialout $USER
macOS:
# 查看串口设备(注意macOS使用cu.*而不是tty.*)
ls -l /dev/cu.*
Docker/HassOS:
# 在docker-compose.yml或HassOS插件配置中添加设备映射
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
MQTT连接失败
确认MQTT broker正在运行:
# Linux sudo systemctl status mosquitto # macOS brew services list | grep mosquitto测试MQTT连接:
mosquitto_sub -h localhost -t test检查Node-RED日志中的MQTT连接信息
主站轮询不工作
- 确认已添加所有从站设备(如10、11、12、13)
- 确认轮询间隔(默认200ms)
- 查看Node-RED调试日志
- 检查串口波特率(9600)
- 检查从站地址(1-247)
- 确认从站设备在线
- 检查MQTT连接(轮询不依赖MQTT,但状态发布需要MQTT)
从站开关无响应
- 检查RS-485连接
- 确认开关面板地址和按钮编号
- 检查MQTT连接
- 查看Node-RED日志中的协议解析信息
输入消息格式
主站节点
// 启动轮询
msg.payload = {cmd: "start"};
// 停止轮询
msg.payload = {cmd: "stop"};
// 写单个线圈
msg.payload = {
cmd: "writeCoil",
slave: 10, // 从站地址
coil: 0, // 线圈编号
value: true // true=开, false=关
};
// 批量写多个线圈
msg.payload = {
cmd: "writeCoils",
slave: 10, // 从站地址
startCoil: 0, // 起始线圈
values: [true, false, true, false] // 线圈值数组
};
从站开关节点
// 发送开关命令
msg.payload = true; // 或 false
msg.payload = "ON"; // 或 "OFF"
msg.payload = 1; // 或 0
输出消息格式
主站节点
{
payload: {
slave: 10, // 从站地址
coils: [true, false, ...], // 线圈状态数组
timestamp: 1234567890 // 时间戳
}
}
从站开关节点
{
payload: true, // 开关状态
topic: "switch_0_btn1", // 主题
switchId: 0, // 开关面板ID
button: 1, // 按钮编号
targetSlave: 10, // 目标从站地址
targetCoil: 0 // 目标线圈编号
}
性能指标
- 内存占用:< 50MB(单个主站节点,轮询10个设备)
- CPU占用:< 5%(正常轮询状态)
- 连接延迟:Modbus响应 < 100ms,MQTT发布 < 50ms
- 稳定运行:经过工控机7x24小时长期运行验证
- 容错能力:Modbus从站离线不影响其他从站,MQTT断线自动重连
示例Flow
[
{
"id": "modbus-master-1",
"type": "modbus-master",
"name": "主站",
"connectionType": "serial",
"serialPort": "/dev/ttyUSB0",
"serialBaudRate": 9600,
"slaves": [
{"address": 10, "coilStart": 0, "coilEnd": 31, "pollInterval": 200},
{"address": 11, "coilStart": 0, "coilEnd": 31, "pollInterval": 200},
{"address": 12, "coilStart": 0, "coilEnd": 31, "pollInterval": 200},
{"address": 13, "coilStart": 0, "coilEnd": 31, "pollInterval": 200}
],
"enableMqtt": true,
"mqttServer": "mqtt-config-1"
}
]
项目信息
更新日志
v2.10.27 (2026-07-09)
- [LF485 开关] 生产发布:拉斐 LF 485 弱电开关完整对接(主动收发、RCU 模式、变背光 BIT8、面板级 0x1008 单帧聚合)。
- [LF485 开关]
sendLfPanelLedSync同面板 8 键只发一条指示灯帧;复用serial-port-config50ms 队列、200ms 防抖、粘包解析与全局缓存。 - [适配] 从站开关 / 继电器输出 / Mesh 透传节点支持 LF 品牌;
lf-protocol.js单元测试覆盖 PDF 范例与用户抓包。 - [打包] npm 包审计:不含
doc/、PDF、开发缓存;兼容 Node-RED ≥2.0、Node.js ≥14。
v2.10.20 (2026-06-30)
- [打包] 修复 npm 发布包误含
.codebase-memory/开发索引的问题,包体积约 158KB;规范.npmignore/.gitignore,开发缓存目录不进入发布包。 - [工程] 提取
lib/lru-map.js、lib/slave-switch-cache.js,全局 LRU 缓存与 Mesh LED 定时器上限(5000);新增lib/http-admin-utils.js,14 个 HTTP Admin 路由统一 read/write 权限校验。 - [工程]
modbus-master串口列表 API 复用lib/serial-utils,消除重复实现。 - [测试] 新增
mesh-protocol、lightweight-protocol协议帧解析单元测试(npm test)。 - [修复] 修正
isMeshFrame请求帧长度判定,与parseAllFrames保持一致。 - [Mesh 窗帘] 按《蓝牙MESH网关(初级版)串口协议V1.0》修正 0x53 0x80 0x06 状态帧解析;窗帘动作/位置分离存储;开停关停与打开-关闭逻辑完善;Clowire 场景按键统一处理。
- [Mesh 透传] 合并重复 close 监听;热路径日志降为 debug;杜亚电机状态双向同步优化;实体持久化增强。
更早版本 (v2.10.14 ~ v2.10.17)
- 多种 Modbus 协议(Telnet ASCII、RTU over TCP、TCP、串口)与智能轮询暂停。
- Home Assistant MQTT Discovery、HomeKit 网桥、控制看板、Mesh 透传节点、继电器输出。
- 按键记忆与端点收敛、场景按键每次按下均触发、LED 反馈同步、串口热插拔与 TCP 自动恢复。
许可证
MIT License
作者
symi-daguo
- NPM: symi-daguo
- GitHub: symi-daguo
支持
- Issues: GitHub Issues
- NPM: node-red-contrib-symi-modbus