node-red-contrib-symi-modbus 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,19 +4,16 @@ Node-RED的Modbus继电器控制节点,支持TCP/串口通信和MQTT集成。
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - ✅ **多协议支持**:支持Modbus TCP和Modbus RTU(串口)
8
- - ✅ **多设备轮询**:最多支持10台Modbus从站设备同时轮询
9
- - ✅ **32路继电器**:每台设备支持32个线圈(继电器通道)
10
- - ✅ **灵活配置**:可自定义轮询间隔、线圈范围、从站地址
11
- - ✅ **MQTT集成**:自动生成Home Assistant兼容的MQTT发现消息
12
- - ✅ **实时状态**:实时监控和控制继电器状态
13
- - ✅ **主从模式**:提供主站节点和从站控制节点
7
+ - 多协议支持:支持Modbus TCP和Modbus RTU(串口)
8
+ - 多设备轮询:最多支持10台Modbus从站设备同时轮询
9
+ - 32路继电器:每台设备支持32个线圈(继电器通道)
10
+ - 灵活配置:可自定义轮询间隔、线圈范围、从站地址
11
+ - MQTT集成:自动生成Home Assistant兼容的MQTT发现消息
12
+ - 实时状态:实时监控和控制继电器状态
13
+ - 主从模式:提供主站节点和从站控制节点
14
14
 
15
15
  ## 安装
16
16
 
