node-red-contrib-symi-modbus 1.5.4 → 1.5.6

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
@@ -963,10 +963,70 @@ node-red
963
963
 
964
964
  ### MQTT问题
965
965
 
966
- 1. 确认MQTT Broker地址正确且可访问
967
- 2. 检查用户名密码(如果需要)
968
- 3. 查看Node-RED日志确认MQTT连接状态
969
- 4. 测试MQTT连接:`mosquitto_pub -h localhost -t test -m "hello"`
966
+ **症状**:HA实体显示不可用,或MQTT错误日志
967
+
968
+ **原因分析**:
969
+ 1. MQTT broker未运行(如:mosquitto服务未启动)
970
+ 2. MQTT broker地址配置错误
971
+ 3. MQTT broker需要认证但未配置用户名密码
972
+ 4. 网络连接问题
973
+
974
+ **解决方案**:
975
+
976
+ 1. **检查MQTT broker是否运行**
977
+ ```bash
978
+ # macOS/Linux查看mosquitto服务状态
979
+ ps aux | grep mosquitto
980
+
981
+ # 或使用systemctl(Linux)
982
+ sudo systemctl status mosquitto
983
+
984
+ # macOS使用brew services
985
+ brew services list | grep mosquitto
986
+ ```
987
+
988
+ 2. **启动MQTT broker**
989
+ ```bash
990
+ # macOS
991
+ brew services start mosquitto
992
+
993
+ # Linux (systemd)
994
+ sudo systemctl start mosquitto
995
+
996
+ # 或直接运行
997
+ mosquitto -v
998
+ ```
999
+
1000
+ 3. **验证MQTT连接**
1001
+ ```bash
1002
+ # 订阅测试主题(打开一个终端)
1003
+ mosquitto_sub -h localhost -t test
1004
+
1005
+ # 发布测试消息(打开另一个终端)
1006
+ mosquitto_pub -h localhost -t test -m "hello"
1007
+
1008
+ # 如果收到消息,说明MQTT broker正常运行
1009
+ ```
1010
+
1011
+ 4. **检查Node-RED日志**
1012
+ - 查看是否有"正在连接MQTT broker: xxx"日志
1013
+ - 查看MQTT错误提示,根据提示信息定位问题
1014
+ - 如果提示"无法连接到MQTT broker",检查broker是否运行
1015
+ - 如果提示"MQTT已启用但broker地址未配置",在MQTT服务器配置节点中填写broker地址
1016
+
1017
+ 5. **正确配置MQTT服务器节点**
1018
+ - 在Node-RED中打开任意主站或从站节点
1019
+ - 找到"MQTT服务器"字段,点击编辑按钮
1020
+ - 填写正确的broker地址(如:`mqtt://localhost:1883`或`mqtt://192.168.1.100:1883`)
1021
+ - 如果需要认证,填写用户名和密码
1022
+ - 点击"添加"保存配置
1023
+ - 重新部署流程
1024
+
1025
+ 6. **HA实体不可用的特殊情况**
1026
+ - 如果HA中实体显示不可用(unavailable),首先确保MQTT连接正常
1027
+ - 然后确保主站节点已启动轮询(查看日志:"开始轮询 X 个从站设备")
1028
+ - 如果轮询成功,实体应该在几秒内变为可用状态
1029
+ - v1.5.5+版本已修复初始状态发布问题,确保使用最新版本
970
1030
 
971
1031
  ### 测试设备
972
1032
 
@@ -1003,144 +1063,37 @@ python -m pymodbus.server tcp --port 502
1003
1063
 
1004
1064
  ## 更新日志
1005
1065
 
