例題集
完成したフローを取り込んですぐに試したい場合は、まず インポート用例題フロー を参照してください。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 → 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 { tag_id: 'TAG_PLANT_TOTAL_QTY', payload: String(sum) };
PlantPulse 自体に 計算式タグ 機能があります。単純な四則演算 はそちらで処理するのが高速で安定しています。Node-RED は 外部 API/MQTT/時間条件/条件分岐 が混在する場合に真価を発揮します。
3. CSV ロギング (分単位)
目標: 1分ごとに主要タグ 5つの値を CSV の 1行としてローカルディスクに蓄積。
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 { 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)
異常分岐末端の 2つのノード (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)。Node-RED からの直接送信は、Sparkplug 動作のカスタマイズが必要な場合 のみ使用してください。詳細設定は Sparkplug B ノード を参照。
12. アラームメッセージに添付するチャート画像の作成
Node-RED の node-red-contrib-image-output + chart.js または外部 QuickChart API を組み合わせて、Slack に 「過去 1時間の推移」 グラフをアラームと共に送信できます — オペレーターが即座に判断可能です。
次のステップ
- フローの問題解決 — よくある落とし穴