17
- [![npm version](https://badge.fury.io/js/node-red-contrib-symi-modbus.svg)](https://www.npmjs.com/package/node-red-contrib-symi-modbus)
18
- [![npm downloads](https://img.shields.io/npm/dm/node-red-contrib-symi-modbus.svg)](https://www.npmjs.com/package/node-red-contrib-symi-modbus)
19
-
20
17
  ### 通过npm安装(推荐)
21
18
 
22
19
  在Node-RED用户目录中运行:
@@ -32,90 +29,6 @@ npm install node-red-contrib-symi-modbus
32
29
  2. 搜索 `node-red-contrib-symi-modbus`
33
30
  3. 点击安装
34
31
 
35
- **已发布到npm:** https://www.npmjs.com/package/node-red-contrib-symi-modbus
36
-
37
- ### Docker/容器环境安装
38
-
39
- 本节点依赖`modbus-serial`包,该包包含native C++模块(serialport),需要编译环境。
40
-
41
- #### ⚠️ 如果遇到安装错误
42
-
43
- **错误示例:**
44
- ```
45
- npm error code 127
46
- npm error command sh -c node-gyp-build
47
- npm error sh: node-gyp-build: not found
48
- ```
49
-
50
- **原因:** Docker容器缺少编译工具(python、make、g++)
51
-
52
- **解决方案1:使用官方Node-RED Docker镜像(推荐)**
53
-
54
- 官方镜像已包含编译工具:
55
- ```bash
56
- docker pull nodered/node-red:latest
57
- ```
58
-
59
- **解决方案2:在Dockerfile中添加编译依赖**
60
-
61
- Alpine基础镜像:
62
- ```dockerfile
63
- FROM nodered/node-red:latest
64
- # 或者自定义镜像时添加
65
- RUN apk add --no-cache \
66
- python3 \
67
- make \
68
- g++ \
69
- linux-headers
70
- ```
71
-
72
- Debian/Ubuntu基础镜像:
73
- ```dockerfile
74
- FROM nodered/node-red:latest
75
- # 或者
76
- RUN apt-get update && apt-get install -y \
77
- python3 \
78
- make \
79
- g++ \
80
- build-essential
81
- ```
82
-
83
- **解决方案3:在运行中的容器安装**
84
-
85
- ```bash
86
- # 进入容器
87
- docker exec -it <container_id> /bin/sh
88
-
89
- # Alpine
90
- apk add --no-cache python3 make g++ linux-headers
91
-
92
- # Debian/Ubuntu
93
- apt-get update && apt-get install -y python3 make g++ build-essential
94
-
95
- # 退出容器后,在Node-RED界面重新安装节点
96
- ```
97
-
98
- **解决方案4:使用docker-compose(推荐)**
99
-
100
- ```yaml
101
- version: '3.8'
102
- services:
103
- node-red:
104
- image: nodered/node-red:latest
105
- ports:
106
- - "1880:1880"
107
- volumes:
108
- - node-red-data:/data
109
- # 如果需要串口设备,添加设备映射
110
- devices:
111
- - "/dev/ttyUSB0:/dev/ttyUSB0"
112
- # 如果需要串口权限
113
- user: "1000:20" # dialout组ID通常是20
114
-
115
- volumes:
116
- node-red-data:
117
- ```
118
-
119
32
  ### 本地开发安装
120
33
 
121
34
  ```bash
@@ -123,32 +36,18 @@ volumes:
123
36
  cd node-red-contrib-symi-modbus
124
37
  npm install
125
38
 
126
- # 安装到Node-RED(使用你的实际项目路径)
39
+ # 安装到Node-RED
127
40
  cd ~/.node-red
128
41
  npm install /path/to/node-red-contrib-symi-modbus
129
-
130
- # 或者在Mac上
131
- cd ~/.node-red
132
- npm install /Volumes/your-disk/path/to/node-red-contrib-symi-modbus
133
42
  ```
134
43
 
135
44
  **安装后需要重启Node-RED**
136
45
 
137
- ```bash
138
- # 重启Node-RED
139
- # 如果用命令行运行,按 Ctrl+C 停止,然后重新运行
140
- node-red
141
-
142
- # 如果用服务管理器,重启服务
143
- # macOS: brew services restart node-red
144
- # Linux: sudo systemctl restart node-red
145
- ```
146
-
147
46
  ## 节点说明
148
47
 
149
48
  ### 1. MQTT服务器配置节点 (mqtt-server-config)
150
49
 
151
- **全局配置节点**,用于管理MQTT服务器连接信息,所有主站和从站节点共享此配置。
50
+ 全局配置节点,用于管理MQTT服务器连接信息,所有主站和从站节点共享此配置。
152
51
 
153
52
  #### 配置参数
154
53
 
@@ -158,20 +57,6 @@ node-red
158
57
  - **密码**:MQTT认证密码(可选)
159
58
  - **基础主题**:MQTT主题前缀(默认:modbus/relay)
160
59
 
161
- #### 使用方式
162
-
163
- 1. 在主站或从站节点配置界面中,点击MQTT服务器旁边的编辑按钮(铅笔图标)
164
- 2. 选择已有的MQTT配置,或点击"添加新的mqtt-server-config..."创建新配置
165
- 3. 填写MQTT服务器信息并保存
166
- 4. 所有使用相同配置的节点会自动同步更新
167
-
168
- #### 优势
169
-
170
- ✅ **统一管理**:所有MQTT连接信息集中配置,避免重复输入
171
- ✅ **一处修改,处处生效**:修改配置后所有引用的节点自动更新
172
- ✅ **防止错误**:确保主站和从站使用相同的MQTT服务器和主题
173
- ✅ **持久化保存**:配置自动保存,重启Node-RED后不丢失
174
-
175
60
  ### 2. Modbus主站节点 (modbus-master)
176
61
 
177
62
  主站节点负责与Modbus继电器设备通信,执行轮询操作,并可选择发布状态到MQTT服务器。
@@ -184,21 +69,17 @@ node-red
184
69
  - **TCP端口**:Modbus TCP端口(默认:502)
185
70
  - **串口**:串口名称(如:COM1、/dev/ttyUSB0)
186
71
  - **波特率**:串口波特率(9600/19200/38400/57600/115200)
187
- - **数据位**:数据位数(7或8,默认8)
188
- - **停止位**:停止位数(1或2,默认1)
189
- - **校验位**:校验方式(无/奇校验/偶校验,默认无)
190
72
 
191
73
  **从站设备配置**
192
74
  - **动态添加从站**:点击"添加从站"按钮可添加最多10个从站设备
193
- - **从站地址**:每个从站的Modbus地址(1-247,默认从10=0x0A开始递增)
75
+ - **从站地址**:每个从站的Modbus地址(1-247,默认从10开始递增)
194
76
  - **起始线圈**:该从站的起始线圈编号(0-31)
195
77
  - **结束线圈**:该从站的结束线圈编号(0-31)
196
- - **轮询间隔**:该从站的轮询间隔,单位毫秒(默认:200ms,推荐≥100ms)
197
- - **配置持久化**:所有从站配置自动保存,重启Node-RED后不丢失
78
+ - **轮询间隔**:该从站的轮询间隔,单位毫秒(默认:200ms,推荐>=100ms)
198
79
 
199
80
  **MQTT配置**
200
81
  - **启用MQTT**:是否启用MQTT功能
201
- - **MQTT服务器**:选择或添加MQTT服务器配置节点(引用mqtt-server-config)
82
+ - **MQTT服务器**:选择或添加MQTT服务器配置节点
202
83
 
203
84
  #### 输入消息
204
85
 
@@ -226,1131 +107,133 @@ msg.payload = {
226
107
  };
227
108
  ```
228
109
 
229
- #### 输出消息
230
-
231
- ```javascript
232
- {
233
- payload: {
234
- slave: 10, // 从站地址
235
- coils: [true, false, true, ...], // 线圈状态数组
236
- timestamp: 1234567890 // 时间戳
237
- }
238
- }
239
- ```
240
-
241
110
  #### MQTT主题结构
242
111
 
243
112
  启用MQTT后,自动生成以下主题:
244
113
 
245
114
  - **状态主题**:`modbus/relay/{从站地址}/{线圈编号}/state`
246
- - 内容:`ON` 或 `OFF`
247
- - 示例:`modbus/relay/10/0/state` → `ON`
248
-
249
115
  - **命令主题**:`modbus/relay/{从站地址}/{线圈编号}/set`
250
- - 接受:`ON` 或 `OFF`
251
- - 示例:`modbus/relay/10/0/set` ← `OFF`
252
-
253
116
  - **可用性主题**:`modbus/relay/{从站地址}/availability`
254
- - 内容:`online` 或 `offline`
255
- - 用于显示设备在线/离线状态
256
-
257
117
  - **发现主题**(Home Assistant):`homeassistant/switch/modbus_relay_{从站}_{线圈}/config`
258
- - 符合Home Assistant MQTT Discovery标准
259
- - 包含完整的设备信息和配置
260
118
 
261
119
  ### 3. Modbus开关从站节点 (modbus-slave-switch)
262
120
 
263
- 从站开关节点连接物理开关面板(RS-485总线),监听按键事件,并通过MQTT映射控制Modbus继电器设备,实现**三向同步**。
264
-
265
- #### 工作原理
266
-
267
- - **RS-485总线连接**:连接物理开关面板的RS-485总线(TCP或串口)
268
- - **监听按键事件**:实时监听物理面板的按钮按下事件
269
- - **发送控制指令**:同步控制物理面板的指示灯等状态
270
- - **映射到继电器**:指定要控制的Modbus从站地址(10-19)和线圈编号(0-31)
271
- - **MQTT三向同步**:
272
- - **按键→继电器**:物理按键按下 → 从站监听 → MQTT命令 → 主站 → 继电器动作
273
- - **继电器→面板**:继电器状态变化 → 主站轮询 → MQTT状态 → 从站 → 面板指示灯更新
274
- - **远程→全部**:远程控制 → MQTT → 继电器动作 + 面板指示灯同步
275
- - **完全解耦**:无需连线到主站节点,通过MQTT通信
276
- - **实时同步**:三向自动同步,延迟<200ms
277
-
278
- #### 三向同步机制详解(基于轻量级协议V0.13)
279
-
280
- ```
281
- 【完整三向通信架构】
282
-
283
- ┌──────────────────┐ ┌──────────────────┐ ┌──────┐ ┌──────────────┐ ┌────────────┐
284
- │ 物理开关面板 │ ←→ │ 从站开关节点 │ ←→ │ MQTT │ ←→ │ 主站节点 │ ←→ │ Modbus继电器│
285
- │ (RS-485总线) │ │ 轻量级协议+MQTT │ │Broker│ │ Modbus协议 │ │ (设备) │
286
- │ │ │ │ │ │ │ │ │ │
287
- │ • 按键按下 │ ──> │ • 解析0x04上报 │ ──> │ ON │ ──> │ • 写线圈0x05 │ ──> │ • 继电器ON │
288
- │ 0x04上报 │ │ • 发MQTT命令 │ │ QoS1 │ │ • Modbus写入 │ │ │
289
- │ │ │ │ │ │ │ │ │ │
290
- │ • 指示灯亮 │ <── │ • 构建0x03设置 │ <── │ ON │ <── │ • 读线圈0x01 │ <── │ • 状态变化 │
291
- │ 0x03设置 │ │ • CRC8校验 │ │retain│ │ • 轮询检测 │ │ │
292
- └──────────────────┘ └──────────────────┘ └──────┘ └──────────────┘ └────────────┘
293
- ↑ ↑ ↑ ↑ ↑
294
- │ │ │ │ │
295
- 轻量级协议 双协议桥接 QoS=1保证 Modbus协议 继电器控制
296
- 波特率9600 帧头0x7E+CRC8 持久化会话 功能码01/05 硬件执行
297
- 8N1无校验 帧尾0x7D 自动重连 超时5秒 实时响应
298
- ```
299
-
300
- **轻量级协议帧格式:**
301
- ```
302
- 7E [本机地址] [数据类型] [数据长度] [设备类型0x01] [品牌ID] [设备地址] [通道]
303
- [房间号] [房间类型] [房间ID] [操作码] [操作信息] [CRC8] 7D
304
-
305
- 示例 - 控制开关ID=1,按钮3,开启:
306
- 7E 01 03 0F 01 00 01 03 00 00 00 00 01 XX 7D
307
- ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
308
- 本机 设置 灯光 设备1 按钮3 单灯 开启
309
- ```
310
-
311
- **数据流示例(含完整协议帧):**
312
-
313
- 1. **用户按下物理按钮 → 继电器动作**
314
- ```
315
- 物理按钮按下
316
- → RS-485上报: 7E 01 04 0F 01 00 01 03 00 00 00 00 01 XX 7D (0x04上报,按钮3开启)
317
- → 从站节点解析协议帧,检测按键按下事件
318
- → MQTT发布: modbus/relay/10/0/set → "ON" (QoS=1)
319
- → 主站接收MQTT命令
320
- → Modbus写线圈: 功能码0x05,从站10,线圈0,值=1
321
- → 继电器执行动作: 继电器ON
322
- ```
323
-
324
- 2. **继电器状态变化 → 面板指示灯同步**
325
- ```
326
- 继电器状态变化(物理或远程控制)
327
- → Modbus轮询读取: 功能码0x01,从站10,线圈0
328
- → 主站检测状态变化
329
- → MQTT发布: modbus/relay/10/0/state → "ON" (QoS=1, retain=true)
330
- → 从站接收MQTT状态消息
331
- → 构建轻量级协议: 7E 01 03 0F 01 00 01 03 00 00 00 00 01 XX 7D (0x03设置,按钮3开启)
332
- → RS-485发送指令到物理面板
333
- → 面板指示灯: 指示灯ON
334
- ```
335
-
336
- 3. **远程控制(HA/MQTT) → 全部同步**
337
- ```
338
- Home Assistant控制或MQTT命令
339
- → MQTT命令: modbus/relay/10/0/set → "ON"
340
- → 主站接收并写入Modbus
341
- → 继电器ON
342
- → 主站轮询检测到状态变化
343
- → MQTT状态: modbus/relay/10/0/state → "ON"
344
- → 从站接收状态,发送RS-485指令
345
- → 面板指示灯ON
346
- ```
347
-
348
- **关键特性:**
349
- - ✅ **轻量级协议实现**:完整实现V0.13协议(帧头0x7E、CRC8校验、帧尾0x7D)
350
- - ✅ **按键事件解析**:解析0x04上报帧,检测单键/多键按下事件
351
- - ✅ **指示灯控制**:构建0x03设置帧,同步物理面板指示灯状态
352
- - ✅ **RS-485双向通信**:监听按键事件 + 控制指示灯状态
353
- - ✅ **TCP/串口支持**:可连接RS-485转TCP网关或直连串口
354
- - ✅ **CRC8校验保证**:所有RS-485帧都进行CRC8校验,确保数据完整性
355
- - ✅ **QoS=1消息保证**:命令和状态都使用QoS=1,确保消息不丢失
356
- - ✅ **持久化会话**:clean=false,断线重连后继续接收未读消息
357
- - ✅ **Retain保留消息**:状态消息使用retain=true,新订阅者立即获取最新状态
358
- - ✅ **自动重连**:RS-485和MQTT都5秒自动重连,网络波动不影响使用
121
+ 从站开关节点连接物理开关面板(RS-485总线),监听按键事件,并通过MQTT映射控制Modbus继电器设备。
359
122
 
360
123
  #### 配置参数
361
124
 
362
- **RS-485总线连接配置(轻量级协议V0.13)**
125
+ **RS-485总线连接配置**
363
126
  - **连接类型**:选择TCP/IP或串口
364
- - **TCP主机**:RS-485转TCP网关地址(如:192.168.1.200)
127
+ - **TCP主机**:RS-485转TCP网关地址
365
128
  - **TCP端口**:网关端口(默认:8888)
366
129
  - **串口**:串口名称(如:COM1、/dev/ttyUSB0)
367
- - **波特率**:9600(协议标准,1起始位,8数据位,1停止位,无校验位)
368
- - **数据位**:8(固定)
369
- - **停止位**:1(固定)
370
- - **校验位**:无(固定)
371
-
372
- **协议说明:**
373
- - 帧格式:`0x7E + 数据 + CRC8 + 0x7D`
374
- - 数据类型:0x01应答、0x02查询、0x03设置、0x04上报
375
- - 设备类型:0x01灯光、0x07场景
376
- - 操作码:0x00单灯、0x05多灯
377
- - 校验:CRC8算法(多项式0x07)
378
-
379
- **MQTT服务器配置**
380
- - **MQTT服务器**:选择或添加MQTT服务器配置节点(需与主站节点使用相同配置)
130
+ - **波特率**:9600(协议标准)
381
131
 
382
132
  **物理开关面板配置**
383
- - **面板品牌**:选择开关面板品牌
384
- - **亖米(Symi)**:默认品牌,完整实现轻量级协议V0.13
385
- - **其他品牌**:预留扩展接口,后续支持更多1-8键开关品牌
386
- - **开关ID**:物理开关面板的设备地址(0-255,RS-485总线地址)
387
- - **按钮编号**:物理面板上的按键编号(1-8键开关)
133
+ - **面板品牌**:选择开关面板品牌(默认:亖米)
134
+ - **开关ID**:物理开关面板的设备地址(0-255)
135
+ - **按钮编号**:物理面板上的按键编号(1-8
388
136
 
389
137
  **映射到继电器设备**
390
138
  - **目标从站地址**:要控制的Modbus继电器设备地址(10-247)
391
139
  - **目标线圈编号**:继电器的具体通道(0-31)
392
140
 
393
- #### 输入消息
394
-
395
- ```javascript
396
- // 布尔值
397
- msg.payload = true; // 开
398
- msg.payload = false; // 关
399
-
400
- // 字符串
401
- msg.payload = "ON"; // 开
402
- msg.payload = "OFF"; // 关
403
-
404
- // 数字
405
- msg.payload = 1; // 开
406
- msg.payload = 0; // 关
407
- ```
408
-
409
- #### 输出消息
410
-
411
- ```javascript
412
- {
413
- payload: true, // 当前状态
414
- topic: "switch_0_btn1", // 主题(开关ID_按钮编号)
415
- switchId: 0, // 物理开关面板ID
416
- button: 1, // 面板按钮编号
417
- targetSlave: 10, // 映射到的继电器从站
418
- targetCoil: 0 // 映射到的继电器线圈
419
- }
420
- ```
421
-
422
- #### 一对多/多对一配置
423
-
424
- **支持灵活的映射关系,通过创建多个从站节点实现:**
425
-
426
- **场景1:一个按钮控制多个继电器(一对多)**
427
- ```
428
- 创建3个从站开关节点:
429
- 节点A: 开关ID=0, 按钮1 → 继电器10-线圈0
430
- 节点B: 开关ID=0, 按钮1 → 继电器10-线圈1
431
- 节点C: 开关ID=0, 按钮1 → 继电器11-线圈5
432
-
433
- 效果:按下物理按钮1时,3个继电器同时动作
434
- ```
435
-
436
- **场景2:多个按钮控制同一个继电器(多对一)**
437
- ```
438
- 创建3个从站开关节点:
439
- 节点A: 开关ID=0, 按钮1 → 继电器10-线圈0
440
- 节点B: 开关ID=0, 按钮2 → 继电器10-线圈0
441
- 节点C: 开关ID=5, 按钮3 → 继电器10-线圈0
442
-
443
- 效果:任意一个按钮都可以控制同一个继电器
444
- ```
445
-
446
- **场景3:复杂联动控制**
447
- ```
448
- 物理面板1的按钮1 → 控制客厅灯(继电器10-0)+ 走廊灯(继电器10-1)
449
- 物理面板2的按钮3 → 控制客厅灯(继电器10-0)+ 卧室灯(继电器11-2)
450
-
451
- 实现:创建4个从站节点,灵活组合
452
- ```
453
-
454
- #### 配置映射示例
455
-
456
- **示例1:亖米开关ID=0,按钮1 → 继电器10-线圈0**
457
- ```
458
- 物理面板配置:
459
- ├─ 面板品牌:亖米(Symi)
460
- ├─ 开关ID:0(物理面板地址)
461
- ├─ 按钮编号:1(面板按钮1)
462
- 映射到继电器:
463
- ├─ 从站地址:10(Modbus继电器设备10)
464
- └─ 线圈编号:0(继电器通道0)
465
-
466
- MQTT主题:
467
- ├─ 订阅状态:modbus/relay/10/0/state
468
- └─ 发布命令:modbus/relay/10/0/set
469
- ```
470
-
471
- **示例2:亖米开关ID=5,按钮3 → 继电器11-线圈15**
472
- ```
473
- 物理面板配置:
474
- ├─ 面板品牌:亖米(Symi)
475
- ├─ 开关ID:5(物理面板地址)
476
- ├─ 按钮编号:3(面板按钮3)
477
- 映射到继电器:
478
- ├─ 从站地址:11(Modbus继电器设备11)
479
- └─ 线圈编号:15(继电器通道15)
480
-
481
- MQTT主题:
482
- ├─ 订阅状态:modbus/relay/11/15/state
483
- └─ 发布命令:modbus/relay/11/15/set
484
- ```
485
-
486
- ## 节点架构
487
-
488
- ### 系统架构图(v1.3.0完整版)
489
-
490
- ```
491
- ┌────────────────────────────────────────────────────────────────────────────────────┐
492
- │ 完整三向通信系统架构 │
493
- └────────────────────────────────────────────────────────────────────────────────────┘
494
-
495
- 物理开关面板 从站开关节点 MQTT Broker 主站节点 继电器设备
496
- (RS-485总线) (双协议桥接) (Modbus通信) (TCP/串口)
497
- ┌──────────┐ ┌──────────────┐ ┌────────────┐ ┌───────────┐ ┌──────────┐
498
- │ 开关ID=0 │◄─RS485───►│ 轻量级协议 │◄─MQTT────►│ QoS=1 │◄────►│ Modbus │◄────►│ 从站10 │
499
- │ 按钮1-8 │ 9600 8N1 │ 解析/构建 │ 命令/状态 │ 持久化 │ 轮询 │ 功能码 │ TCP │ 线圈0-31 │
500
- │ │ │ CRC8校验 │ │ Retain │ 写入 │ 01/05/0F │ 502 │ │
501
- │ • 按键输入│ ────────> │ • 0x04上报解析│ ────────> │ /10/0/set │ ────> │ • 写线圈 │ ────>│ • 继电器 │
502
- │ • 指示灯 │ <──────── │ • 0x03设置构建│ <──────── │ /10/0/state│ <──── │ • 读状态 │ <────│ • 动作 │
503
- └──────────┘ └──────────────┘ └────────────┘ └───────────┘ └──────────┘
504
- 开关ID=5 开关ID=0-255 ↓ 从站10-19 从站10-19
505
- 开关ID=10 按钮1-8映射 ┌────────────┐ 线圈0-31 线圈0-31
506
- ... 继电器任意组合 │Home Assistant│
507
- │ MQTT Discovery│
508
- │ 自动发现实体 │
509
- └────────────┘
510
-
511
- 【关键特性】
512
- ✅ 轻量级协议V0.13:完整实现帧头0x7E、数据、CRC8校验、帧尾0x7D
513
- ✅ Modbus主站节点:轮询继电器设备(10-19),MQTT发布状态,HA自动发现
514
- ✅ 从站开关节点:RS-485监听按键 + MQTT命令 + 指示灯同步,完整三向通信
515
- ✅ MQTT双协议桥接:轻量级协议(RS-485) ↔ MQTT ↔ Modbus协议
516
- ✅ Home Assistant集成:MQTT Discovery自动创建实体,完美兼容
517
- ```
518
-
519
141
  ## 快速开始
520
142
 
521
- ### 基础使用
522
-
523
- #### 配置MQTT服务器(首次使用)
143
+ ### 配置MQTT服务器(首次使用)
524
144
 
525
145
  1. 拖拽任意节点(主站或从站)到流程画布
526
146
  2. 双击节点,找到"MQTT服务器"字段
527
- 3. 点击旁边的编辑按钮(铅笔图标)
528
- 4. 点击"添加新的mqtt-server-config..."
529
- 5. 填写MQTT服务器信息:
530
- - **MQTT服务器**:mqtt://192.168.1.100:1883
531
- - **用户名**:(可选)
532
- - **密码**:(可选)
533
- - **基础主题**:modbus/relay
534
- 6. 点击"添加"保存配置
147
+ 3. 点击旁边的编辑按钮
148
+ 4. 填写MQTT服务器信息并保存
535
149
 
536
- #### 配置主站节点
150
+ ### 配置主站节点
537
151
 
538
152
  1. 拖拽 **Modbus主站** 节点到流程画布
539
- 2. 双击节点,配置连接参数:
540
-
541
- **TCP连接:**
542
- - 连接类型:TCP/IP
543
- - TCP主机:192.168.1.100
544
- - TCP端口:502
545
-
546
- **串口连接:**
547
- - 连接类型:串口
548
- - 点击"搜索串口"按钮查找可用串口
549
- - 从下拉列表中选择串口(自动填入)
550
- - 或手动输入:COM1 / /dev/ttyUSB0 / /dev/ttyS1
551
- - 波特率:9600(或根据设备要求,8-N-1已固定)
552
-
553
- 3. 配置从站设备:
554
- - 默认已有1个从站(地址10)
555
- - 点击"添加从站"按钮可添加更多(最多10个)
556
- - 每个从站自动递增地址(10→11→12...)
153
+ 2. 双击节点配置连接参数
154
+ 3. 配置从站设备
557
155
  4. 启用MQTT(如果需要与HA集成)
558
- 5. 选择已配置的MQTT服务器
559
- 6. 部署流程
156
+ 5. 部署流程
560
157
 
561
- #### 配置从站开关节点
158
+ ### 配置从站开关节点
562
159
 
563
160
  1. 拖拽 **从站开关** 节点到流程画布
564
- 2. 双击节点配置:
565
-
566
- **RS-485总线连接:**
567
- - **连接类型**:TCP/IP 或 串口
568
-
569
- TCP模式:
570
- - **TCP主机**:192.168.1.200(RS-485转TCP网关地址)
571
- - **TCP端口**:8888
572
-
573
- 串口模式:
574
- - 点击"搜索串口"按钮查找可用串口
575
- - 从下拉列表中选择串口(自动填入)
576
- - 或手动输入:COM1 / /dev/ttyUSB0 / /dev/ttyS1
577
- - **波特率**:9600(亖米协议固定,8-N-1已自动配置)
578
-
579
- **MQTT服务器:**
580
- - 选择与主站相同的MQTT配置
581
-
582
- **开关面板:**
583
- - **面板品牌**:亖米(Symi)- 默认,支持1-8键开关
584
- - **开关ID**:0(物理面板地址,0-255)
585
- - **按钮编号**:1(面板按钮,1-8)
586
-
587
- **映射到继电器:**
588
- - **从站地址**:10(Modbus继电器设备地址)
589
- - **线圈编号**:0(继电器通道,0-31)
590
-
591
- 3. 连接输入节点(可选,用于手动控制)
592
- 4. 连接输出节点(如:debug节点)查看状态
161
+ 2. 配置RS-485总线连接
162
+ 3. 配置开关面板信息
163
+ 4. 配置映射到的继电器
593
164
  5. 部署流程
594
165
 
595
- **配置示例:**
596
- ```
597
- 【完整配置】
598
- RS-485连接:TCP网关192.168.1.200:8888(或串口/dev/ttyUSB0 9600)
599
- MQTT服务器:本地MQTT服务器(192.168.1.100:1883)
600
- 面板品牌:亖米(Symi)- 支持1-8键开关
601
- 物理面板:开关ID=0,按钮1
602
- 映射到:继电器10,线圈0
603
-
604
- 【工作流程】
605
- 物理按钮1按下
606
- → RS-485上报: 7E 01 04 0F 01 00 00 01 00 00 00 00 01 XX 7D
607
- → 从站解析:检测到开关0按钮1按下
608
- → MQTT命令: modbus/relay/10/0/set → "ON"
609
- → 主站写入: Modbus从站10线圈0 → 1
610
- → 继电器动作:继电器ON
611
- → 主站轮询:检测到状态变化
612
- → MQTT状态: modbus/relay/10/0/state → "ON" (retain)
613
- → 从站接收:构建RS-485控制帧
614
- → RS-485设置: 7E 01 03 0F 01 00 00 01 00 00 00 00 01 XX 7D
615
- → 面板指示灯:指示灯ON
616
- ```
617
-
618
- ### 导入示例流程
619
-
620
- 项目包含示例流程文件 `examples/basic-flow.json`:
621
-
622
- 1. 点击右上角菜单 → 导入
623
- 2. 选择 `examples/basic-flow.json` 文件
624
- 3. 导入后即可测试所有功能
625
-
626
- 示例流程包含:
627
- - 启动/停止轮询
628
- - 写单个线圈
629
- - 开关节点控制
630
- - 调试输出
631
-
632
- ### TCP连接示例
633
-
634
- ```
635
- 配置:
636
- - 连接类型:TCP/IP
637
- - TCP主机:192.168.1.100
638
- - TCP端口:502
639
-
640
- 从站1:
641
- - 地址:10 (0x0A)
642
- - 线圈范围:0-31
643
- - 轮询间隔:200ms
644
-
645
- 从站2:(点击"添加从站"按钮)
646
- - 地址:11 (0x0B)(自动递增)
647
- - 线圈范围:0-31
648
- - 轮询间隔:200ms
649
- ```
650
-
651
- ### 串口连接示例(支持自动搜索)
652
-
653
- ```
654
- 配置方式1:自动搜索(推荐)
655
- 1. 连接类型:串口
656
- 2. 点击"搜索串口"按钮
657
- 3. 等待系统检测串口(1-2秒)
658
- 4. 从下拉列表中选择串口
659
- - 支持:COM1, COM2, COM3... (Windows)
660
- - 支持:/dev/ttyUSB0, /dev/ttyS1, /dev/ttyS2... (Linux/macOS)
661
- - 显示厂商信息,便于识别设备
662
- 5. 波特率:9600(默认,已自动配置8-N-1)
663
-
664
- 配置方式2:手动输入
665
- - 连接类型:串口
666
- - 串口:COM3(Windows)或 /dev/ttyUSB0 或 /dev/ttyS1(Linux/macOS)
667
- - 波特率:9600
668
- - 其他参数:8-N-1(已固定,无需配置)
669
- ```
670
-
671
- ### MQTT集成示例
672
-
673
- 启用MQTT后,可与Home Assistant或其他MQTT平台集成:
674
-
675
- 1. 在主站节点中启用MQTT
676
- 2. 配置MQTT服务器地址
677
- 3. 部署流程
678
- 4. Home Assistant会自动发现设备
679
-
680
166
  ## Home Assistant集成
681
167
 
682
- 本节点完全兼容Home Assistant的MQTT Discovery标准,支持自动发现和持久化:
168
+ 本节点完全兼容Home Assistant的MQTT Discovery标准,支持自动发现和持久化。
683
169
 
684
170
  ### 集成步骤
685
171
 
686
- 1. **配置MQTT集成**
687
- - 确保Home Assistant已配置MQTT集成
688
- - 记下MQTT Broker地址(如:mqtt://192.168.1.100:1883)
689
-
690
- 2. **配置MQTT服务器节点**
691
- - 创建一个MQTT服务器配置节点(mqtt-server-config)
692
- - 配置MQTT Broker地址、用户名、密码、基础主题
693
- - 所有主站和从站节点引用此配置
694
-
695
- 3. **配置Node-RED主站节点**
696
- - 在主站节点中启用MQTT
697
- - 选择已配置的MQTT服务器
698
- - 添加从站设备(点击"添加从站"按钮,可添加多个设备)
699
- - 默认第一个从站地址为10,后续自动递增为11、12...
700
-
701
- 4. **部署流程**
702
- - 点击Node-RED的Deploy按钮
703
- - 节点会自动发布MQTT Discovery消息
704
- - 设备自动出现在Home Assistant中
705
-
706
- 5. **验证集成**
707
- - 在HA中查看:设置 → 设备与服务 → MQTT → 设备
708
- - 每个从站显示为一个设备(如:`Modbus继电器-10`)
709
- - 每个继电器显示为一个开关实体
172
+ 1. 确保Home Assistant已配置MQTT集成
173
+ 2. 配置MQTT服务器节点
174
+ 3. 在主站节点中启用MQTT
175
+ 4. 部署流程
176
+ 5. 设备自动出现在Home Assistant中
710
177
 
711
178
  ### 实体和设备规则
712
179
 
713
- **唯一ID规则(确保不重复):**
714
180
  - 设备唯一标识符:`modbus_relay_{从站地址}`
715
181
  - 实体唯一ID:`modbus_relay_{从站地址}_{线圈编号}`
716
182
  - 实体ID:`switch.relay_{从站地址}_{线圈编号}`
717
183
 
718
- **示例:**
719
- ```
720
- 从站地址=10,线圈0-31:
721
- ├─ 设备:Modbus继电器-10 (标识符: modbus_relay_10)
722
- │ ├─ 实体:switch.relay_10_0 (继电器 10-0)
723
- │ ├─ 实体:switch.relay_10_1 (继电器 10-1)
724
- │ └─ ... (共32个实体)
725
-
726
- 从站地址=11,线圈0-31:
727
- ├─ 设备:Modbus继电器-11 (标识符: modbus_relay_11)
728
- ├─ 实体:switch.relay_11_0 (继电器 11-0)
729
- └─ ...
730
- ```
731
-
732
- ### 持久化和稳定性保证
733
-
734
- ✅ **唯一ID稳定性**
735
- - 使用从站地址作为设备标识符
736
- - 使用从站地址+线圈编号作为实体唯一ID
737
- - 断电、重启、重新部署不会创建重复实体
738
-
739
- ✅ **MQTT retain消息**
740
- - 所有发现消息使用`retain=true`
741
- - HA重启后自动重新发现设备
742
-
743
- ✅ **设备可用性状态**
744
- - 每个从站有独立的availability主题
745
- - 节点关闭时自动发送`offline`状态
746
- - 节点启动时自动发送`online`状态
747
-
748
- ✅ **避免重复实体的机制**
749
- 1. 稳定的unique_id(基于从站地址)
750
- 2. MQTT retain消息保持配置
751
- 3. 设备标识符保持不变
752
- 4. HA会自动识别并更新现有实体,不会创建新的
753
-
754
- ### 多从站配置示例
755
-
756
- **场景1:3台32路继电器**
757
- ```
758
- 从站配置(点击3次"添加从站"):
759
- - 从站1:地址10,线圈0-31,间隔200ms
760
- - 从站2:地址11,线圈0-31,间隔200ms
761
- - 从站3:地址12,线圈0-31,间隔200ms
762
-
763
- Home Assistant结果:
764
- - 设备10:32个实体(switch.relay_10_0 到 switch.relay_10_31)
765
- - 设备11:32个实体(switch.relay_11_0 到 switch.relay_11_31)
766
- - 设备12:32个实体(switch.relay_12_0 到 switch.relay_12_31)
767
- 总计:3个设备,96个实体
768
- ```
769
-
770
- **场景2:10台32路继电器(最大容量)**
771
- ```
772
- 从站配置(点击10次"添加从站"):
773
- - 从站1-10:地址10-19,每个线圈0-31,间隔200ms
774
-
775
- Home Assistant结果:
776
- 10个设备(地址10-19),总计320个实体
777
- ```
778
-
779
- **场景3:不同线圈范围配置**
780
- ```
781
- 从站配置:
782
- - 从站1:地址10,线圈0-7(仅8路继电器),间隔150ms
783
- - 从站2:地址15,线圈0-15(16路继电器),间隔200ms
784
- - 从站3:地址20,线圈0-31(全部32路),间隔250ms
785
-
786
- Home Assistant结果:
787
- - 设备10:8个实体
788
- - 设备15:16个实体
789
- - 设备20:32个实体
790
- 总计:3个设备,56个实体
791
- ```
792
-
793
- ### 故障恢复测试
794
-
795
- ✅ **RS-485断线/恢复**:5秒自动重连,按键事件和指示灯控制自动恢复
796
- ✅ **MQTT断线/恢复**:5秒自动重连,QoS=1保证离线消息不丢失
797
- ✅ **Modbus断线/恢复**:5秒自动重连,继续轮询其他正常设备
798
- ✅ **断网/通网**:不影响,所有连接自动重连,retain消息保持配置
799
- ✅ **断电/通电**:不影响,所有配置持久化,上电后自动运行
800
- ✅ **HA重启**:不影响,通过retain消息自动重新发现
801
- ✅ **Node-RED重启**:不影响,配置自动加载,连接自动建立
802
-
803
- ## 智能日志系统
804
-
805
- ### 日志限流机制
806
-
807
- 为避免日志过多导致内存占用过大,本节点实现了智能日志限流系统:
808
-
809
- **工作原理**:
810
- - **首次错误**:立即显示完整错误信息
811
- - **重复错误**:10分钟内不再重复显示相同错误
812
- - **10分钟后**:再次显示错误,确保持续监控
813
- - **重新部署**:清除日志记录,允许立即显示错误
814
-
815
- **日志提示**:
816
- ```
817
- [warn] 轮询从站10失败(不影响其他从站): Timed out [此错误将在10分钟后再次显示]
818
- ```
819
-
820
- **好处**:
821
- - ✅ 避免日志文件快速增长
822
- - ✅ 防止内存占用过大
823
- - ✅ 保持错误监控能力
824
- - ✅ 不影响正常功能
825
-
826
- **适用场景**:
827
- - Modbus设备未连接时的超时错误
828
- - MQTT服务器未配置时的连接错误
829
- - 其他周期性重复的错误
830
-
831
- ## 可靠性保证
832
-
833
- ### 消息队列和并发处理
834
-
835
- **Node-RED内置机制:**
836
- - ✅ **单线程事件循环**:自动排队处理,不会丢失消息
837
- - ✅ **异步非阻塞**:大量设备同时动作时不会阻塞
838
- - ✅ **自动流控**:内部队列管理,防止消息堆积
839
-
840
- **MQTT QoS保证:**
841
- - ✅ **QoS=1(至少一次)**:所有命令和状态消息都使用QoS=1
842
- - 发送方等待接收方确认
843
- - 未收到确认会重发
844
- - 保证消息至少送达一次
845
- - ✅ **持久化会话(clean=false)**:
846
- - 客户端离线期间的消息会被MQTT Broker保存
847
- - 重连后自动接收离线期间的消息
848
- - ✅ **Retain保留消息**:
849
- - 状态消息使用retain=true
850
- - 新订阅者立即获取最新状态
851
- - 断电重启后自动恢复状态
852
-
853
- ### 断电/断网/重启测试
854
-
855
- | 场景 | 行为 | 恢复时间 | 数据丢失 |
856
- |------|------|---------|---------|
857
- | **Node-RED重启** | 自动重连MQTT和Modbus | 5-10秒 | ❌ 无(配置持久化) |
858
- | **MQTT Broker重启** | 5秒自动重连 | <10秒 | ❌ 无(retain消息恢复) |
859
- | **网络断开** | 自动重连,离线消息缓存 | 网络恢复后5秒 | ❌ 无(QoS=1保证) |
860
- | **主机断电** | 重启后自动加载配置 | 主机启动时间+10秒 | ❌ 无(配置和状态都持久化) |
861
- | **Modbus设备断电** | 主站显示设备离线,继续轮询 | 设备上电后立即恢复 | ❌ 无 |
862
-
863
- ### 大量设备并发性能
864
-
865
- **测试场景:100个从站开关节点同时控制100个继电器**
866
-
867
- | 指标 | 性能 | 说明 |
868
- |------|------|------|
869
- | **消息处理速度** | >1000条/秒 | MQTT.js高性能库 |
870
- | **命令延迟** | <200ms | 发送命令到继电器执行 |
871
- | **状态反馈延迟** | <300ms | 继电器状态变化到从站显示 |
872
- | **并发处理能力** | 无限制 | 自动队列管理 |
873
- | **消息丢失率** | 0% | QoS=1保证 |
874
- | **内存占用** | <50MB | 100个节点 |
875
-
876
- **实际测试验证:**
877
- ```
878
- 场景:10个物理开关面板,每个8个按钮,映射到10台32路继电器
879
- 节点数量:80个从站开关节点 + 1个主站节点
880
- 同时按下10个按钮:所有继电器在200ms内响应,无遗漏
881
- ```
882
-
883
- ### 配置持久化机制
884
-
885
- | 配置项 | 存储位置 | 持久化方式 | 重启后恢复 |
886
- |--------|---------|-----------|----------|
887
- | **MQTT服务器配置** | Node-RED flows文件 | JSON持久化 | ✅ 自动 |
888
- | **主站节点配置** | Node-RED flows文件 | JSON持久化 | ✅ 自动 |
889
- | **从站节点配置** | Node-RED flows文件 | JSON持久化 | ✅ 自动 |
890
- | **继电器状态** | MQTT Broker(retain) | MQTT持久化 | ✅ 自动 |
891
- | **Home Assistant实体** | HA数据库+MQTT Discovery | 双重持久化 | ✅ 自动 |
892
-
893
- **所有配置和状态都是永久保存的,无需手动备份!**
894
-
895
184
  ## 技术规格
896
185
 
897
- ### Modbus协议(主站节点)
186
+ ### Modbus协议
898
187
 
899
188
  - **Modbus协议**:Modbus TCP / Modbus RTU
900
- - **功能码支持**:
901
- - 0x01:读线圈状态(Read Coils)
902
- - 0x05:写单个线圈(Write Single Coil)
903
- - 0x0F:写多个线圈(Write Multiple Coils)
189
+ - **功能码支持**:0x01(读线圈)、0x05(写单个线圈)、0x0F(写多个线圈)
904
190
  - **从站地址范围**:1-247
905
191
  - **线圈数量**:每台设备32个(0-31)
906
192
  - **最大设备数**:10台同时轮询
907
- - **轮询间隔**:最小10ms,默认200ms,推荐≥100ms
908
- - **连接超时**:5秒
909
- - **自动重连**:连接失败后每5秒重试
910
- - **错误恢复**:自动检测连接断开并重连
911
-
912
- ### 轻量级协议(从站节点,V0.13)
913
-
914
- #### 品牌支持
915
-
916
- - **亖米(Symi)**:默认品牌,完整实现轻量级协议V0.13
917
- - 支持1-8键开关面板
918
- - RS-485总线通信(TCP网关或串口)
919
- - 完整的按键监听和指示灯控制
920
- - CRC8校验保证数据完整性
921
- - **其他品牌**:预留扩展接口
922
- - 可通过修改协议适配其他品牌1-8键开关
923
- - 后续版本将陆续增加更多品牌支持
924
-
925
- #### 亖米协议规格
926
-
927
- - **物理层**:RS-485总线
928
- - **串口参数**:波特率9600,1起始位,8数据位,1停止位,无校验位
929
- - **帧格式**:`[0x7E][数据][CRC8][0x7D]`
930
- - **帧长度**:15-500字节
931
- - **校验算法**:CRC8(多项式0x07)
932
- - **本机地址**:0x01(网关地址)
933
- - **广播地址**:0x7F
934
-
935
- **数据类型:**
936
- - 0x01:应答(面板→网关)
937
- - 0x02:查询(网关→面板)
938
- - 0x03:设置(网关→执行设备)
939
- - 0x04:上报(执行设备→网关)
940
-
941
- **设备类型:**
942
- - 0x01:灯光(继电器、调光、RGBW)
943
- - 0x02:空调(电源、模式、风速、温度)
944
- - 0x03:窗帘(开关、百分比)
945
- - 0x04:音乐(播放、音源、音量)
946
- - 0x05:地暖(电源、温度)
947
- - 0x06:新风(电源、风速)
948
- - 0x07:场景(场景号1-9)
949
- - 0xF1:多通道继电器(1-8路)
950
-
951
- **灯光操作码:**
952
- - 0x00:单灯控制(1开0关)
953
- - 0x02:单灯调光(亮度0-100)
954
- - 0x03:双色温调光(色温+亮度)
955
- - 0x04:RGBW调光(红绿蓝+亮度)
956
- - 0x05:多灯控制(延时+8bit状态位图)
957
-
958
- **协议示例:**
959
- ```
960
- 单灯控制 - 开关ID=1,按钮3,开启:
961
- 7E 01 03 0F 01 00 01 03 00 00 00 00 01 XX 7D
962
- │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ 帧尾
963
- │ │ │ │ │ │ │ │ │ │ │ │ │ └──── CRC8校验
964
- │ │ │ │ │ │ │ │ │ │ │ │ └─────── 操作信息(1=开)
965
- │ │ │ │ │ │ │ │ │ │ │ └────────── 操作码(0x00=单灯)
966
- │ │ │ │ │ │ │ │ └──┴──┴───────────── 房间信息(默认00)
967
- │ │ │ │ │ │ │ └─────────────────────── 通道(3=按钮3)
968
- │ │ │ │ │ │ └────────────────────────── 设备地址(1=开关ID)
969
- │ │ │ │ │ └───────────────────────────── 品牌ID(00)
970
- │ │ │ │ └──────────────────────────────── 设备类型(0x01=灯光)
971
- │ │ │ └─────────────────────────────────── 数据长度(0x0F=15字节)
972
- │ │ └────────────────────────────────────── 数据类型(0x03=设置)
973
- │ └───────────────────────────────────────── 本机地址(0x01=网关)
974
- └──────────────────────────────────────────── 帧头(0x7E)
975
-
976
- 设备上报 - 按钮按下事件:
977
- 7E 01 04 0F 01 00 01 03 00 00 00 00 01 XX 7D
978
- │ │ └─ 状态(1=按下)
979
- │ └─ 数据类型(0x04=上报)
980
- └──── 本机地址(从物理面板)
981
- ```
193
+ - **轮询间隔**:最小10ms,默认200ms,推荐>=100ms
982
194
 
983
195
  ### 兼容性
984
196
 
985
197
  - **Node.js**: >= 14.0.0
986
198
  - **Node-RED**: >= 2.0.0
987
- - **已测试环境**: Node-RED v4.0.8 / Node.js v23.1.0
988
199
  - **MQTT Broker**: Mosquitto / EMQ / Any MQTT 3.1.1/5.0
989
200
  - **Home Assistant**: 2024.x+(MQTT Discovery标准)
990
201
  - **操作系统**: Windows / Linux / macOS
991
202
 
992
203
  ## 故障排除
993
204
 
994
- ### 节点没有出现在面板中
995
-
996
- **症状**:安装后在Node-RED左侧面板找不到节点
997
-
998
- **解决方案**:
999
- 1. 确认已重启Node-RED(**必须重启!**)
1000
- 2. 检查安装路径:`~/.node-red/node_modules/node-red-contrib-symi-modbus`
1001
- 3. 查看Node-RED启动日志是否有错误
1002
- 4. 清除浏览器缓存并刷新页面
1003
-
1004
- ```bash
1005
- # 重启Node-RED
1006
- # 按 Ctrl+C 停止,然后重新运行
1007
- node-red
1008
- ```
1009
-
1010
205
  ### 连接失败
1011
206
 
1012
207
  **TCP连接失败**:
1013
208
  - 检查网络连通性:`ping <IP地址>`
1014
209
  - 确认Modbus TCP服务器地址和端口
1015
210
  - 检查防火墙设置
1016
- - 确认设备已启动Modbus TCP服务
1017
211
 
1018
212
  **串口连接失败**:
1019
- - **使用串口搜索功能**:点击"搜索串口"按钮自动检测可用串口
1020
- - 确认串口名称正确(Windows设备管理器或Linux `ls /dev/tty*`)
1021
- - 检查串口权限(Linux需要:`sudo usermod -a -G dialout $USER`,然后重新登录)
1022
- - 确认波特率等参数与设备匹配
213
+ - 确认串口名称正确
214
+ - 检查串口权限(Linux需要添加到dialout组)
1023
215
  - 确保串口没有被其他程序占用
1024
- - 重新拔插USB串口适配器
1025
-
1026
- **串口列表为空**:
1027
- - 确认系统已正确安装USB驱动
1028
- - Windows:检查设备管理器中的"端口(COM和LPT)"
1029
- - Linux/macOS:运行 `ls /dev/tty*` 查看串口设备(/dev/ttyUSB0、/dev/ttyS1等)
1030
- - 可以手动输入串口路径,无需依赖自动搜索
1031
-
1032
- ### 轮询错误
1033
-
1034
- 1. 检查从站地址是否正确(默认10,即0x0A)
1035
- 2. 确认设备在线且响应正常
1036
- 3. 验证线圈范围是否超出设备限制
1037
- 4. 适当增加轮询间隔(快速轮询可能导致超时)
1038
- 5. 查看Node-RED日志获取详细错误信息
1039
-
1040
- **关于日志输出**:
1041
- - 本节点使用智能日志限流机制,相同的错误每10分钟只显示一次
1042
- - 重新部署流程时会清除日志记录,允许再次显示错误
1043
- - 这样可以避免日志过多导致内存占用过大
1044
- - 如果看到"[此错误将在10分钟后再次显示]"提示,说明日志限流正在工作
1045
216
 
1046
217
  ### MQTT问题
1047
218
 
1048
- **症状**:HA实体显示不可用,或MQTT错误日志`ECONNREFUSED 127.0.0.1:1883`
1049
-
1050
- **根本原因**:
1051
- 1. MQTT broker未运行(如:mosquitto服务未启动)
1052
- 2. MQTT broker地址配置不适配运行环境(Docker/容器/本地)
1053
- 3. MQTT broker需要认证但未配置用户名密码
1054
- 4. 网络连接问题
1055
-
1056
- #### MQTT配置最佳实践(重要!)
1057
-
1058
- **v1.6.0+版本已内置智能连接机制**:
1059
- - ✅ 自动尝试多个候选地址(localhost → host.docker.internal → 172.17.0.1 → homeassistant → mosquitto)
1060
- - ✅ 自动fallback到可用的broker地址
1061
- - ✅ 完美兼容Docker/容器环境和本地环境
1062
- - ✅ 无需手动配置多个地址
1063
-
1064
- **推荐配置(按优先级)**:
1065
-
1066
- 1. **本地Mac/Linux/Windows环境(Node-RED直接安装)**
1067
- ```
1068
- MQTT服务器地址:mqtt://localhost:1883
1069
- ```
1070
- 节点会自动尝试:localhost → 127.0.0.1
1071
-
1072
- 2. **Docker/容器环境(Node-RED在Docker中运行)**
1073
- ```
1074
- MQTT服务器地址:mqtt://localhost:1883
1075
- ```
1076
- 节点会自动尝试:
1077
- - localhost
1078
- - host.docker.internal(Docker Desktop推荐)
1079
- - 172.17.0.1(Docker默认网关)
1080
- - homeassistant(HA容器名)
1081
- - mosquitto(Mosquitto容器名)
1082
-
1083
- 3. **Home Assistant插件/Supervisor环境**
1084
- ```
1085
- MQTT服务器地址:mqtt://localhost:1883
1086
- ```
1087
- 或使用HA的MQTT broker地址:
1088
- ```
1089
- MQTT服务器地址:mqtt://core-mosquitto:1883
1090
- ```
1091
-
1092
- 4. **自定义网络/远程broker**
1093
- ```
1094
- MQTT服务器地址:mqtt://192.168.1.100:1883
1095
- ```
1096
- 使用实际的broker IP地址
1097
-
1098
- **环境兼容性总结**:
1099
-
1100
- | 运行环境 | 推荐配置 | 自动fallback | 说明 |
1101
- |---------|---------|-------------|------|
1102
- | 本地安装 | mqtt://localhost:1883 | ✅ localhost → 127.0.0.1 | 直接连接本地broker |
1103
- | Docker Desktop (Mac/Win) | mqtt://localhost:1883 | ✅ localhost → host.docker.internal → 172.17.0.1 | 自动适配Docker网络 |
1104
- | Docker Compose | mqtt://localhost:1883 或容器名 | ✅ 容器名 → 172.17.0.1 → localhost | 优先使用Docker网络 |
1105
- | HA Supervisor | mqtt://localhost:1883 | ✅ localhost → homeassistant → core-mosquitto | 自动连接HA内置broker |
1106
- | Kubernetes | mqtt://mosquitto:1883 | ✅ service名 → localhost | 使用K8s service名称 |
1107
-
1108
- #### 解决步骤
1109
-
1110
- 1. **检查MQTT broker是否运行**
1111
- ```bash
1112
- # macOS/Linux查看mosquitto服务状态
1113
- ps aux | grep mosquitto
1114
-
1115
- # 或使用systemctl(Linux)
1116
- sudo systemctl status mosquitto
1117
-
1118
- # macOS使用brew services
1119
- brew services list | grep mosquitto
1120
-
1121
- # Docker环境检查容器
1122
- docker ps | grep mosquitto
1123
- ```
1124
-
1125
- 2. **启动MQTT broker**
1126
-
1127
- **本地环境:**
1128
- ```bash
1129
- # macOS
1130
- brew services start mosquitto
1131
-
1132
- # Linux (systemd)
1133
- sudo systemctl start mosquitto
1134
-
1135
- # 或直接运行
1136
- mosquitto -v
1137
- ```
1138
-
1139
- **Docker环境:**
1140
- ```bash
1141
- # 启动Mosquitto容器
1142
- docker run -d --name mosquitto -p 1883:1883 eclipse-mosquitto
1143
-
1144
- # 或使用docker-compose
1145
- docker-compose up -d mosquitto
1146
- ```
1147
-
1148
- 3. **验证MQTT连接**
1149
- ```bash
1150
- # 订阅测试主题(打开一个终端)
1151
- mosquitto_sub -h localhost -t test
1152
-
1153
- # 发布测试消息(打开另一个终端)
1154
- mosquitto_pub -h localhost -t test -m "hello"
1155
-
1156
- # 如果收到消息,说明MQTT broker正常运行
1157
-
1158
- # Docker环境中测试
1159
- docker exec -it <node-red-container> mosquitto_pub -h host.docker.internal -t test -m "hello"
1160
- ```
1161
-
1162
- 4. **检查Node-RED日志(重要!)**
1163
-
1164
- **v1.6.0+版本会显示详细的连接日志:**
1165
- ```
1166
- ✅ 成功日志:
1167
- MQTT broker候选地址: mqtt://localhost:1883, mqtt://host.docker.internal:1883, ...
1168
- 正在连接MQTT broker: mqtt://localhost:1883
1169
- MQTT已连接: mqtt://host.docker.internal:1883
1170
- 使用fallback地址成功: mqtt://host.docker.internal:1883(原配置: mqtt://localhost:1883)
1171
-
1172
- ❌ 错误日志:
1173
- MQTT错误: connect ECONNREFUSED 127.0.0.1:1883
1174
- 所有MQTT broker候选地址都无法连接: mqtt://localhost:1883, mqtt://host.docker.internal:1883, ...
1175
- 请检查:1) MQTT broker是否运行 2) 网络连接是否正常 3) broker地址是否正确
1176
- 提示:如果Node-RED运行在Docker容器中,可能需要使用host.docker.internal或容器IP
1177
- ```
1178
-
1179
- 5. **正确配置MQTT服务器节点**
1180
- - 在Node-RED中打开任意主站或从站节点
1181
- - 找到"MQTT服务器"字段,点击编辑按钮
1182
- - 填写broker地址:`mqtt://localhost:1883`(推荐,会自动fallback)
1183
- - 如果需要认证,填写用户名和密码
1184
- - 点击"添加"保存配置
1185
- - 重新部署流程
1186
-
1187
- 6. **HA实体不可用的特殊情况**
1188
- - 如果HA中实体显示不可用(unavailable),首先确保MQTT连接正常
1189
- - 查看Node-RED日志确认"MQTT已连接"
1190
- - 然后确保主站节点已启动轮询(查看日志:"开始轮询 X 个从站设备")
1191
- - 如果轮询成功,实体应该在几秒内变为可用状态
1192
- - v1.6.0+版本已优化连接机制,确保使用最新版本
1193
-
1194
- #### 常见错误和解决方案
1195
-
1196
- | 错误提示 | 原因 | 解决方案 |
1197
- |---------|------|---------|
1198
- | `ECONNREFUSED 127.0.0.1:1883` | MQTT broker未运行或地址不对 | 1) 启动broker 2) 让节点自动尝试fallback地址(v1.6.0+) |
1199
- | `所有MQTT broker候选地址都无法连接` | 所有地址都无法连接 | 1) 确认broker运行 2) 检查防火墙 3) 使用实际IP地址 |
1200
- | `MQTT已启用但broker地址未配置` | 未配置MQTT服务器节点 | 在MQTT服务器配置节点中填写broker地址 |
1201
- | 实体不可用但MQTT已连接 | Modbus轮询未启动或失败 | 检查Modbus连接和从站配置 |
1202
-
1203
- ### 测试设备
1204
-
1205
- 如果没有真实Modbus设备,可以使用模拟器测试:
1206
-
1207
- **Windows**:
1208
- - ModRSsim2(免费Modbus模拟器)
1209
- - 下载:https://sourceforge.net/projects/modrssim2/
1210
-
1211
- **跨平台**:
1212
- ```bash
1213
- # 安装pymodbus
1214
- pip install pymodbus
1215
-
1216
- # 运行TCP模拟器
1217
- python -m pymodbus.server tcp --port 502
1218
- ```
1219
-
1220
- ## 开发计划
1221
-
1222
- ### 即将推出的功能
1223
-
1224
- - [ ] **调光从站节点**:支持0-100%调光控制
1225
- - [ ] **窗帘从站节点**:开关、停止、位置控制
1226
- - [ ] **温控从站节点**:温度设置和模式控制
1227
- - [ ] **更多Modbus功能码**:读保持寄存器、输入寄存器等
1228
- - [ ] **数据持久化**:保存设备状态
1229
- - [ ] **设备分组管理**:批量操作多个设备
1230
- - [ ] **Web配置界面**:可视化配置工具
1231
-
1232
- ### 贡献
1233
-
1234
- 欢迎贡献代码、报告问题、提出建议!
1235
-
1236
- ## 更新日志
1237
-
1238
- ### v1.6.0 (2025-10-18) - 智能MQTT连接和Docker/容器环境完美兼容 ✅最新稳定版
1239
-
1240
- #### 核心功能
1241
-
1242
- **1. 智能MQTT连接机制(解决Docker/容器环境MQTT连接问题)**
1243
- - ✅ **自动fallback**:配置localhost后自动尝试host.docker.internal、172.17.0.1、homeassistant、mosquitto等候选地址
1244
- - ✅ **环境自适应**:自动检测运行环境,选择合适的连接地址
1245
- - ✅ **完美兼容性**:支持本地安装、Docker Desktop、Docker Compose、HA Supervisor、Kubernetes等所有环境
1246
- - ✅ **实时日志**:显示所有候选地址和连接尝试过程,便于诊断问题
1247
- - ✅ **零配置**:只需配置mqtt://localhost:1883,节点自动处理环境差异
1248
-
1249
- **2. 增强的错误提示和诊断**
1250
- - ✅ 详细的连接日志:显示所有尝试的broker地址
1251
- - ✅ 友好的错误提示:提供具体的检查步骤和解决建议
1252
- - ✅ 环境提示:自动识别Docker环境并提供相应建议
1253
- - ✅ 成功日志:显示实际连接成功的地址(fallback地址会特别标注)
219
+ **症状**:HA实体显示不可用,或MQTT错误日志
1254
220
 
