node-red-contrib-symi-modbus 2.10.6
Node-RED Modbus节点,支持TCP/串口通信、多主站独立运行、串口自动搜索、多设备轮询、可选MQTT集成(支持纯本地模式和MQTT模式)、Home Assistant自动发现、HomeKit网桥、可视化控制看板、自定义协议转换和物理开关面板双向同步(支持Symi/Clowire品牌),工控机长期稳定运行
node-red-contrib-symi-modbus
Node-RED的Modbus继电器控制节点,支持TCP/串口通信和MQTT集成,专为智能家居场景设计。
核心特性
- 双模式运行:
- 本地模式:纯串口/TCP通信,断网也能稳定运行,无需MQTT
- MQTT模式:可选接入Home Assistant等第三方平台
- 工业级稳定性:
- 多主站隔离:采用实例级隔离机制,支持无限个主站和从站节点共存,配置互不干扰
- 智能分包/粘包处理:内置1KB环形缓冲区和协议分析器,完美处理RS-485总线的分包、粘包问题
- 内存安全:严格的内存管理策略,长时间运行内存不泄露,自动清理过期缓存
- 死锁防护:多级看门狗机制,自动检测并恢复控制死循环,确保生产环境不卡顿
- Symi/Clowire生态集成:
- 多协议支持:完美支持Symi和Clowire(克伦威尔)双品牌协议,全面兼容
0x03 SET、0x04 REPORT、0x05 STATUS等多种帧类型 - 全按键覆盖:协议解析逻辑通用化,完美支持 1-8 号所有物理按键,不再局限于特定编号
- 蓝牙Mesh深度集成:支持Symi蓝牙Mesh网关V1.3.1协议,实现无线开关秒级响应
- 设备持久化:Mesh设备列表自动保存到磁盘,断电/重启/断网后配置不丢失
- 多协议支持:完美支持Symi和Clowire(克伦威尔)双品牌协议,全面兼容
- 反馈同步优化:
- 轮询暂停机制:上报数据时自动暂停主站轮询,防止状态回跳
- REPORT协议强制化:指示灯反馈强制使用REPORT (0x04)协议,不触发继电器动作,避免闪烁
- 指示灯状态强同步:无论当前状态如何,物理按键操作都会强制下发指示灯同步指令,确保面板 LED 与系统状态严格一致,彻底解决状态错位导致的按键失灵
- 物理按键强制同步:物理按键触发时强制同步 LED 反馈(忽略重复检查),纠正面板可能存在的状态不一致
- 协议解析安全化:严格过滤 REPORT (0x04) 反馈回显数据,从源头上切断“反馈触发控制”的无限死循环,确保继电器不乱跳
- 精准反馈锁:内置 100ms 毫秒级反馈锁,完美过滤 RS485 总线物理回显,同时确保高频连点操作不丢失状态
- 高级控制功能:
- 门禁联动过滤:继电器节点支持门禁ID过滤,实现精确的门禁联动控制
- HomeKit网桥:一键接入Apple HomeKit,支持Siri语音控制,状态实时同步
- 智能写入队列:所有写入操作串行执行,支持优先级管理,确保指示灯反馈在群控场景下秒级响应
- 多主站精准隔离:支持多主站并行运行,通过
masterId实现指令精准定向,严格过滤跨主站事件,彻底解决多主站环境下的控制冲突与误触发 - 智能反馈路由:从站开关节点自动识别所属主站,仅响应目标主站的状态变化,防止多系统并存时的信号串扰
- 真·状态翻转逻辑:继电器输出节点内置状态感知能力,基于物理设备真实反馈执行翻转操作,解决传统盲发指令导致的开关失灵
- 可视化运维:
- 控制看板:实时显示所有继电器状态,支持手动控制
- 调试模式:详细的通信日志,支持十六进制报文监控
1. 安装
通过npm安装(推荐)
cd ~/.node-red
npm install node-red-contrib-symi-modbus
node-red-restart
通过Node-RED界面安装
- 点击右上角菜单 → 设置 → 节点管理
- 搜索
node-red-contrib-symi-modbus - 点击安装
2. 选择运行模式
本节点支持两种运行模式,根据需求选择:
模式1:本地模式(推荐用于纯串口控制)
适用场景:
- 无需对接第三方平台
- 断网环境下稳定运行
- 纯本地化控制,不受网络影响
配置方法:
- 主站节点:不启用MQTT或不配置MQTT服务器
- 从站开关节点:不配置MQTT服务器
- 无需连线:主站和从站通过内部事件自动通信
优势:
- 断网也能稳定运行
- 不依赖外部服务
- 响应速度更快
- 配置更简单
- 无需手动连线(免连线通信)
模式2:MQTT模式(推荐用于Home Assistant集成)
适用场景:
- 需要对接Home Assistant等平台
- 需要远程控制
- 需要状态持久化
配置方法:
- 拖拽任意节点到流程画布
- 双击节点,找到"MQTT服务器"字段
- 点击编辑按钮,填写MQTT服务器信息:
- MQTT Broker:
mqtt://localhost:1883(或你的MQTT服务器地址) - 用户名/密码: 按需填写
- 基础主题:
modbus/relay(默认)
- MQTT Broker:
优势:
- Home Assistant自动发现
- 支持远程控制
- 状态持久化存储
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或留空
- MQTT模式:启用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. 配置从站开关节点(可选)
使用物理开关面板控制继电器,支持三种模式:
模式1:RS-485开关模式(传统有线开关)
- 拖拽 从站开关 节点到流程画布
- 选择刚创建的RS-485连接配置
- 配置开关面板信息:
- 面板品牌:
亖米(默认) - 按钮类型:
开关按钮(RS-485) - 开关ID: 物理面板地址 (0-255)
- 按钮编号: 按键编号 (1-8)
- 面板品牌:
- 配置映射到的继电器:
- 目标从站地址:
10 - 目标线圈编号:
1(用户输入1-32)
- 目标从站地址:
- 无需连线:主站和从站通过内部事件自动通信
- 部署流程
模式2:RS-485场景模式(场景触发)
- 配置步骤同上,但按钮类型选择
场景按钮(RS-485) - 每次按键触发状态翻转(ON→OFF或OFF→ON)
- 适用于场景联动、一键控制等场景
模式3:Mesh开关模式(蓝牙Mesh无线开关)
适用场景:使用Symi蓝牙Mesh网关和Mesh开关面板
配置步骤:
准备工作
- 确保Mesh网关已通过TCP或串口连接到Node-RED
- 确保Mesh开关已配网到网关
添加节点
- 拖拽 从站开关 节点到流程画布
- 选择Mesh网关的连接配置(TCP或串口)
扫描Mesh设备
- 按钮类型: 选择
Mesh开关(蓝牙Mesh) - 点击 扫描设备 按钮
- 系统发送
53 12 00 41协议帧到网关 - 网关立即返回所有Mesh开关列表(通常5秒内完成)
- 设备列表自动持久化保存到
~/.node-red/mesh-devices-persist/ - 重启Node-RED无需重新扫描,直接从持久化存储加载
- 按钮类型: 选择
选择设备和按键
- Mesh设备: 从下拉框选择开关(显示格式:
MAC地址 (X路开关)) - 按钮编号: 选择要使用的按键(1-6路)
- 无线模式(可选): 勾选此选项后,该按键不响应LED反馈
- 适用场景:按键用于触发场景(如全开/全关),继电器状态变化不应点亮该按键LED
- 例如:按键3控制线圈16(全开触发),勾选无线模式后,线圈0-15状态变化不会点亮按键3的LED
- 多个节点可共享同一设备列表,无需重复扫描
- Mesh设备: 从下拉框选择开关(显示格式:
配置目标继电器
- 目标从站地址:
10 - 目标线圈编号:
1(用户输入1-32)
- 目标从站地址:
部署流程
- 点击"完成"并部署
- Mesh开关按键会自动控制对应继电器
- 继电器状态变化会自动反馈到Mesh开关LED(无线模式按键除外)
Mesh模式特点:
- 无线控制,无需布线
- 支持1-6路开关
- 双向同步(按键→继电器,继电器→LED)
- 支持无线模式(场景触发按键不响应LED反馈)
- 设备列表持久化保存
- 短地址自动更新(如果网关重新配网)
- 与RS-485开关使用方式完全一致
6. 配置HomeKit网桥节点(可选)
将Modbus继电器桥接到Apple HomeKit,实现Siri语音控制:
配置步骤:
添加网桥节点
- 拖拽 HomeKit网桥 节点到流程画布
- 双击节点打开配置界面
基础配置
- 网桥名称:
Modbus继电器网桥(在HomeKit中显示) - 选择主站节点: 从下拉框选择已配置的主站
- 配对码:
031-45-154(添加到HomeKit时使用) - 端口:
51828(保持默认)
- 网桥名称:
配置继电器名称(推荐)
- 选择主站后,下方会自动显示所有继电器
- 为每个继电器输入友好的中文名称
- 例如:
客厅灯、卧室灯、空调插座等 - 配置后在HomeKit中直接显示,无需再修改
部署并添加到HomeKit
- 点击"完成"并部署流程
- 打开iPhone/iPad的"家庭"App
- 点击右上角"+" → "添加配件"
- 选择"更多选项"
- 找到"Modbus继电器网桥"
- 输入配对码:
031-45-154 - 完成配对
使用说明:
- 线圈0-15显示为开关,线圈16-31显示为插座
- 支持Siri语音控制:"嘿Siri,打开客厅灯"
- 支持HomeKit自动化和场景
- 配置会自动保存,重启后无需重新配对
- 群控性能:支持同时控制多个继电器(如创建编组),智能队列机制确保流畅无卡顿
群控说明(客户友好模式):
本节点专为智能家居群控场景优化,支持以下高性能操作:
HomeKit编组群控:
- 在HomeKit中创建房间或编组,可同时控制多个继电器
- 例如:创建"客厅"编组,包含10个灯光开关,一键全开/全关
- 智能优先队列机制确保触发源面板最快响应,其他继电器按序执行
- 10个继电器同时动作仅需约 500ms(50ms间隔×10),触发源面板优先反馈
场景联动:
- 支持HomeKit场景(如"回家模式"、"离家模式")
- 场景可包含多个继电器动作,自动串行执行
- 前16个线圈(继电器)可同时动作,后16个线圈(场景)按需触发
性能保证:
- 最大支持10台继电器(每台32路),共320个线圈
- 前160个线圈(10台×16路)可用于继电器控制,支持群控
- 后160个线圈(10台×16路)可用于场景触发,一般不会全部同时动作
- 智能写入队列确保所有操作串行执行,避免总线冲突
- 长期稳定运行,反复控制不会造成内存增加、卡顿或死机
技术细节:
- 写入队列间隔:50ms(确保总线稳定,优化指示灯反馈)
- 写入锁机制:写入操作优先级高于轮询,自动抢占总线资源
- 轮询恢复时间:50ms(写入完成后快速恢复轮询)
- 锁等待超时:500ms(适配高延迟网络,确保指令不丢失)
- 智能优先队列:触发源面板优先处理(500ms优先窗口)
- 触发源追踪:全链路追踪控制指令来源(triggerSource),日志清晰记录是物理按键、HomeKit还是自动化触发
- 队列自动处理,无需手动干预
核心特性说明
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指示灯精确同步开关状态
- 适用场景:
- 灯光开关(客厅灯、卧室灯等)
- 插座开关(电器控制)
- 窗帘开关(电动窗帘)
- 任何需要明确开/关状态的场景
- 技术特点:
- 使用REPORT协议(0x04)发送LED反馈
- 使用原始设备地址确保LED精确反馈
- 支持物理按键和Home Assistant远程控制
- 面板LED完美同步,响应速度快
2. 场景按钮
- 控制方式:每次按下toggle切换状态(开→关→开)
- LED反馈:根据当前状态显示LED(开=亮,关=灭)
- 协议特征:操作信息为0x11、0x12、0x13等(高4位=1表示场景模式)
- 适用场景:
- 场景触发(回家模式、离家模式等)
- 一键全开/全关
- 需要状态指示的场景按钮
- 技术特点:
- 使用REPORT协议(0x04)发送LED反馈
- 使用原始设备地址确保LED精确反馈
- 支持物理按键和Home Assistant远程控制
- 200ms防抖,避免重复触发
- 自动识别场景模式(根据操作信息高4位判断)
两种模式对比:
| 特性 | 开关按钮 | 场景按钮 |
|---|---|---|
| 控制方式 | 开/关独立 | Toggle切换 |
| 操作信息 | 0x00/0x01 | 0x11/0x12/0x13等 |
| LED反馈协议 | REPORT (0x04) | REPORT (0x04) |
| 按键事件 | 独立开/关码 | 统一触发码 |
| LED同步 | ✓ 完美同步 | ✓ 完美同步 |
| HA远程控制 | ✓ 支持 | ✓ 支持 |
| 推荐场景 | 灯光/插座 | 场景触发 |
| 自动识别 | ✓ 支持 | ✓ 支持 |
配置说明:
- RS-485连接:选择串口配置节点(波特率9600,8N1)
- MQTT服务器(可选):
- 本地模式:不启用MQTT,主站和从站通过内部事件自动通信(免连线)
- MQTT模式:启用MQTT并选择MQTT配置节点
- 面板配置:
- 面板品牌:选择亖米(Symi)
- 按钮类型:开关按钮或场景按钮(也可自动识别)
- 开关ID:物理面板的RS-485地址(0-255)
- 按钮编号:面板上的按键序号(1-8)
- 继电器映射:
- 从站地址:Modbus继电器地址(10-247)
- 继电器路数:继电器通道(1-32路)
使用示例:
示例1:客厅灯光开关(本地模式)
- 面板:开关ID=2,按键1(开关按钮)
- 继电器:从站10,1路
- 配置:不启用MQTT,主站和从站自动通信(免连线)
- 效果:按下面板按键,客厅灯开/关,面板LED同步状态,断网也能正常工作
示例2:全开场景(MQTT模式)
- 面板:开关ID=2,按键8(场景按钮)
- 继电器:从站10,32路
- 配置:启用MQTT,连接到Home Assistant
- 效果:按下面板按键,触发全开场景,HA中可远程控制,面板LED同步状态
示例3:三键场景开关(本地模式)
- 面板:开关ID=1,按键1/2/3(场景按钮,自动识别)
- 继电器:从站10,1/2/3路
- 配置:不启用MQTT,主站和从站自动通信(免连线)
- 效果:按下按键1/2/3,分别控制对应继电器,LED指示灯同步状态
智能轮询机制
主站轮询时,从站开关可以同时使用。当从站开关上报数据到服务器后:
- 自动暂停轮询:主站检测到写入操作,立即暂停轮询
- 优先处理数据:处理从站上报的数据(写入Modbus继电器)
- 继续轮询:数据处理完成后(100ms延迟),自动恢复轮询
- 日志记录:记录轮询暂停时长和跳过的轮询次数
这种机制确保:
- 主站轮询不会与从站写入冲突
- 从站上报的数据得到优先处理
- 系统响应迅速,状态同步及时
总线数据过滤与稳定性
本节点具备完善的总线数据过滤机制,确保长期稳定运行:
数据过滤机制:
- CRC校验:所有Symi协议帧都经过CRC8校验,无效数据自动丢弃
- 静默忽略:总线上的非相关数据(其他设备、其他协议)静默忽略,不影响正常通信
- 精确匹配:只处理本节点配置的从站地址和线圈范围内的数据
- TCP粘包处理:TCP模式下自动处理粘包和分包问题,确保数据完整性
稳定性保障:
- 写入队列:多个节点同时写入时自动排队,避免并发冲突
- 断线重连:TCP和串口断线后自动重连,指数退避策略(最大60秒)
- 内存管理:定时清理缓存,防止内存泄漏
- 错误日志限流:避免日志刷屏影响性能
- MQTT独立性:MQTT开启或关闭都不影响主站和从站的本地通信
网络适应性:
- 离线通信:串口模式完全脱离网络依赖,断网也能正常工作
- TCP稳定性:TCP模式支持局域网通信,网络恢复后自动重连
- MQTT可选:MQTT仅用于对接第三方平台,不影响本地控制
调试节点(modbus-debug)
用于抓取并显示原始RS485字节流数据(HEX),帮助定位串口或TCP网关下的Modbus通信问题。
- 数据来源:
- 共享连接:
serial-port-config(推荐,复用主站/从站的同一连接) - 独立连接:
modbus-server-config(直接连接TCP或串口)
- 共享连接:
- 输出内容:
msg.payload:格式化的HEX字符串(可选大写)msg.buffer:原始Buffer数据msg.meta:来源信息与连接参数(串口或TCP详情)msg.timestamp:时间戳(可选)
- 显示控制:
maxBytes:限制显示字节数,超过会截断并在meta.truncated标记
使用步骤:
- 将
modbus-debug节点拖入画布。 - 选择“数据来源”:
- 选“共享串口配置(serial-port-config)”以复用主站/从站连接;或
- 选“Modbus服务器(modbus-server-config)”进行独立直连。
- 可选:勾选“大写HEX”、勾选“时间戳”、设置“最大字节数”。
- 部署后,节点自动输出捕获到的原始数据。
典型用法:
- 联调TCP转RS485网关时,观察上行/下行原始数据帧是否完整。
- 排查波特率/数据位/校验位配置是否正确(串口模式)。
- 与
modbus-master或modbus-slave-switch同时使用,定位现场设备通信异常。
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网络故障自动恢复
- 连接前彻底清理旧实例,避免资源泄漏
- 互斥锁机制:防止读写冲突导致的数据异常
- TCP永久连接:
- 禁用TCP超时(永久连接),避免无数据时超时断开
- Keep-Alive心跳10秒间隔,确保连接活跃
- 适应客户长期不在家、总线无数据的场景
- 网络故障自动重连,恢复后立即恢复通信
技术规格
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,建议300-500ms(多台从站时避免总线拥堵)
- 查看Node-RED调试日志:部署后查看日志中的轮询信息
- 检查串口波特率:确认波特率为9600(与从站设备一致)
- 检查从站地址:确认从站地址正确(1-247)
轮询超时或频繁报错
- 轮询永不停止原则:
- 即使从站不响应,轮询也会持续运行
- 不会因超时而跳过任何从站
- 只记录错误日志,不影响总线轮询机制
- 正常超时:偶尔超时是正常的,系统会自动重试
- 超时设置:2-3秒(串口/TCP)
- 只记录日志,不停止轮询
- 轮询会持续运行,不受超时影响
- 频繁超时:
- 检查Modbus连接是否稳定
- 调整轮询间隔(默认200ms,可增加到500ms)
- 检查从站设备是否在线
- 查看总线是否有其他设备干扰
- 总线干扰:
- 总线上的其他数据(如Symi网关通信、其他Modbus设备)可能导致偶尔超时或CRC错误
- 系统已优化容错机制,会自动忽略异常数据并继续轮询
- 非超时错误(如CRC错误)不累积计数,只记录日志
- 长期稳定性保障:
- 轮询循环采用try-catch包裹,确保异常不会中断轮询
- 每1000轮输出一次调试日志,证明轮询持续运行
- 定时清理机制(每小时)防止内存泄漏
- 所有定时器在节点关闭时正确清除
总线上出现未知数据
- 识别数据来源:
- 使用
modbus-debug节点监听总线数据(必须使用共享的serial-port-config,避免串口冲突) - 查看Node-RED日志中的"写入线圈"日志,确认是否是本节点发送的
- 检查是否有其他Modbus设备或Symi网关在总线上通信
- 使用
- 常见数据格式:
01 05 00 01 FF 00 ...:写单个线圈(功能码0x05)01 0F 00 00 00 20 ...:写多个线圈(功能码0x0F)7E 01 03 ...:Symi轻量级协议数据
- 影响:
- 总线上的其他数据不会影响轮询稳定性
- 可能导致偶尔的CRC错误或超时,但系统会自动忽略并继续轮询
串口冲突错误
错误信息:
串口监听错误: Port is not open
串口监听错误: Error Resource temporarily unavailable Cannot lock port
原因:
- 多个节点试图独立打开同一个串口
- 串口只能被一个进程同时打开
解决方案:
- modbus-debug节点:必须使用"serial"源类型,选择共享的
serial-port-config配置节点 - 不要使用独立连接:不要让多个节点独立打开同一个串口
- 共享连接配置:所有节点(主站、从站开关、modbus-debug)都应该使用同一个
serial-port-config配置节点
批量更换连接配置
问题:如何批量更换所有节点的RS-485连接配置?
Node-RED原生方法(推荐):
- 创建新的
serial-port-config配置节点 - 点击右上角菜单 → 配置节点
- 找到旧的
serial-port-config配置节点 - 点击删除按钮
- Node-RED会提示"此配置节点被X个节点使用,是否替换为其他配置?"
- 选择新创建的配置节点
- 点击确认,所有使用旧配置的节点会自动更换为新配置
注意:
- 这是Node-RED的原生功能,安全可靠
- 删除配置节点前必须先创建新配置
- 替换后需要部署才能生效
- 确认从站设备在线:使用Modbus调试工具测试从站是否响应
- 检查MQTT连接:确保MQTT broker地址正确,轮询不依赖MQTT但状态发布需要MQTT
- 测试连接:
- TCP连接问题:先用
modbus-serial单独测试TCP连接 - 串口问题:先用
serialport单独测试串口通信
- TCP连接问题:先用
从站开关无响应
- 检查免连线通信(v2.6.7+推荐):
- 无需连线:主站和从站通过内部事件自动通信,无需手动连线
- 查看Node-RED日志,确认是否有"内部事件模式:发送命令到从站X 线圈Y"的日志
- 查看主站节点日志,确认是否有"收到内部事件:从站X 线圈Y"的日志
- 查看主站节点日志,确认是否有"内部事件写入成功,已广播状态变化"的日志
- 查看从站开关节点日志,确认是否有"收到状态变化事件"和"LED反馈已发送"的日志
- 检查RS-485连接:
- 确认RS-485连接配置正确(串口路径、波特率等)
- 查看节点状态显示是否为"MQTT未启用 - 使用内部事件模式"
- 物理面板连接:确认物理面板连接到正确的RS-485总线(TCP或串口)
- 检查开关面板配置:
- 确认开关面板地址和按钮编号正确
- 场景模式开关:操作信息为0x11、0x12、0x13等(高4位=1)
- 开关模式开关:操作信息为0x00(关)或0x01(开)
- 检查继电器映射:
- 确认目标从站地址和线圈编号正确
- 线圈编号范围:0-31(对应用户输入的1-32路)
- 查看调试日志:
- 使用modbus-debug节点抓取原始总线数据
- 查看Node-RED日志中的协议解析信息
- 确认按键事件是否被正确识别
- 确认LED反馈协议帧是否正确发送(查看日志中的HEX字符串)
输入消息格式
主站节点
// 启动轮询
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
HomeKit网桥节点
HomeKit网桥节点无需输入消息,自动同步主站配置和状态。
配置参数:
- 主站节点:选择要桥接的Modbus主站节点(必填)
- 网桥名称:在HomeKit中显示的网桥名称(默认:Modbus继电器网桥)
- MAC地址:HomeKit网桥的唯一标识符(自动生成,无需修改)
- 配对码:HomeKit配对时使用的PIN码(格式:XXX-XX-XXX,默认:031-45-154)
- 端口:HomeKit网桥监听端口(默认:51828)
- 继电器名称配置:为每个继电器配置友好的中文名称(可选)
自动同步规则:
- 自动读取主站节点配置的所有从站和线圈
- 线圈0-15(1-16路):创建为开关(Switch)配件
- 线圈16-31(17-32路):创建为插座(Outlet)配件
- 监听主站的状态变化事件,实时同步到HomeKit
- 接收HomeKit控制命令,发送到主站执行
使用示例:
- 在Node-RED中配置好主站节点和从站
- 添加HomeKit网桥节点,选择主站节点
- 为每个继电器配置友好的名称(例如:客厅灯、卧室灯)
- 部署流程
- 在iPhone的"家庭"App中添加配件,输入配对码
- 完成配对后,即可在HomeKit中控制继电器,支持Siri语音控制
注意事项:
- 确保主站节点已正确配置并运行
- 配对码格式必须为XXX-XX-XXX(8位数字)
- 端口不能与其他服务冲突(默认51828)
- 配置信息持久化存储在~/.node-red/homekit-persist目录
- 重启Node-RED后自动恢复配对状态,无需重新配对
控制看板节点(客户友好模式)
控制看板节点提供可视化界面,实时显示和控制所有从站的继电器状态,适合现场调试和日常监控。
配置参数:
- 节点名称:控制看板的显示名称(默认:Modbus控制看板)
- 主站节点:选择要监控的Modbus主站节点(必填)
功能特性:
- 实时状态显示:在配置界面中显示所有从站和线圈的实时状态
- 一键控制:点击按钮即可控制继电器开关,无需部署流程
- 美观布局:网格布局,按从站分组显示,一目了然
- 名称同步:自动同步HomeKit网桥配置的继电器名称
- 快速响应:状态实时更新(500ms轮询),响应迅速
- 零开销:不参与实际Modbus通信,不影响主站性能
使用步骤:
- 在Node-RED中添加控制看板节点
- 选择已配置的Modbus主站节点
- 双击节点打开配置界面,即可看到所有继电器状态
- 点击按钮即可控制继电器开关(绿色=ON,红色=OFF)
- 部署流程后,节点会显示"监控中"状态
使用场景:
- 现场调试:快速测试继电器是否正常工作
- 日常监控:实时查看所有继电器状态
- 批量控制:快速控制多个继电器
- 客户演示:美观的界面,适合向客户展示系统功能
技术细节:
- 使用HTTP API与主站通信,通过内部事件发送控制命令
- 状态缓存机制,减少网络请求
- 仅在配置界面打开时才轮询状态,关闭后自动停止
- 与HomeKit网桥共享继电器名称配置,保持一致性
注意事项:
- 确保主站节点已正确配置并运行
- 控制看板只在配置界面打开时才轮询状态
- 继电器名称需在HomeKit网桥节点中配置
- 本节点不参与实际Modbus通信,不会增加主站负担
自定义协议节点
用于控制非标准Modbus协议的485设备(如窗帘、特殊开关等)。
配置步骤:
- 添加自定义协议节点到流程画布
- 选择设备类型(开关/窗帘/其他)
- 选择串口配置节点
- 输入16进制指令(空格分隔,自动格式化为大写)
- 打开指令:例如
01 05 00 00 FF 00 8C 3A - 关闭指令:例如
01 05 00 00 00 00 CD CA - 暂停指令:仅窗帘模式需要,例如
01 05 00 01 FF 00 DD FA
- 打开指令:例如
- 点击"测试"按钮验证指令是否正确发送
- 连线:从站开关 → 自定义协议节点
- 部署流程
设备类型说明:
- 开关模式:收到
true发送打开指令,收到false发送关闭指令 - 窗帘模式:每次触发循环发送下一个指令(打开 → 暂停 → 关闭 → 暂停 → 打开...)
- 其他模式:与开关模式相同
使用场景:
- 窗帘控制:支持打开/暂停/关闭循环控制
- 特殊开关:非标准Modbus协议的485设备
- 自定义设备:任何需要发送固定16进制指令的设备
注意事项:
- 每个指令最多48字节
- 窗帘模式需配置三个指令(打开、关闭、暂停)
- 测试功能需先选择串口配置
- 无需连线到debug节点,直接通过串口配置节点发送数据
继电器输出节点(relay-output)
用于控制Modbus继电器,支持绑定从站开关触发源或接收外部输入,无需连线到主站。
核心特性:
- 从站开关、继电器输出、主站之间完全无需连线
- 共享RS-485连接配置,支持多个节点共用
- 支持绑定从站开关作为触发源(内部事件通信)
- 支持外部设备触发(如海康门禁)
- 支持延时执行(0-60000毫秒),实现级联开灯效果
- 配置持久化保存,断电断网恢复后正常工作
配置参数:
RS-485连接配置:
- 连接配置:选择已配置的RS-485连接(支持TCP网关或串口),多个节点共享
按键触发配置:
- 面板品牌:开关面板品牌,目前支持亖米(Symi)
- 按钮类型:开关按钮/场景按钮/输入端触发(外部设备)
- 开关ID:物理面板地址(0-255)
- 按钮编号:按键编号(1-8,15=背光灯)
- 门禁ID:可选,0=不过滤,>0=只响应指定门禁编号
目标继电器配置:
- 从站地址:要控制的Modbus从站地址(1-247)
- 继电器路数:要控制的继电器通道(1-32)
动作配置:
- 动作:打开/关闭/跟随输入/翻转状态
- 延时:执行延时(0-60000毫秒),用于实现级联开灯效果
- 忽略释放信号:只响应按下信号
使用示例:
示例1:按键触发继电器(无需任何连线)
配置:开关ID=1,按钮编号=3,从站地址=10,继电器路数=1,动作=打开
效果:当开关1的按钮3被按下时,自动控制从站10的1路继电器打开
示例2:一个按键控制多路继电器(级联开灯)
继电器输出1: 开关ID=1, 按钮=3, 继电器=1路, 延时=0ms, 动作=打开
继电器输出2: 开关ID=1, 按钮=3, 继电器=2路, 延时=500ms, 动作=打开
继电器输出3: 开关ID=1, 按钮=3, 继电器=3路, 延时=1000ms, 动作=打开
示例3:海康门禁触发(使用输入端)
海康门禁事件 → 继电器输出(按钮类型=输入端触发, 从站地址=10, 继电器=1路, 门禁ID=4)
工作原理:
- 节点监听
modbus:buttonPressed事件(按键触发) - 通过
modbus:writeCoil事件发送控制命令到主站 - 实现按键 → 继电器输出 → 主站之间的无连线通信
稳定性保障:
- 长期运行不卡顿、不死机、内存不溢出
- 无调试数据输出,具备生产条件长期运行
- 断电断网恢复后正常工作
- 内置防抖和状态检测机制,不会出现设备反复开关进入死循环
输出消息格式
主站节点
{
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"
}
]
完整示例请参考项目中的 examples/basic-flow.json 文件。
技术栈
- Node.js: >=14.0.0
- Node-RED: >=2.0.0
- modbus-serial: ^8.0.23
- serialport: ^12.0.0
- mqtt: ^5.14.1(可选)
- hap-nodejs: ^1.2.0
- node-persist: ^4.0.4
版本更新说明
v2.10.6 (2026-01-17)
- 多节点LED状态聚合: 支持多个
从站开关节点配置为同一物理按键(相同 Switch ID 和 Button ID)但控制不同继电器。系统会自动聚合所有关联继电器的状态(OR逻辑),实现“任意开则灯亮,全关则灯灭”的智能反馈,完美支持“一键多控”场景。 - Clowire协议深度优化: 新增支持 Clowire 协议的“全关”指令(0x1020=0x0002)。当检测到某面板下的所有按键状态均为 OFF 时,系统会自动合并发送一条全关指令,替代逐个发送的关闭指令,大幅降低 RS-485 总线通信压力,提升批量关灯时的响应速度。
- Symi协议深度优化: 新增支持 Symi 协议的“全关”指令(0x05 MULTI)。逻辑同上,当检测到 Symi 面板所有按键全关时,自动发送一条多灯控制指令(状态位全0),实现高效的“一键全关”反馈。
- 网络错误日志优化: 对 Modbus 主站的 TCP/串口底层连接错误进行严格限流(每分钟仅记录一次),避免在网络不稳定或断网情况下产生大量垃圾日志,保护磁盘空间。
- 稳定性增强: 优化了全局状态管理的内存回收机制,确保节点删除或重部署时无内存残留。
v2.10.5 (2026-01-15)
- 多主站精准隔离架构:引入
masterId指令定向机制。relay-output节点现在可以精准锁定目标主站,彻底解决了多主站环境下(如多台 Modbus 网关)指令错发或“一控多”的冲突问题。 - 真·状态翻转 (Toggle) 逻辑:继电器输出节点新增状态感知能力。通过实时监听总线状态回传(Coil State Sync),翻转动作不再是盲目的逻辑取反,而是基于物理设备真实状态的精准操作,解决了高频连点或多端控制下的状态不同步顽疾。
- 指示灯反馈机制重构:优化了
modbus-slave-switch的反馈锁与初始化逻辑。移除了过度的初始化过滤,确保面板指示灯在系统重启或状态突变时能秒级同步(包括 OFF 状态),解决了指示灯反馈“只开不关”的问题。 - 生产级日志分级:对全局日志进行了分级处理。将底层的 Modbus 通信报文转入 Debug 级别,控制台仅保留关键的业务联动日志(如
[免连线联动]),极大提升了高并发场景下的运行效率并降低了 IO 损耗。 - 资源管理与稳定性:规范化了所有节点的
close生命周期管理。完善了事件监听器的移除机制,确保在频繁部署或节点增删时内存无泄露,系统长期运行更加稳健。
v2.10.4 (2026-01-14)
- Modbus超时优化:将默认Modbus通信超时时间(Timeout)统一调整为 3000ms(原TCP 1000ms/串口 2000ms),彻底解决网络波动或从站响应慢导致的“轮询超时”和“写入失败”问题,这是生产环境稳定的关键参数。
- 锁等待恢复合理值:将写入锁等待超时恢复为 3000ms,配合更长的底层通信超时,确保在总线繁忙时依然能有序排队,不再出现死锁或虚假超时。
- 断连彻底静默:移除写入队列在断连时的错误日志提醒,断线期间不报错、不刷屏,确保生产环境日志整洁。
- 缓存策略优化:连接断开时立即清空所有待处理的写入任务(
writeQueue = []),重连后不处理断连期间的旧指令,只响应重连后的新操作。 - 连接恢复优化:移除重连后的自动任务恢复逻辑,实现真正的“断连不处理缓存,重连只理新数”。
v2.10.3 (2026-01-14)
- 协议兼容性: 完善 Symi 协议解析逻辑,全面支持
0x03 SET、0x04 REPORT和0x05 STATUS帧类型,解决某些面板状态错位导致的按键不响应问题。 - 稳定性修复: 紧急修复物理回显导致的“继电器无限跳动”死循环问题,通过严格过滤
0x04反馈帧并延长反馈锁至 100ms,确保系统在复杂干扰环境下依然稳定。 - 并发优化: 优化主站写入锁等待机制,将最大等待时间延长至 500ms,适配 TCP 网关或低速串口的高延迟场景。
- 指示灯同步: 引入物理按键“强制同步”机制,无论系统状态是否变化,物理按键按下时都会强制纠正面板 LED,确保面板与继电器状态 100% 对齐。
- 多主站联动: 优化
relay-output和modbus-slave-switch的事件路由,确保多台主站独立轮询、互不干扰,支持复杂的跨网关控制场景。 - 架构解耦: 明确指示灯同步职责,实现多主站环境下的闭环同步,同时保持 50ms 队列间隔与轮询暂停机制。
v2.10.2 (2026-01-14)
- 轮询优化: 引入轮询暂停机制,上报数据时自动暂停主站轮询,解决状态回跳问题。
- 反馈增强: 强制使用 REPORT (0x04) 协议进行指示灯同步,实现状态显示与物理继电器控制的彻底隔离。
- 并发管理: 优化写入队列机制。串口写入增加 50ms 厂家推荐间隔,支持高并发下的顺序发送,确保指示灯反馈稳定。
- Mesh深度支持: 完善 Mesh 模式下的 LED 反馈。通过
OP_DEVICE_REPORT (0x31)操作码同步状态,不干扰物理开关动作。 - 稳定性提升: 优化主站轮询逻辑,支持 7x24 小时高可靠性运行,具备自动重连与异常恢复能力。
- 隔离机制: 引入多串口/多网关作用域隔离,支持在同一 Node-RED 实例中运行多个物理隔离的 Modbus 网络。
v2.10.1 (2026-01-13)
- 名称校准: HA 实体名称校准,从 0-31 线圈索引校准为 1-32 路。
- 防抖优化: 引入全局按键事件去重防抖,解决信号抖动问题。
- 组网支持: 改进 LED 反馈机制,支持 Symi/Clowire/Mesh 多品牌混合组网下的状态同步。
核心特性:
- 指示灯同步逻辑优化:
- 485面板:使用
REPORT (0x04)协议进行反馈,并将主机地址固定为0x00,确保同步状态时不触发继电器动作。 - Mesh面板:引入
OP_DEVICE_REPORT (0x31)专用指令,并支持0x00 (保持不变)状态位,解决全控场景下的状态覆盖问题。 - 批量同步:支持同一面板多按键状态变更的合并排队发送,确保所有指示灯同步无遗漏。
- 485面板:使用
- 串口队列优先级:
- 触发源优先:手动触发按键的面板反馈指令进入最高优先级队列,响应时间 < 100ms。
- 智能限速:严格执行 50ms 发送间隔,确保 RS-485 总线和 TCP 网络在高并发场景下的稳定性。
- 兼容性优化:
- 优化 macOS 环境下多串口/TCP 连接稳定性。
- 保持
v2.10.2版本号,采用非沙盒模式打包,确保 Node-RED 长期运行的兼容性与稳定性。
LED 反馈与同步机制:
- 触发源优先:手动按下的开关面板享有 50ms 稳定反馈优先级,优先进入发送队列。
- 批量同步:支持全开/全关等大批量操作,所有受影响面板按 50ms 间隔有序同步,无丢失。
- Mesh 合并:Mesh 面板采用按面板合并策略,一帧同步所有按键状态,节省总线带宽。
- RS-485 独立同步:Symi/Clowire 采用按键独立防抖,确保每个按键的状态变化都能准确反馈。
- 状态锁定:LED 发送后自动开启 50ms 状态锁定,防止主站旧状态回刷导致的指示灯闪烁。
稳定性保障:
- 轮询暂停:优化轮询暂停逻辑,在上报数据时自动暂停主站轮询 50ms,解决状态回跳问题。
- 多连接支持:支持 Mac/Linux 多串口与 TCP 同时运行,各主站实例完全隔离,互不干扰。
- 断电恢复:所有状态和配置自动持久化,设备上电后 1 秒内自动同步最新状态。
- 日志防护:错误日志限流与磁盘溢出保护,确保工控机环境下的系统安全。
- 日志分级:生产环境下仅输出关键业务日志,详细通信日志转入 Debug 级别
- 智能优先队列:触发源面板优先处理(500ms优先窗口)
- 队列自动处理:指令自动串行化,避免 RS485 总线冲突
- 断连自动恢复:主站/从站连接断开后支持毫秒级自动重连
- 多实例运行:支持同时运行多个
Modbus主站节点,配置完全隔离 - 状态持久化:Mesh 设备列表和继电器状态在重启后自动恢复
- 日志分级:生产环境下仅输出关键业务日志,详细通信日志转入 Debug 级别
实际使用场景:
- 主站轮询:200ms/台,支持5-10台从站设备
- 开关面板:支持50个以内Mesh面板,约200个按钮
- LED同步:部署/重启后1秒内完成所有LED状态同步
- 批量控制:支持全开/全关等批量操作,LED反馈流畅无卡顿
- 多面板支持:100个面板同时LED反馈仅需 5 秒(50ms间隔×100)
- 场景触发:支持无线模式按键,不受LED反馈影响
许可证
MIT License