1006
- ### v1.5.4 (2025-10-18) - MQTT错误日志优化 ✅最新版本
1007
- - ✅ **MQTT错误日志限流**:
1008
- - MQTT连接错误也采用10分钟限流机制
1009
- - 避免MQTT未配置时频繁输出错误日志(每几秒一次)
1010
- - 与Modbus错误日志统一管理,保持日志整洁
1011
- - 重新部署时清除MQTT错误日志记录,允许再次显示
1012
- - ✅ **日志系统完善**:
1013
- - 所有错误日志都采用10分钟限流机制
1014
- - 提示信息统一:"[此错误将在10分钟后再次显示]"
1015
- - 不影响功能正常运行,只是减少重复日志输出
1016
- - ✅ **默认配置确认**:
1017
- - RS-485串口参数默认9600-8-N-1(符合亖米协议)
1018
- - 面板品牌默认SYMI,支持1-8键开关
1019
- - 所有默认参数都已正确配置并持久化
1066
+ ### v1.5.6 (2025-10-18) - MQTT错误提示优化 ✅最新版本
1067
+ - ✅ **MQTT错误提示改进**:
1068
+ - MQTT连接失败且错误消息为空时,提供友好的默认提示
1069
+ - 明确提示broker地址和可能的原因:"无法连接到MQTT broker: xxx,请检查broker是否运行"
1070
+ - 添加MQTT连接日志:"正在连接MQTT broker: xxx",便于调试
1071
+ - 帮助用户快速定位MQTT配置问题
1072
+ - ✅ **调试信息完善**:
1073
+ - MQTT连接过程增加详细日志输出
1074
+ - 错误提示更加明确和友好
1075
+ - 便于用户排查MQTT连接问题
1076
+
1077
+ ### v1.5.5 (2025-10-18) - HA自动发现修复和初始状态发布
1078
+ - ✅ **修复HA实体不可用问题**:
1079
+ - 添加MQTT broker配置验证,空地址时不尝试连接并给出警告
1080
+ - 第一次轮询成功后立即发布所有线圈的初始状态到MQTT
1081
+ - 确保HA能立即获取到设备的真实状态,实体显示为可用
1082
+ - 解决初始状态为false时不发布导致实体不可用的问题
1083
+ - ✅ **初始状态发布机制**:
1084
+ - 新增initialPublished标志,记录每个从站是否已发布初始状态
1085
+ - 第一次轮询成功后,无论状态值是什么,都发布到MQTT
1086
+ - 后续轮询只在状态改变时发布,减少MQTT消息量
1087
+ - 确保HA自动发现后立即显示正确的设备状态
1088
+ - ✅ **MQTT配置优化**:
1089
+ - 主站和从站都添加broker地址验证
1090
+ - 配置无效时不尝试连接,避免无意义的错误日志
1091
+ - 提供清晰的警告信息,帮助用户配置
1020
1092
  - ✅ **完整测试验证**:
1021
- - 日志限流机制测试通过
1022
- - Node-RED持久稳定运行
1093
+ - 从站轮询正常,HA实体自动创建并显示可用
1094
+ - 初始状态正确同步到HA
1023
1095
  - 配置持久化保存正常
1024
1096
 