1255
- **3. 修复关键问题**
1256
- - ✅ 修复Docker环境中MQTT连接失败的问题(ECONNREFUSED 127.0.0.1:1883)
1257
- - 修复HA Supervisor环境中无法连接core-mosquitto的问题
1258
- - 修复容器网络环境中localhost解析错误的问题
1259
- - ✅ 优化连接超时和重试逻辑,提升连接成功率
1260
-
1261
- #### 技术实现
1262
-
1263
- **智能fallback候选地址生成**:
1264
- ```javascript
1265
- // 根据配置的broker地址自动生成候选列表
1266
- mqtt://localhost:1883 →
1267
- [ 'mqtt://localhost:1883', // 首选配置的地址
1268
- 'mqtt://host.docker.internal:1883', // Docker Desktop (Mac/Windows)
1269
- 'mqtt://172.17.0.1:1883', // Docker默认网关
1270
- 'mqtt://homeassistant:1883', // HA容器名
1271
- 'mqtt://mosquitto:1883' ] // Mosquitto容器名
1272
- ```
1273
-
1274
- **连接尝试和错误处理**:
1275
- - 每个候选地址尝试5秒超时
1276
- - 连接失败自动切换到下一个候选地址
1277
- - 所有地址都失败后,5秒后重试第一个地址
1278
- - 日志限流:错误最多每10分钟输出一次,避免日志过多
1279
-
1280
- #### 环境兼容性
1281
-
1282
- | 运行环境 | 配置地址 | 自动fallback | 测试状态 |
1283
- |---------|---------|-------------|---------|
1284
- | 本地Mac/Linux/Windows | mqtt://localhost:1883 | ✅ → 127.0.0.1 | ✅ 通过 |
1285
- | Docker Desktop (Mac/Win) | mqtt://localhost:1883 | ✅ → host.docker.internal → 172.17.0.1 | ✅ 通过 |
1286
- | Docker Compose | mqtt://localhost:1883 | ✅ → 容器名 → 172.17.0.1 → localhost | ✅ 通过 |
1287
- | HA Supervisor | mqtt://localhost:1883 | ✅ → homeassistant → core-mosquitto | ✅ 通过 |
1288
- | Kubernetes | mqtt://mosquitto:1883 | ✅ → service名 → localhost | ✅ 通过 |
1289
-
1290
- #### 使用示例
1291
-
1292
- **场景1:本地Mac环境**
1293
- ```
1294
- 配置:mqtt://localhost:1883
1295
- 日志:MQTT已连接: mqtt://localhost:1883
1296
- 结果:✅ 直接连接成功
1297
- ```
1298
-
1299
- **场景2:Docker容器中运行Node-RED**
1300
- ```
1301
- 配置:mqtt://localhost:1883
1302
- 日志:
1303
- MQTT broker候选地址: mqtt://localhost:1883, mqtt://host.docker.internal:1883, ...
1304
- 正在连接MQTT broker: mqtt://localhost:1883
1305
- 尝试备用MQTT broker: mqtt://host.docker.internal:1883
1306
- MQTT已连接: mqtt://host.docker.internal:1883
1307
- 使用fallback地址成功: mqtt://host.docker.internal:1883(原配置: mqtt://localhost:1883)
1308
- 结果:✅ 自动fallback成功
1309
- ```
1310
-
1311
- **场景3:HA Supervisor环境**
1312
- ```
1313
- 配置:mqtt://localhost:1883
1314
- 日志:
1315
- MQTT broker候选地址: mqtt://localhost:1883, mqtt://host.docker.internal:1883, mqtt://homeassistant:1883, ...
1316
- 正在连接MQTT broker: mqtt://localhost:1883
1317
- 尝试备用MQTT broker: mqtt://homeassistant:1883
1318
- MQTT已连接: mqtt://homeassistant:1883
1319
- 使用fallback地址成功: mqtt://homeassistant:1883(原配置: mqtt://localhost:1883)
1320
- 结果:✅ 自动连接到HA内置broker
1321
- ```
1322
-
1323
- #### 升级建议
1324
-
1325
- **从v1.5.x升级到v1.6.0**:
1326
- 1. 更新节点:`cd ~/.node-red && npm install node-red-contrib-symi-modbus@latest`
1327
- 2. 重启Node-RED
1328
- 3. 无需修改任何配置,现有流程自动兼容
1329
- 4. 如果之前MQTT连接有问题,升级后会自动修复
1330
-
1331
- **新安装用户**:
1332
- - 直接使用`mqtt://localhost:1883`作为MQTT broker地址
1333
- - 节点会自动适配所有环境
1334
- - 无需手动配置不同环境的地址
1335
-
1336
- #### 已知限制
1337
-
1338
- - 如果所有候选地址都无法连接,需要手动配置实际的broker IP地址
1339
- - 错误日志每10分钟输出一次,避免日志过多(可通过重新部署立即显示)
1340
-
1341
- #### 文档更新
221
+ **解决方案**:
222
+ 1. 检查MQTT broker是否运行:`ps aux | grep mosquitto`
223
+ 2. 启动MQTT broker:`brew services start mosquitto`(macOS)
224
+ 3. 验证MQTT连接:`mosquitto_sub -h localhost -t test`
225
+ 4. 检查Node-RED日志确认连接状态
1342
226
 
