IIoT 示例集
以下示例均为现场经常构建的实用模式。与 Hello World 一样,只需拖拽节点、连接并 Deploy 即可运行。代码块是 JavaScript,直接粘贴到 function 节点中即可。
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 → 每秒更新一次 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 { tagId: 'TAG_PLANT_TOTAL_QTY', payload: String(sum) };
PlantPulse 自身带有计算公式标签功能。简单四则运算在那里处理更快也更稳定。当涉及外部 API / MQTT / 时间条件 / 条件分支混合时,Node-RED 更为强大。
3. CSV 记录(按分钟)
目标:每分钟将 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 { tagId: '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 { tagId: '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 —— 运维人员可立即判断。
后续步骤
- 故障排查 —— 常见陷阱