1025
- ### v1.5.3 (2025-10-18) - 界面优化和智能日志系统
1026
- - ✅ **串口选择界面优化**:
1027
- - 输入框和下拉框一体化,不再单独占用一行
1028
- - 点击搜索后,下拉框替换输入框显示检测到的串口
1029
- - 选择串口后自动填充并恢复输入框显示
1030
- - 完美支持所有类型串口(COM1、/dev/ttyUSB0、/dev/ttyS1等)
1031
- - ✅ **智能日志限流系统**:
1032
- - Modbus超时错误每10分钟只提示一次,避免日志过多
1033
- - 重新部署时清除日志记录,允许再次显示错误
1034
- - 减少日志输出,防止内存占用过大
1035
- - 保持功能正常,不影响错误监控
1036
- - ✅ **界面布局完善**:
1037
- - 主站节点:Grid布局,从站地址/线圈范围/轮询间隔完美对齐
1038
- - 标签在输入框上方,清晰的垂直布局
1039
- - 移除所有emoji图标,保持专业简洁
1040
- - 渐变配色和阴影效果,现代化视觉
1041
- - ✅ **错误处理优化**:
1042
- - RS-485连接添加配置验证,防止无效配置重试
1043
- - 串口未配置时提供明确提示
1044
- - 配置错误时不重试,避免无用日志
1045
- - ✅ **完整测试验证**:
1046
- - Node-RED v4.0.8 / Node.js v23.1.0测试通过
1047
- - 日志输出优化,10分钟内不重复显示相同错误
1048
- - 界面布局完美,串口选择流畅
1049
-
1050
- ### v1.5.0 (2025-10-18) - 串口搜索和完整测试
1051
- - ✅ **串口自动搜索**:主站和从站节点支持一键搜索本机可用串口
1052
- - 点击"搜索串口"按钮自动检测系统串口
1053
- - 双击列表项自动填入串口名称
1054
- - 显示串口厂商信息,便于识别
1055
- - 兼容serialport v9和v10+
1056
- - ✅ **串口连接修复**:优化串口列表API,使用modbus-serial自带的serialport模块
1057
- - ✅ **代码规范检查**:符合Node-RED开发标准
1058
- - ✅ **完整测试验证**:Node-RED启动正常,节点加载成功
1059
- - ✅ **文档完善**:更新所有配置说明和使用指南
1060
-
1061
- ### v1.4.0 (2025-10-18) - 界面优化和品牌扩展
1062
- - ✅ **品牌选择功能**:从站开关节点增加品牌选择(默认亖米,预留其他品牌扩展)
1063
- - ✅ **界面布局优化**:
1064
- - 主站节点:从站地址/线圈标签紧贴输入框,更清晰的布局
1065
- - 从站节点:所有标签优化对齐,提升配置体验
1066
- - ✅ **全面美化**:
1067
- - 统一间距和对齐方式
1068
- - 优化配置区域分组(颜色、边框、圆角)
1069
- - 改进提示信息样式(蓝色、黄色、绿色主题)
1070
- - 增强按钮视觉效果(悬停、禁用状态)
1071
- - ✅ **代码规范检查**:确保符合Node-RED开发标准
1072
- - ✅ **本地测试验证**:安装测试通过,节点加载正常
1073
-
1074
- ### v1.3.0 (2025-10-17) - 轻量级协议完整实现 ✅已发布到npm
1075
- - ✅ **完整协议实现**:实现轻量级智能家居通信协议(V0.13)
1076
- - ✅ **协议解析**:完整的帧解析、CRC8校验、按键事件检测
1077
- - ✅ **协议构建**:单灯控制、多灯控制、查询指令完整实现
1078
- - ✅ **按键监听**:实时监听RS-485总线上的按键按下事件
1079
- - ✅ **指示灯控制**:通过协议同步控制物理面板指示灯
1080
- - ✅ **完整三向同步**:
1081
- - 物理按键 → RS-485协议 → MQTT命令 → 继电器动作
1082
- - 继电器状态 → MQTT状态 → RS-485协议 → 指示灯同步
1083
- - 远程控制 → MQTT → 继电器 + 指示灯同步
1084
- - ✅ **协议帧格式**:0x7E帧头 + 数据 + CRC8 + 0x7D帧尾
1085
- - ✅ **多种操作类型**:单灯控制(0x00)、多灯控制(0x05)、查询(0x02)
1086
- - ✅ **CRC8校验**:完整的CRC8算法实现,确保数据完整性
1087
- - ✅ **自动应答**:接收到按键事件后自动发送MQTT命令
1088
- - ✅ **状态同步**:MQTT状态变化自动发送RS-485控制指令
1089
- - ✅ **已发布npm**:https://www.npmjs.com/package/node-red-contrib-symi-modbus
1090
- - ✅ **npm安装验证**:从npm安装测试通过
1091
-
1092
- ### v1.2.0 (2025-10-17) - 完整RS-485总线支持
1093
- - ✅ **新增RS-485总线连接**:从站节点支持连接物理开关面板的RS-485总线
1094
- - ✅ **TCP/串口双模式**:支持RS-485转TCP网关或直连串口
1095
- - ✅ **监听按键事件**:实时监听物理面板的按钮按下事件
1096
- - ✅ **控制指示灯**:同步控制物理面板的指示灯状态
1097
- - ✅ **三向同步**:物理面板 ↔ 从站 ↔ MQTT ↔ 主站 ↔ Modbus继电器
1098
- - ✅ **双协议桥接**:RS-485协议 + MQTT协议无缝桥接
1099
- - ✅ **状态显示优化**:显示RS-485和MQTT连接状态
1100
- - ✅ **自动重连**:RS-485和MQTT都支持5秒自动重连
1101
- - ✅ **配置持久化**:所有RS-485配置自动保存
1102
- - ✅ **协议扩展接口**:预留轻量级协议实现接口
1103
-
1104
- ### v1.1.0 (2025-10-17) - 重大可靠性提升
1105
- - ✅ **新增MQTT服务器配置节点**:统一管理MQTT连接信息
1106
- - ✅ **简化配置流程**:主站和从站共享MQTT配置,避免重复输入
1107
- - ✅ **防止配置错误**:确保所有节点使用相同的MQTT服务器和主题
1108
- - ✅ **配置持久化**:MQTT服务器配置自动保存,重启不丢失
1109
- - ✅ **QoS=1消息保证**:所有命令和状态消息使用QoS=1,确保不丢失
1110
- - ✅ **持久化会话**:clean=false,断线重连后继续接收未读消息
1111
- - ✅ **自动重连机制**:MQTT 5秒自动重连,Modbus 5秒自动重连
1112
- - ✅ **完整双向同步**:控制命令和状态反馈双向实时同步
1113
- - ✅ **支持一对多/多对一**:灵活的按钮到继电器映射关系
1114
- - ✅ **大量设备支持**:测试验证100+节点并发无遗漏
1115
- - ✅ **断电断网恢复**:所有配置和状态自动恢复,零数据丢失
1116
- - ✅ **符合Node-RED规范**:使用标准config节点模式,官方开发规范
1117
-
1118
- ### v1.0.1 (2025-10-17)
1119
- - ✅ **重新设计从站开关节点**:支持物理开关面板(RS-485)到Modbus继电器的映射
1120
- - ✅ **开关ID分离**:开关ID(0-255)对应物理面板,不是继电器地址
1121
- - ✅ **完整映射配置**:物理面板(开关ID+按钮)→ 继电器(从站+线圈)
1122
- - ✅ **优化配置界面**:更清晰的配置说明和示例
1123
- - ✅ **本地验证通过**:所有功能测试正常
1124
-
1125
- ### v1.0.0 (2025-10-17)
1126
- - ✅ 初始版本发布
1127
- - ✅ Modbus主站节点(TCP/串口支持)
1128
- - ✅ **动态从站管理**:支持动态添加/删除从站设备(最多10台)
1129
- - ✅ **独立配置**:每个从站独立配置地址、线圈范围、轮询间隔
1130
- - ✅ **容错机制**:单个从站失败不影响其他从站继续轮询
1131
- - ✅ **配置持久化**:所有从站配置自动保存
1132
- - ✅ MQTT集成和Home Assistant MQTT Discovery(完全兼容)
1133
- - ✅ 开关从站节点
1134
- - ✅ 完整文档和示例流程
1135
- - ✅ 优化的错误处理和自动重连机制
1136
- - ✅ 连接断开自动检测和恢复
1137
- - ✅ 完善的资源清理和内存管理
1138
- - ✅ 稳定的唯一ID机制(避免重复实体)
1139
- - ✅ 设备可用性状态管理(online/offline)
1140
- - ✅ MQTT retain消息支持(断电重启不丢失配置)
1141
- - ✅ 智能状态显示(正常设备数/总设备数)
1142
- - ✅ 本地测试验证通过(Node-RED v4.0.8)
1143
-
1144
1097
  ## 许可证