1343
- - ✅ 新增MQTT配置最佳实践章节
1344
- - ✅ 新增环境兼容性对照表
1345
- - ✅ 新增常见错误和解决方案
1346
- - ✅ 更新故障排除指南
1347
- - ✅ 添加Docker环境测试步骤
227
+ ### 日志系统
1348
228
 
1349
- ---
229
+ 本节点使用智能日志限流机制:
230
+ - 首次错误立即显示
231
+ - 重复错误10分钟内不再显示
232
+ - 重新部署后清除日志记录
1350
233
 
1351
234
  ## 许可证
1352
235
 
1353
- MIT License - 详见 [LICENSE](LICENSE) 文件
236
+ MIT License
1354
237
 
1355
238
  ## 作者
1356
239
 
@@ -1362,15 +245,5 @@ MIT License - 详见 [LICENSE](LICENSE) 文件
1362
245
  ## 支持
1363
246
 
1364
247
  如有问题或建议:
1365
- - 📧 提交Issue:https://github.com/symi-daguo/node-red-contrib-symi-modbus/issues
1366
- - 📦 NPM包:https://www.npmjs.com/package/node-red-contrib-symi-modbus
1367
- - 👤 NPM作者:https://www.npmjs.com/~symi-daguo
1368
- - 🌐 Node-RED Flow Library:即将提交
1369
-
1370
- ## 致谢
1371
-
1372
- 感谢以下开源项目:
1373
- - [Node-RED](https://nodered.org/) - 流程编程平台
1374
- - [modbus-serial](https://github.com/yaacov/node-modbus-serial) - Modbus通信库
1375
- - [MQTT.js](https://github.com/mqttjs/MQTT.js) - MQTT客户端库
1376
- - Node-RED社区的支持和贡献
248
+ - 提交Issue:https://github.com/symi-daguo/node-red-contrib-symi-modbus/issues
249
+ - NPM包:https://www.npmjs.com/package/node-red-contrib-symi-modbus