Node-RED 实现设备状态优先级与通讯中断判定

丁丁智造 · 2026-08-03
Node-RED 实现设备状态优先级与通讯中断判定
导读:一台设备同时有运行、待机、报警、故障、离线等状态,界面到底显示哪个?本文用 Node-RED 实现状态优先级计算和通讯中断自动判定。

问题:多个状态同时存在显示哪个

设备可能“有报警但还在运行”,也可能“故障且通讯中断”。如果直接显示最后收到的状态,界面会乱跳。正确做法是定义状态优先级,永远显示当前最严重/最该关注的状态。

定义优先级(数字越大越优先)

离线/通讯中断 = 5(最高,数据已不可信)
故障         = 4
报警         = 3
待机         = 2
运行         = 1

离线优先级最高,是因为通讯断了之后其他状态都是过期数据,必须先提示“数据不可信”。

Node-RED 实现思路

  1. 各状态位通过不同 MQTT 主题/消息进入
  2. 用 function 节点维护每台设备的上下文(context)状态对象
  3. 每来一个状态,更新对应位,再按优先级规则计算“最终显示状态”
  4. 输出统一的汇总状态给看板/数据库

function 节点核心逻辑:

const s = context.get('state') || {};
Object.assign(s, msg.payload);           // 更新对应状态位
let final = 'run';
if (s.offline) final = 'offline';
else if (s.fault) final = 'fault';
else if (s.alarm) final = 'alarm';
else if (s.standby) final = 'standby';
context.set('state', s);
return { payload: { device: s.device, state: final } };

通讯中断怎么自动判定

不能只靠设备主动发“我离线了”——真断了它根本发不出来。要靠超时判定

  • 每收到一次数据,记录最后通讯时间戳
  • 用定时节点(每 5~10 秒)检查:当前时间 - 最后时间 > 阈值(如 15 秒),则置 offline=true
  • 收到新数据时自动清除 offline

这就是“心跳超时”机制,是判断设备在线与否的可靠方法。

状态防抖

报警位可能在临界点快速跳变,建议:

  • 连续 N 次为真才确认报警
  • 连续 M 次为假才解除
  • 避免状态灯频繁闪烁和误报

输出与落地

计算出的最终状态一路写时序库(便于统计故障时长),一路推看板实时显示,一路在故障/离线时触发告警。把这套逻辑做成可复用的子流程(subflow),多台设备直接复制改设备号即可。