IIoT 예제 모음
아래 예제들은 현장에서 실제로 자주 만드는 패턴 들 입니다. 모두 Hello World 와 같은 식으로 노드를 드래그/연결/Deploy 만 하면 동작합니다. 코드 블록은 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 로 1초마다 갱신.
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 자체에 계산식 태그 기능이 있습니다. 단순 사칙연산 은 거기서 처리하는 게 빠르고 안정적입니다. 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 의 값을 태그로 가져오기 (역방향 통합)
목표: 외부 기상 API 의 외기온도를 5분마다 → 가상 태그 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. 알람 발생 시 슬랙 + 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). Node-RED 에서 직접 송신은 Sparkplug 동작 커스터마이즈가 필요할 때 만 사용하세요. 자세한 설정은 Sparkplug B 노드 참고.
12. 알람 메시지에 첨부할 차트 이미지 만들기
Node-RED 의 node-red-contrib-image-output + chart.js 또는 외부 QuickChart API 를 결합해서, 슬랙에 “지난 1시간 추이” 그래프를 알람과 함께 보낼 수 있습니다 — 운영자가 바로 판단 가능.
다음 단계
- 트러블슈팅 — 자주 빠지는 함정