1145
1098
 
1146
1099
  MIT License - 详见 [LICENSE](LICENSE) 文件
@@ -106,7 +106,8 @@ module.exports = function(RED) {
106
106
  coils: new Array(32).fill(false),
107
107
  lastUpdate: null,
108
108
  error: null,
109
- config: slave // 保存该从站的配置
109
+ config: slave, // 保存该从站的配置
110
+ initialPublished: false // 标记是否已发布初始状态
110
111
  };
111
112
  });
112
113
 
@@ -160,6 +161,14 @@ module.exports = function(RED) {
160
161
  return;
161
162
  }
162
163
 
164
+ // 验证MQTT broker配置
165
+ if (!node.config.mqttBroker || node.config.mqttBroker.trim() === '') {
166
+ node.warn('MQTT已启用但broker地址未配置,跳过MQTT连接');
167
+ return;
168
+ }
169
+
170
+ node.log(`正在连接MQTT broker: ${node.config.mqttBroker}`);
171
+
163
172
  const options = {
164
173
  clientId: `modbus_master_${Math.random().toString(16).substr(2, 8)}`,
165
174
  clean: false, // 持久化会话,断线重连后继续接收消息
@@ -190,7 +199,8 @@ module.exports = function(RED) {
190
199
  const shouldLog = (now - node.lastMqttErrorLog) > node.errorLogInterval;
191
200
 
192
201
  if (shouldLog) {
193
- node.error(`MQTT错误: ${err.message} [此错误将在10分钟后再次显示]`);
202
+ const errorMsg = err.message || `无法连接到MQTT broker: ${node.config.mqttBroker},请检查broker是否运行`;
203
+ node.error(`MQTT错误: ${errorMsg} [此错误将在10分钟后再次显示]`);
194
204
  node.lastMqttErrorLog = now;
195
205
  }
196
206
  });
