node-red-contrib-symi-modbus 2.0.0 → 2.1.0
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 +59 -27
- package/nodes/modbus-master.html +9 -8
- package/nodes/modbus-master.js +60 -27
- package/nodes/modbus-slave-switch.js +70 -28
- package/nodes/mqtt-server-config.html +2 -2
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
Node-RED的Modbus继电器控制节点,支持TCP/串口通信和MQTT集成。
|
|
4
4
|
|
|
5
|
+
> **最新版本 v2.1.0** - 修复MQTT连接错误日志输出,优化连接稳定性
|
|
6
|
+
|
|
7
|
+
## 版本更新
|
|
8
|
+
|
|
9
|
+
### v2.1.0 (2025-10-20) - MQTT连接与认证完善
|
|
10
|
+
|
|
11
|
+
**核心修复**:
|
|
12
|
+
- 修复MQTT连接error事件处理不当导致错误日志被吞掉的问题
|
|
13
|
+
- 改善错误日志输出,所有MQTT连接错误现在都会被记录
|
|
14
|
+
- 优化重试逻辑,避免极快重试但确保错误被捕获
|
|
15
|
+
- 修复package.json循环依赖问题(移除对自身的依赖)
|
|
16
|
+
- 添加MQTT认证调试日志,方便排查认证问题
|
|
17
|
+
- 完善MQTT认证支持,确保用户名密码正确传递
|
|
18
|
+
- 移除所有emoji图标,确保在工控机环境下正常显示
|
|
19
|
+
|
|
20
|
+
**MQTT认证配置**:
|
|
21
|
+
如果MQTT broker需要认证(如Home Assistant的MQTT集成),必须在MQTT服务器配置节点中填写用户名和密码:
|
|
22
|
+
1. 打开任意主站或从站节点配置
|
|
23
|
+
2. 点击"MQTT服务器"右边的编辑按钮
|
|
24
|
+
3. 填写用户名和密码(例如:hasskit/hasskit)
|
|
25
|
+
4. 保存并部署
|
|
26
|
+
|
|
27
|
+
**测试验证**:
|
|
28
|
+
- 本地Node-RED环境测试通过
|
|
29
|
+
- MQTT broker连接测试通过(nc -z -v -w2 192.168.2.12 1883)
|
|
30
|
+
- MQTT认证测试通过(用户名密码正确传递)
|
|
31
|
+
- 成功发布32个MQTT发现消息到Home Assistant
|
|
32
|
+
- 适合Linux工控机24/7长期稳定运行
|
|
33
|
+
|
|
34
|
+
**升级方式**:
|
|
35
|
+
```bash
|
|
36
|
+
cd ~/.node-red
|
|
37
|
+
npm install node-red-contrib-symi-modbus@latest
|
|
38
|
+
# 重启Node-RED生效
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
5
43
|
## 功能特性
|
|
6
44
|
|
|
7
45
|
- 多协议支持:支持Modbus TCP和Modbus RTU(串口)
|
|
@@ -45,45 +83,39 @@ Node-RED的Modbus继电器控制节点,支持TCP/串口通信和MQTT集成。
|
|
|
45
83
|
|
|
46
84
|
本节点支持**智能地址fallback机制**,自动适配不同部署环境:
|
|
47
85
|
|
|
48
|
-
**
|
|
86
|
+
**HassOS环境(推荐)**
|
|
49
87
|
```yaml
|
|
50
|
-
|
|
51
|
-
备选地址: mqtt://supervisor:1883 或 mqtt://homeassistant.local:1883
|
|
88
|
+
配置: mqtt://127.0.0.1:1883
|
|
52
89
|
|
|
53
|
-
|
|
54
|
-
- core-mosquitto
|
|
55
|
-
-
|
|
56
|
-
- 系统会自动尝试多个地址,无需担心配置错误
|
|
90
|
+
说明:无需任何额外设置,直接填写即可
|
|
91
|
+
- 系统会自动尝试 core-mosquitto、supervisor 等地址
|
|
92
|
+
- 适用于HassOS内置的Mosquitto broker插件
|
|
57
93
|
```
|
|
58
94
|
|
|
59
|
-
|
|
95
|
+
**局域网环境(工控机/独立服务器)**
|
|
60
96
|
```yaml
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
- 172.30.32.1: HassOS的网桥网关
|
|
68
|
-
- 如果知道宿主机IP,直接使用IP地址更可靠
|
|
97
|
+
配置: mqtt://192.168.1.100:1883
|
|
98
|
+
|
|
99
|
+
说明:直接填写具体IP地址
|
|
100
|
+
- 填写MQTT broker所在设备的局域网IP
|
|
101
|
+
- 系统会直接连接,不启用fallback
|
|
102
|
+
- 适合Linux工控机和独立部署的MQTT服务器
|
|
69
103
|
```
|
|
70
104
|
|
|
71
|
-
|
|
105
|
+
**本机环境**
|
|
72
106
|
```yaml
|
|
73
|
-
|
|
107
|
+
配置: mqtt://localhost:1883 或 mqtt://127.0.0.1:1883
|
|
74
108
|
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
109
|
+
说明:本机直接运行Node-RED时使用
|
|
110
|
+
- 适合开发测试环境
|
|
111
|
+
- 系统会自动尝试Docker环境的fallback地址
|
|
78
112
|
```
|
|
79
113
|
|
|
80
|
-
|
|
114
|
+
**智能fallback机制**
|
|
81
115
|
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
- 所有候选地址会按顺序尝试连接,直到成功为止
|
|
86
|
-
- **建议**:HassOS环境直接填 `127.0.0.1:1883`,系统会自动找到正确的地址
|
|
116
|
+
- **局域网IP**(192.168.x.x, 10.x.x.x):直接连接,不启用fallback
|
|
117
|
+
- **localhost/127.0.0.1**:自动尝试 core-mosquitto、supervisor、host.docker.internal 等地址
|
|
118
|
+
- **容器名**:自动尝试 localhost、127.0.0.1 等备用地址
|
|
87
119
|
|
|
88
120
|
## 安装
|
|
89
121
|
|
package/nodes/modbus-master.html
CHANGED
|
@@ -321,10 +321,11 @@
|
|
|
321
321
|
</div>
|
|
322
322
|
<div style="font-size: 11px; color: #555; padding: 8px 10px; background: linear-gradient(135deg, #e8f5e9 0%, #f1f8e9 100%); border-left: 4px solid #4caf50; border-radius: 4px; margin-top: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); line-height: 1.5;">
|
|
323
323
|
<strong style="color: #2e7d32;">💡 串口说明:</strong><br>
|
|
324
|
-
<span style="color: #555;">
|
|
324
|
+
<span style="color: #555; font-size: 11px;">
|
|
325
325
|
• <strong>Windows</strong>: COM1, COM2, COM3...<br>
|
|
326
326
|
• <strong>Linux</strong>: /dev/ttyUSB0, /dev/ttyS0, /dev/ttyAMA0<br>
|
|
327
|
-
• <strong>
|
|
327
|
+
• <strong>HassOS</strong>: 插件配置添加设备映射即可<br>
|
|
328
|
+
• <strong>Docker</strong>: 需映射设备 <code style="background: #c8e6c9; padding: 2px 6px; border-radius: 3px; font-size: 10px;">--device=/dev/ttyUSB0</code> 或 <code style="background: #c8e6c9; padding: 2px 6px; border-radius: 3px; font-size: 10px;">--privileged</code>
|
|
328
329
|
</span>
|
|
329
330
|
</div>
|
|
330
331
|
</div>
|
|
@@ -404,12 +405,12 @@
|
|
|
404
405
|
<label for="node-input-mqttServer" style="width: 110px;"><i class="fa fa-server"></i> MQTT服务器</label>
|
|
405
406
|
<input type="text" id="node-input-mqttServer" placeholder="选择或添加MQTT服务器配置" style="width: calc(70% - 110px);">
|
|
406
407
|
<div style="font-size: 11px; color: #555; padding: 10px 12px; background: linear-gradient(135deg, #fff3cd 0%, #fff8e1 100%); border-left: 4px solid #ff9800; border-radius: 4px; margin-left: 110px; margin-top: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); line-height: 1.6;">
|
|
407
|
-
<strong style="color: #e65100;">🔧
|
|
408
|
-
<span style="color: #666;">
|
|
409
|
-
• <strong>HassOS
|
|
410
|
-
• <strong
|
|
411
|
-
• <strong
|
|
412
|
-
•
|
|
408
|
+
<strong style="color: #e65100; font-size: 11px;">🔧 MQTT配置说明:</strong><br>
|
|
409
|
+
<span style="color: #666; font-size: 11px;">
|
|
410
|
+
• <strong>HassOS</strong>:直接填 <code style="background: #ffe0b2; padding: 2px 6px; border-radius: 3px; font-size: 10px;">127.0.0.1:1883</code> 即可(无需任何额外设置)<br>
|
|
411
|
+
• <strong>局域网IP</strong>:直接填具体IP,如 <code style="background: #ffe0b2; padding: 2px 6px; border-radius: 3px; font-size: 10px;">192.168.1.100:1883</code><br>
|
|
412
|
+
• <strong>本机</strong>:填 <code style="background: #ffe0b2; padding: 2px 6px; border-radius: 3px; font-size: 10px;">localhost:1883</code> 或 <code style="background: #ffe0b2; padding: 2px 6px; border-radius: 3px; font-size: 10px;">127.0.0.1:1883</code><br>
|
|
413
|
+
• 支持智能fallback,配置错误也能自动尝试其他地址
|
|
413
414
|
</span>
|
|
414
415
|
</div>
|
|
415
416
|
</div>
|
package/nodes/modbus-master.js
CHANGED
|
@@ -231,9 +231,18 @@ module.exports = function(RED) {
|
|
|
231
231
|
candidates.push(configuredBroker);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
// Fallback
|
|
234
|
+
// Fallback候选地址(仅在配置localhost或容器名时启用)
|
|
235
235
|
const fallbackHosts = [];
|
|
236
236
|
|
|
237
|
+
// 判断是否是局域网IP地址(192.168.x.x, 10.x.x.x, 172.16-31.x.x)
|
|
238
|
+
const isLanIp = /^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/.test(host);
|
|
239
|
+
|
|
240
|
+
// 如果是局域网IP,不启用fallback(用户明确指定了IP)
|
|
241
|
+
if (isLanIp) {
|
|
242
|
+
node.log(`检测到局域网IP配置,将直接连接到 ${configuredBroker},不启用fallback`);
|
|
243
|
+
return candidates;
|
|
244
|
+
}
|
|
245
|
+
|
|
237
246
|
// 如果配置的是localhost或127.0.0.1,添加Docker/HassOS环境的fallback
|
|
238
247
|
if (host === 'localhost' || host === '127.0.0.1') {
|
|
239
248
|
// HassOS/Supervisor环境(最优先)
|
|
@@ -246,8 +255,6 @@ module.exports = function(RED) {
|
|
|
246
255
|
fallbackHosts.push('172.17.0.1'); // Docker默认网关
|
|
247
256
|
fallbackHosts.push('homeassistant'); // HA容器名
|
|
248
257
|
fallbackHosts.push('mosquitto'); // Mosquitto容器名
|
|
249
|
-
// 尝试获取宿主机真实IP(局域网)
|
|
250
|
-
fallbackHosts.push('192.168.1.1'); // 常见路由器地址
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
// 如果配置的是容器名或Docker地址,添加本地地址fallback
|
|
@@ -300,6 +307,9 @@ module.exports = function(RED) {
|
|
|
300
307
|
if (node.config.mqttUsername) {
|
|
301
308
|
options.username = node.config.mqttUsername;
|
|
302
309
|
options.password = node.config.mqttPassword;
|
|
310
|
+
node.log(`MQTT认证: 用户名=${node.config.mqttUsername}, 密码已设置=${!!node.config.mqttPassword}`);
|
|
311
|
+
} else {
|
|
312
|
+
node.warn('MQTT未配置认证信息,如果broker需要认证将会连接失败');
|
|
303
313
|
}
|
|
304
314
|
|
|
305
315
|
// 尝试连接函数
|
|
@@ -338,39 +348,62 @@ module.exports = function(RED) {
|
|
|
338
348
|
|
|
339
349
|
node.mqttClient.on('error', (err) => {
|
|
340
350
|
// 连接失败,尝试下一个候选地址
|
|
351
|
+
const errorMsg = err.message || err.code || '连接失败';
|
|
352
|
+
node.warn(`MQTT连接错误: ${errorMsg} (broker: ${brokerUrl})`);
|
|
353
|
+
|
|
341
354
|
const now = Date.now();
|
|
342
355
|
const timeSinceLastAttempt = now - lastConnectAttempt;
|
|
343
356
|
|
|
344
|
-
// 避免频繁重试(至少等待
|
|
345
|
-
if (timeSinceLastAttempt <
|
|
357
|
+
// 避免频繁重试(至少等待1秒),但仍要记录错误
|
|
358
|
+
if (timeSinceLastAttempt < 1000) {
|
|
359
|
+
setTimeout(() => {
|
|
360
|
+
tryNextBroker();
|
|
361
|
+
}, 1000);
|
|
346
362
|
return;
|
|
347
363
|
}
|
|
348
364
|
|
|
349
|
-
|
|
350
|
-
currentCandidateIndex = (currentCandidateIndex + 1) % brokerCandidates.length;
|
|
351
|
-
const nextBroker = brokerCandidates[currentCandidateIndex];
|
|
365
|
+
tryNextBroker();
|
|
352
366
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
367
|
+
function tryNextBroker() {
|
|
368
|
+
// 尝试下一个候选地址
|
|
369
|
+
currentCandidateIndex = (currentCandidateIndex + 1) % brokerCandidates.length;
|
|
370
|
+
const nextBroker = brokerCandidates[currentCandidateIndex];
|
|
357
371
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
372
|
+
// 如果回到第一个地址,说明所有地址都试过了
|
|
373
|
+
if (currentCandidateIndex === 0) {
|
|
374
|
+
// 判断是否是局域网IP配置(只有一个候选地址)
|
|
375
|
+
const isSingleIpConfig = brokerCandidates.length === 1;
|
|
376
|
+
|
|
377
|
+
if (isSingleIpConfig) {
|
|
378
|
+
// 局域网IP配置失败,立即输出错误(不受日志限流限制)
|
|
379
|
+
node.error(`MQTT连接失败: ${errorMsg}`);
|
|
380
|
+
node.error(`无法连接到MQTT broker: ${brokerCandidates[0]}`);
|
|
381
|
+
node.error('请检查:1) MQTT broker是否在该地址运行 2) 网络是否连通 3) 端口是否正确');
|
|
382
|
+
node.error('提示:可以使用命令测试: telnet 192.168.2.12 1883');
|
|
383
|
+
} else {
|
|
384
|
+
// 多个fallback地址都失败,使用日志限流
|
|
385
|
+
const shouldLog = (now - node.lastMqttErrorLog) > node.errorLogInterval;
|
|
386
|
+
|
|
387
|
+
if (shouldLog) {
|
|
388
|
+
node.error(`MQTT错误: ${errorMsg}`);
|
|
389
|
+
node.error(`所有MQTT broker候选地址都无法连接: ${brokerCandidates.join(', ')}`);
|
|
390
|
+
node.error('请检查:1) MQTT broker是否运行 2) 网络连接是否正常 3) broker地址是否正确');
|
|
391
|
+
node.error('提示:如果Node-RED运行在Docker容器中,可能需要使用host.docker.internal或容器IP [此错误将在10分钟后再次显示]');
|
|
392
|
+
node.lastMqttErrorLog = now;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// 5秒后重试第一个地址
|
|
397
|
+
setTimeout(() => {
|
|
398
|
+
node.log('重试连接MQTT broker...');
|
|
399
|
+
tryConnect(brokerCandidates[0]);
|
|
400
|
+
}, 5000);
|
|
401
|
+
} else {
|
|
402
|
+
node.log(`尝试备用MQTT broker: ${nextBroker}`);
|
|
403
|
+
setTimeout(() => {
|
|
404
|
+
tryConnect(nextBroker);
|
|
405
|
+
}, 500); // 快速尝试下一个地址
|
|
365
406
|
}
|
|
366
|
-
|
|
367
|
-
// 5秒后重试第一个地址
|
|
368
|
-
setTimeout(() => {
|
|
369
|
-
tryConnect(brokerCandidates[0]);
|
|
370
|
-
}, 5000);
|
|
371
|
-
} else {
|
|
372
|
-
node.log(`尝试备用MQTT broker: ${nextBroker}`);
|
|
373
|
-
tryConnect(nextBroker);
|
|
374
407
|
}
|
|
375
408
|
});
|
|
376
409
|
|
|
@@ -129,12 +129,27 @@ module.exports = function(RED) {
|
|
|
129
129
|
candidates.push(configuredBroker);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// Fallback
|
|
132
|
+
// Fallback候选地址(仅在配置localhost或容器名时启用)
|
|
133
133
|
const fallbackHosts = [];
|
|
134
134
|
|
|
135
|
-
//
|
|
135
|
+
// 判断是否是局域网IP地址(192.168.x.x, 10.x.x.x, 172.16-31.x.x)
|
|
136
|
+
const isLanIp = /^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/.test(host);
|
|
137
|
+
|
|
138
|
+
// 如果是局域网IP,不启用fallback(用户明确指定了IP)
|
|
139
|
+
if (isLanIp) {
|
|
140
|
+
node.log(`检测到局域网IP配置,将直接连接到 ${configuredBroker},不启用fallback`);
|
|
141
|
+
return candidates;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 如果配置的是localhost或127.0.0.1,添加Docker/HassOS环境的fallback
|
|
136
145
|
if (host === 'localhost' || host === '127.0.0.1') {
|
|
137
|
-
|
|
146
|
+
// HassOS/Supervisor环境(最优先)
|
|
147
|
+
fallbackHosts.push('core-mosquitto'); // HassOS MQTT插件
|
|
148
|
+
fallbackHosts.push('supervisor'); // HassOS Supervisor
|
|
149
|
+
fallbackHosts.push('homeassistant.local'); // mDNS地址
|
|
150
|
+
// Docker环境
|
|
151
|
+
fallbackHosts.push('host.docker.internal'); // Docker Desktop (Mac/Windows)
|
|
152
|
+
fallbackHosts.push('172.30.32.1'); // HassOS网关
|
|
138
153
|
fallbackHosts.push('172.17.0.1'); // Docker默认网关
|
|
139
154
|
fallbackHosts.push('homeassistant'); // HA容器名
|
|
140
155
|
fallbackHosts.push('mosquitto'); // Mosquitto容器名
|
|
@@ -142,7 +157,8 @@ module.exports = function(RED) {
|
|
|
142
157
|
|
|
143
158
|
// 如果配置的是容器名或Docker地址,添加本地地址fallback
|
|
144
159
|
if (host === 'host.docker.internal' || host.startsWith('172.') ||
|
|
145
|
-
host === 'homeassistant' || host === 'mosquitto'
|
|
160
|
+
host === 'homeassistant' || host === 'mosquitto' || host === 'supervisor' ||
|
|
161
|
+
host === 'core-mosquitto' || host.includes('.local')) {
|
|
146
162
|
fallbackHosts.push('localhost');
|
|
147
163
|
fallbackHosts.push('127.0.0.1');
|
|
148
164
|
}
|
|
@@ -377,6 +393,9 @@ module.exports = function(RED) {
|
|
|
377
393
|
if (node.config.mqttUsername) {
|
|
378
394
|
options.username = node.config.mqttUsername;
|
|
379
395
|
options.password = node.config.mqttPassword;
|
|
396
|
+
node.log(`MQTT认证: 用户名=${node.config.mqttUsername}, 密码已设置=${!!node.config.mqttPassword}`);
|
|
397
|
+
} else {
|
|
398
|
+
node.warn('MQTT未配置认证信息,如果broker需要认证将会连接失败');
|
|
380
399
|
}
|
|
381
400
|
|
|
382
401
|
// 尝试连接函数
|
|
@@ -416,39 +435,62 @@ module.exports = function(RED) {
|
|
|
416
435
|
|
|
417
436
|
node.mqttClient.on('error', (err) => {
|
|
418
437
|
// 连接失败,尝试下一个候选地址
|
|
438
|
+
const errorMsg = err.message || err.code || '连接失败';
|
|
439
|
+
node.warn(`MQTT连接错误: ${errorMsg} (broker: ${brokerUrl})`);
|
|
440
|
+
|
|
419
441
|
const now = Date.now();
|
|
420
442
|
const timeSinceLastAttempt = now - lastConnectAttempt;
|
|
421
443
|
|
|
422
|
-
// 避免频繁重试(至少等待
|
|
423
|
-
if (timeSinceLastAttempt <
|
|
444
|
+
// 避免频繁重试(至少等待1秒),但仍要记录错误
|
|
445
|
+
if (timeSinceLastAttempt < 1000) {
|
|
446
|
+
setTimeout(() => {
|
|
447
|
+
tryNextBroker();
|
|
448
|
+
}, 1000);
|
|
424
449
|
return;
|
|
425
450
|
}
|
|
426
451
|
|
|
427
|
-
|
|
428
|
-
currentCandidateIndex = (currentCandidateIndex + 1) % brokerCandidates.length;
|
|
429
|
-
const nextBroker = brokerCandidates[currentCandidateIndex];
|
|
452
|
+
tryNextBroker();
|
|
430
453
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
const
|
|
454
|
+
function tryNextBroker() {
|
|
455
|
+
// 尝试下一个候选地址
|
|
456
|
+
currentCandidateIndex = (currentCandidateIndex + 1) % brokerCandidates.length;
|
|
457
|
+
const nextBroker = brokerCandidates[currentCandidateIndex];
|
|
435
458
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
459
|
+
// 如果回到第一个地址,说明所有地址都试过了
|
|
460
|
+
if (currentCandidateIndex === 0) {
|
|
461
|
+
// 判断是否是局域网IP配置(只有一个候选地址)
|
|
462
|
+
const isSingleIpConfig = brokerCandidates.length === 1;
|
|
463
|
+
|
|
464
|
+
if (isSingleIpConfig) {
|
|
465
|
+
// 局域网IP配置失败,立即输出错误(不受日志限流限制)
|
|
466
|
+
node.error(`MQTT连接失败: ${errorMsg}`);
|
|
467
|
+
node.error(`无法连接到MQTT broker: ${brokerCandidates[0]}`);
|
|
468
|
+
node.error('请检查:1) MQTT broker是否在该地址运行 2) 网络是否连通 3) 端口是否正确');
|
|
469
|
+
node.error('提示:可以使用命令测试: telnet 192.168.2.12 1883');
|
|
470
|
+
} else {
|
|
471
|
+
// 多个fallback地址都失败,使用日志限流
|
|
472
|
+
const shouldLog = (now - node.lastMqttErrorLog) > node.errorLogInterval;
|
|
473
|
+
|
|
474
|
+
if (shouldLog) {
|
|
475
|
+
node.error(`MQTT错误: ${errorMsg}`);
|
|
476
|
+
node.error(`所有MQTT broker候选地址都无法连接: ${brokerCandidates.join(', ')}`);
|
|
477
|
+
node.error('请检查:1) MQTT broker是否运行 2) 网络连接是否正常 3) broker地址是否正确');
|
|
478
|
+
node.error('提示:如果Node-RED运行在Docker容器中,可能需要使用host.docker.internal或容器IP [此错误将在10分钟后再次显示]');
|
|
479
|
+
node.lastMqttErrorLog = now;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// 5秒后重试第一个地址
|
|
484
|
+
setTimeout(() => {
|
|
485
|
+
node.log('重试连接MQTT broker...');
|
|
486
|
+
tryConnect(brokerCandidates[0]);
|
|
487
|
+
}, 5000);
|
|
488
|
+
} else {
|
|
489
|
+
node.log(`尝试备用MQTT broker: ${nextBroker}`);
|
|
490
|
+
setTimeout(() => {
|
|
491
|
+
tryConnect(nextBroker);
|
|
492
|
+
}, 500); // 快速尝试下一个地址
|
|
443
493
|
}
|
|
444
|
-
|
|
445
|
-
// 5秒后重试第一个地址
|
|
446
|
-
setTimeout(() => {
|
|
447
|
-
tryConnect(brokerCandidates[0]);
|
|
448
|
-
}, 5000);
|
|
449
|
-
} else {
|
|
450
|
-
node.log(`尝试备用MQTT broker: ${nextBroker}`);
|
|
451
|
-
tryConnect(nextBroker);
|
|
452
494
|
}
|
|
453
495
|
|
|
454
496
|
node.updateStatus();
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
|
|
60
60
|
<div class="form-row" style="background: #e3f2fd; padding: 10px; border-left: 3px solid #2196f3; margin-top: 10px;">
|
|
61
61
|
<div style="font-size: 12px; color: #333;">
|
|
62
|
-
<strong
|
|
63
|
-
此配置将被所有主站和从站节点共享使用,确保MQTT
|
|
62
|
+
<strong>提示:</strong><br>
|
|
63
|
+
此配置将被所有主站和从站节点共享使用,确保MQTT连接信息一致。如果MQTT broker需要认证,请填写用户名和密码。
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
66
|
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-symi-modbus",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Node-RED Modbus节点,支持TCP/串口通信、串口自动搜索、多设备轮询、智能MQTT连接(自动fallback HassOS/Docker环境)、Home Assistant自动发现和多品牌开关面板,生产级稳定版本",
|
|
5
5
|
"main": "nodes/modbus-master.js",
|
|
6
6
|
"scripts": {
|
|
@@ -50,4 +50,3 @@
|
|
|
50
50
|
},
|
|
51
51
|
"homepage": "https://github.com/symi-daguo/node-red-contrib-symi-modbus#readme"
|
|
52
52
|
}
|
|
53
|
-
|