示例集
如果您想导入完整的流并直接运行,请先查看 导入示例流 —— 由于 Node-RED 交付时为该空白画布,示例需从文档中导入。
以下示例是现场实际经常构建的模式。所有示例只需像 Hello World 一样,通过拖动/连接/Deploy 节点即可运行。代码块是需要直接粘贴到 function 节点中的 JavaScript。
1. 阈值报警 (Threshold Alert)
目标: 当温度标签 ≥ 80℃ 时,通过 Slack 发送通知。
inject (5s) ─▶ 태그값 읽기 (TAG_TEMPERATURE) ─▶ function (임계값 체크) ─▶ switch ─▶ slack out
function:
const v = parseFloat(msg.payload.value);
msg.over = (v >= 80);
msg.temp = v;
return msg;
switch: 条件 msg.over is true → 通过。
slack out (或 email/telegram) 的消息中包含 🔥 온도 경보 ${msg.temp}℃。
为了防止在阈值附近产生抖动(80↔80.1),建议仅在上升时点发送报警,并在消除后再次上升时才再次发送。请使用 flow.set('lastAlert', true) 记录状态,仅在切换时点触发。
2. 汇总多个标签并写入新标签 (计算值)
目标: TAG_LINE1_QTY + TAG_LINE2_QTY + TAG_LINE3_QTY → 每 1 秒更新至 TAG_PLANT_TOTAL_QTY。
inject (1s) ─▶ 태그값 읽기 ×3 (병렬) ─▶ join ─▶ function (sum) ─▶ 태그값 쓰기
join: mode manual, combine array, key msg.topic, count 3.
在每个 读取标签值 的输出端连接 change 节点,通过 msg.topic 分别赋予 line1/line2/line3。
function:
const sum = msg.payload.reduce(
(a, p) => a + (parseFloat(p.value) || 0), 0);
return { tag_id: 'TAG_PLANT_TOTAL_QTY', payload: String(sum) };
PlantPulse 本身具有计算公式标签功能。简单四则运算在其中处理速度更快且更稳定。Node-RED 在涉及外部 API/MQTT/时间条件/条件分支混合时更为强大。
3. CSV 日志记录 (分钟级)
目标: 每 1 分钟将 5 个主要标签的值作为 CSV 一行记录在本地磁盘。
inject (1m) ─▶ 태그값 읽기 ×5 ─▶ join ─▶ function (CSV 한 줄) ─▶ file (append)
function:
const ts = new Date().toISOString();
const cols = msg.payload.map(p => (p.value || '').replace(/,/g, ''));
msg.payload = [ts, ...cols].join(',') + '\n';
msg.filename = '/data1/pp-data/node-red/log/tags-' + ts.slice(0, 10) + '.csv';
return msg;
file 节点: Action append to file, Add newline off.
Node-RED userDir 为 /data1/pp-data/node-red。将 CSV 存放在该目录下,即可包含在网关备份策略中。
4. 通过 MQTT 向外部 SCADA 实时发布
(详细设置请参考 MQTT)。快速单行模式:
inject (1s) ─▶ 태그값 읽기 ─▶ change (topic=plant/${tag_id}/value) ─▶ mqtt out
5. 将外部 REST API 的值导入为标签 (反向集成)
目标: 每 5 分钟将外部天气 API 的室外温度 → 记录至虚拟标签 TAG_OUTDOOR_TEMP。
inject (5m) ─▶ http request (GET https://api.example.com/weather?...) ─▶ function ─▶ 태그값 쓰기
function:
return { tag_id: 'TAG_OUTDOOR_TEMP', payload: String(msg.payload.main.temp) };
该值在所有 PlantPulse 画面 / 图表 / 外部 SCADA 中均可像普通标签一样使用。
6. 工作开始时的日报邮件
目标: 每天早上 7 点,将前一日 24 小时的平均/最大/最小值为通过邮件发送。
inject (cron: 0 7 * * *) ─▶ http request (GET /ui/opcua/history?...) ─▶ function (집계) ─▶ email
function:
const points = msg.payload.points || [];
const vs = points.map(p => parseFloat(p.value)).filter(v => !isNaN(v));
const avg = vs.reduce((a,b)=>a+b,0) / vs.length;
msg.topic = '[일일 리포트] 어제의 ' + msg.payload.tag_id;
msg.payload = '평균: ' + avg.toFixed(2)
+ '\n최대: ' + Math.max(...vs)
+ '\n최소: ' + Math.min(...vs);
return msg;
7. 报警发生时 Slack + DB 同时分支
inject (1s) ─▶ 태그값 읽기 ─▶ switch (정상/비정상) ─▶┬─▶ slack out
└─▶ http request (POST /alerts)
异常分支末端的两个节点 (slack out, http request) 将同时接收相同的消息。
8. 单位/量程转换 (4-20mA → bar)
inject (1s) ─▶ 태그값 읽기 (TAG_RAW_MA) ─▶ function (스케일) ─▶ 태그값 쓰기 (TAG_PRESSURE_BAR)
function:
const raw = parseFloat(msg.payload.value);
const ma = (raw / 32767) * 20;
const bar = Math.max(0, ((ma - 4) / (20 - 4)) * 100);
return { tag_id: 'TAG_PRESSURE_BAR', payload: bar.toFixed(2) };
9. 网关自身健康检查 → Telegram
直接轮询 OPC UA 服务器(/ui/opcua) 中可见的 EDGE 系统标签。
inject (30s) ─▶ 태그값 읽기 (TAG_EDGE_..._OPC_CONNECTED_COUNT) ─▶ function ─▶ telegram
若数值掉至 0,则表示所有 PLC 已断开 → 立即通知。
10. 通过 OPC-UA Subscribe 实现无需轮询的实时传输 (Edge → Edge)
inject (once) ─▶ OpcUa-Item ×N ─▶ join ─▶ OpcUa-Subscribe ─▶ function (정규화) ─▶ 태그값 쓰기
仅接收其他公司 OPC-UA 服务器的变更事件,并将其镜像 (mirror) 到本网关的标签中 —— 实现实时网关桥接。
详细 OPC-UA 节点设置请参考 OPC-UA 节点 页面。
11. 通过 Sparkplug B 发送到云端
inject (5s) ─▶ 태그값 읽기 ×N ─▶ function (metrics 배열 만들기) ─▶ sparkplug device out
PlantPulse 本身也支持 Sparkplug 发送 (고급 / 통합 파트너용 → Sparkplug B)。仅在需要自定义 Sparkplug 行为时才在 Node-RED 中直接发送。详细设置请参考 Sparkplug B 节点。
12. 创建用于随报警消息附带的图表图像
通过 Node-RED 的 node-red-contrib-image-output + chart.js 或外部 QuickChart API,可以将“过去 1 小时趋势”图表与报警一起发送至 Slack —— 使操作员能够立即做出判断。
下一步
- 流问题解决 — 常见陷阱