@@ -390,6 +400,8 @@ module.exports = function(RED) {
390
400
  const data = await node.client.readCoils(slave.coilStart, coilCount);
391
401
 
392
402
  // 更新设备状态
403
+ const isFirstPoll = !node.deviceStates[slaveId].initialPublished;
404
+
393
405
  for (let i = 0; i < coilCount; i++) {
394
406
  const coilIndex = slave.coilStart + i;
395
407
  const oldValue = node.deviceStates[slaveId].coils[coilIndex];
@@ -397,8 +409,8 @@ module.exports = function(RED) {
397
409
 
398
410
  node.deviceStates[slaveId].coils[coilIndex] = newValue;
399
411
 
400
- // 如果状态改变,发布到MQTT和触发事件
401
- if (oldValue !== newValue) {
412
+ // 第一次轮询或状态改变时,发布到MQTT和触发事件
413
+ if (isFirstPoll || oldValue !== newValue) {
402
414
  node.publishMqttState(slaveId, coilIndex, newValue);
403
415
  node.emit('stateUpdate', {
404
416
  slave: slaveId,
@@ -410,6 +422,7 @@ module.exports = function(RED) {
410
422
 
411
423
  node.deviceStates[slaveId].lastUpdate = Date.now();
412
424
  node.deviceStates[slaveId].error = null;
425
+ node.deviceStates[slaveId].initialPublished = true; // 标记已发布初始状态
413
426
 
414
427
  // 输出消息
415
428
  const output = {
@@ -294,6 +294,12 @@ module.exports = function(RED) {
294
294
 
295
295
  // 连接MQTT
296
296
  node.connectMqtt = function() {
297
+ // 验证MQTT broker配置
298
+ if (!node.config.mqttBroker || node.config.mqttBroker.trim() === '') {
299
+ node.warn('MQTT broker地址未配置,跳过MQTT连接');
300
+ return;
301
+ }
302
+
297
303
  const options = {
298
304
  clientId: `modbus_switch_${node.id}`,
299
305
  clean: false, // 持久化会话,断线重连后继续接收消息
@@ -329,7 +335,8 @@ module.exports = function(RED) {
329
335
  const shouldLog = (now - node.lastMqttErrorLog) > node.errorLogInterval;
330
336
 
331
337
  if (shouldLog) {
332
- node.error(`MQTT错误: ${err.message} [此错误将在10分钟后再次显示]`);
338
+ const errorMsg = err.message || `无法连接到MQTT broker: ${node.config.mqttBroker},请检查broker是否运行`;
339
+ node.error(`MQTT错误: ${errorMsg} [此错误将在10分钟后再次显示]`);
333
340
  node.lastMqttErrorLog = now;
334
341
  }
335
342
  node.updateStatus();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-symi-modbus",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "Node-RED Modbus节点,支持TCP/串口通信、串口自动搜索(包括/dev/ttyS1等)、多设备轮询、智能日志限流、MQTT集成、Home Assistant自动发现和多品牌开关面板,现代化美观配置界面",
5
5
  "main": "nodes/modbus-master.js",
6
6
  "scripts": {