✅ Node-RED Complete / Status ノードガイド

📚 目次

📖 1. 概要

Complete ノードStatus ノードは、他のノードの動作状況を監視するためのノードです。Catch ノード(エラー監視)と合わせて、フローの監視に使用します。

✅ Complete ノード

Complete

役割: 指定ノードの処理完了を検知

用途:

  • 非同期処理の完了検知
  • 処理時間の計測
  • 後続処理のトリガー

📊 Status ノード

Status

役割: 指定ノードのステータス変化を検知

用途:

  • 接続状態の監視(MQTT等)
  • 処理状況の表示
  • エラー状態の早期検知

🏭 工場のラインに例えると:Complete ノードは「作業完了」のランプ、Status ノードは機械の「状態表示パネル」のようなものです。作業が終わったか、今どんな状態かをリアルタイムで把握できます。

⚙️ 2. Complete ノード詳細

プロパティ

プロパティ説明
Scope監視対象ノードを選択(複数選択可)
Nameノードの表示名

出力メッセージ

{ "payload": /* 完了したノードが最後に出力した payload */, "_msgid": "元のメッセージID", /* 元のメッセージの全プロパティを継承 */ }

Complete が発火するタイミング

💡 ポイント:

すべてのノードが Complete をサポートしているわけではありません。主に非同期処理を行うノード(HTTP Request、Exec、File など)で有効です。

📊 3. Status ノード詳細

プロパティ

プロパティ説明
ステータス取得元監視対象ノードを選択(複数選択可、または全ノード)
名前ノードの表示名

出力メッセージ

{ "status": { "fill": "green", // 色: red, green, yellow, blue, grey "shape": "dot", // 形状: dot, ring "text": "connected" // テキスト }, "source": { "id": "ノードID", "type": "mqtt in", "name": "MQTT購読" } }

よくあるステータスパターン

fill(色)shape(形状)意味
greendot(塗りつぶし)正常・接続中
yellowring(輪)待機中・処理中
reddotエラー・切断
bluedot情報・アクティブ
greyring無効・停止

🔄 4. Catch ノードとの違い

ノード検知するもの発火タイミング
Complete処理完了ノードがメッセージ処理を完了したとき
Status状態変化ノードがステータスを更新したとき
Catchエラーノードがエラーを投げたとき
HTTP Request 正常完了 Complete
ステータス変化 Status
エラー発生 Catch

📥 5. サンプルフロー

📥 サンプルフローJSON(クリックで展開)
[ { "id": "complete_status_tab", "type": "tab", "label": "Complete/Status サンプル", "disabled": false, "info": "" }, { "id": "cs_comment1", "type": "comment", "z": "complete_status_tab", "name": "━━━ Complete ノード:処理完了の検知 ━━━", "info": "", "x": 210, "y": 40, "wires": [] }, { "id": "cs_inject1", "type": "inject", "z": "complete_status_tab", "name": "開始", "props": [{"p": "payload"}, {"p": "startTime", "v": "", "vt": "date"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "処理開始", "payloadType": "str", "x": 130, "y": 100, "wires": [["cs_delay"]] }, { "id": "cs_delay", "type": "delay", "z": "complete_status_tab", "name": "2秒待機", "pauseType": "delay", "timeout": "2", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 280, "y": 100, "wires": [["cs_debug1"]] }, { "id": "cs_debug1", "type": "debug", "z": "complete_status_tab", "name": "メイン出力", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 450, "y": 100, "wires": [] }, { "id": "cs_complete", "type": "complete", "z": "complete_status_tab", "name": "Delay完了検知", "scope": ["cs_delay"], "x": 300, "y": 160, "wires": [["cs_func_time"]] }, { "id": "cs_func_time", "type": "function", "z": "complete_status_tab", "name": "処理時間計算", "func": "var elapsed = Date.now() - msg.startTime;\nmsg.payload = \"処理完了! 経過時間: \" + elapsed + \"ms\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 500, "y": 160, "wires": [["cs_debug2"]] }, { "id": "cs_debug2", "type": "debug", "z": "complete_status_tab", "name": "完了通知", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "payload", "statusType": "auto", "x": 680, "y": 160, "wires": [] }, { "id": "cs_comment2", "type": "comment", "z": "complete_status_tab", "name": "━━━ Status ノード:ステータス監視 ━━━", "info": "", "x": 200, "y": 240, "wires": [] }, { "id": "cs_inject2", "type": "inject", "z": "complete_status_tab", "name": "ステータス更新", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "テストデータ", "payloadType": "str", "x": 160, "y": 300, "wires": [["cs_func_status"]] }, { "id": "cs_func_status", "type": "function", "z": "complete_status_tab", "name": "処理中表示", "func": "// ステータスを「処理中」に設定\nnode.status({fill:\"yellow\", shape:\"ring\", text:\"処理中...\"});\n\n// 1秒後に「完了」に変更\nsetTimeout(function() {\n node.status({fill:\"green\", shape:\"dot\", text:\"完了\"});\n}, 1000);\n\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 360, "y": 300, "wires": [["cs_debug3"]] }, { "id": "cs_debug3", "type": "debug", "z": "complete_status_tab", "name": "出力", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 530, "y": 300, "wires": [] }, { "id": "cs_status", "type": "status", "z": "complete_status_tab", "name": "ステータス監視", "scope": ["cs_func_status"], "x": 300, "y": 360, "wires": [["cs_debug4"]] }, { "id": "cs_debug4", "type": "debug", "z": "complete_status_tab", "name": "ステータス出力", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "status", "targetType": "msg", "statusVal": "status.text", "statusType": "msg", "x": 500, "y": 360, "wires": [] }, { "id": "cs_comment3", "type": "comment", "z": "complete_status_tab", "name": "━━━ 全監視ノードの組み合わせ ━━━", "info": "", "x": 190, "y": 440, "wires": [] }, { "id": "cs_inject3", "type": "inject", "z": "complete_status_tab", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "5", "payloadType": "num", "x": 130, "y": 500, "wires": [["cs_func_error"]] }, { "id": "cs_func_error", "type": "function", "z": "complete_status_tab", "name": "ランダムエラー", "func": "node.status({fill:\"blue\", shape:\"dot\", text:\"実行中\"});\n\nif (Math.random() < 0.5) {\n node.status({fill:\"red\", shape:\"dot\", text:\"エラー\"});\n node.error(\"ランダムエラー発生\", msg);\n return null;\n}\n\nnode.status({fill:\"green\", shape:\"dot\", text:\"成功\"});\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 300, "y": 500, "wires": [["cs_debug5"]] }, { "id": "cs_debug5", "type": "debug", "z": "complete_status_tab", "name": "成功", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 470, "y": 500, "wires": [] }, { "id": "cs_catch", "type": "catch", "z": "complete_status_tab", "name": "エラー捕捉", "scope": ["cs_func_error"], "uncaught": false, "x": 290, "y": 560, "wires": [["cs_debug6"]] }, { "id": "cs_debug6", "type": "debug", "z": "complete_status_tab", "name": "エラー内容", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "error", "targetType": "msg", "x": 490, "y": 560, "wires": [] } ]

📝 6. 演習問題

演習1: Complete で処理時間を計測 初級

📋 課題: Delay ノードの処理完了を Complete ノードで検知し、開始から完了までの時間を表示してください。

✅ 成功の条件:

💡 ヒント

1. Inject ノードで msg.startTime に現在時刻を設定

2. Complete ノードで Delay の完了を検知

3. Function ノードで経過時間を計算

✅ 解答例フロー
[ {"id": "ex1_tab", "type": "tab", "label": "演習1"}, {"id": "ex1_inject", "type": "inject", "z": "ex1_tab", "name": "開始", "props": [{"p": "payload"}, {"p": "startTime", "v": "", "vt": "date"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "開始", "payloadType": "str", "x": 130, "y": 100, "wires": [["ex1_delay"]]}, {"id": "ex1_delay", "type": "delay", "z": "ex1_tab", "name": "3秒待機", "pauseType": "delay", "timeout": "3", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 280, "y": 100, "wires": [[]]}, {"id": "ex1_complete", "type": "complete", "z": "ex1_tab", "name": "完了検知", "scope": ["ex1_delay"], "x": 290, "y": 160, "wires": [["ex1_func"]]}, {"id": "ex1_func", "type": "function", "z": "ex1_tab", "name": "経過時間", "func": "var ms = Date.now() - msg.startTime;\nmsg.payload = \"経過時間: \" + ms + \"ms\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 460, "y": 160, "wires": [["ex1_debug"]]}, {"id": "ex1_debug", "type": "debug", "z": "ex1_tab", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "payload", "targetType": "msg", "statusVal": "payload", "statusType": "auto", "x": 610, "y": 160, "wires": []} ]

演習2: Status でノード状態を監視 中級

📋 課題: Function ノードでステータスを更新し、Status ノードでその変化を検知してください。

✅ 成功の条件:

💡 ヒント

Function 内で node.status({fill:"色", shape:"形状", text:"テキスト"}) を使用します。

✅ 解答例フロー
[ {"id": "ex2_tab", "type": "tab", "label": "演習2"}, {"id": "ex2_inject", "type": "inject", "z": "ex2_tab", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "test", "payloadType": "str", "x": 130, "y": 100, "wires": [["ex2_func"]]}, {"id": "ex2_func", "type": "function", "z": "ex2_tab", "name": "状態変化", "func": "node.status({fill:\"yellow\", shape:\"ring\", text:\"処理中\"});\nsetTimeout(function(){\n node.status({fill:\"green\", shape:\"dot\", text:\"完了\"});\n}, 1500);\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 300, "y": 100, "wires": [[]]}, {"id": "ex2_status", "type": "status", "z": "ex2_tab", "name": "監視", "scope": ["ex2_func"], "x": 270, "y": 160, "wires": [["ex2_debug"]]}, {"id": "ex2_debug", "type": "debug", "z": "ex2_tab", "name": "状態", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "status", "targetType": "msg", "statusVal": "status.text", "statusType": "msg", "x": 430, "y": 160, "wires": []} ]

演習3: 3種類の監視ノード組み合わせ 上級

📋 課題: Complete、Status、Catch を組み合わせて、処理の成功/失敗を完全に監視するフローを作成してください。

✅ 成功の条件:

💡 ヒント

Function ノードで node.error() を使うとエラーを発生させ、Catch で捕捉できます。

✅ 解答例フロー
[ {"id": "ex3_tab", "type": "tab", "label": "演習3"}, {"id": "ex3_inject", "type": "inject", "z": "ex3_tab", "name": "実行", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "test", "payloadType": "str", "x": 130, "y": 120, "wires": [["ex3_func"]]}, {"id": "ex3_func", "type": "function", "z": "ex3_tab", "name": "ランダム処理", "func": "node.status({fill:\"blue\", shape:\"dot\", text:\"実行中\"});\nif (Math.random() < 0.3) {\n node.status({fill:\"red\", shape:\"dot\", text:\"エラー\"});\n node.error(\"失敗\", msg);\n return null;\n}\nnode.status({fill:\"green\", shape:\"dot\", text:\"成功\"});\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 310, "y": 120, "wires": [["ex3_debug1"]]}, {"id": "ex3_debug1", "type": "debug", "z": "ex3_tab", "name": "成功", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 490, "y": 120, "wires": []}, {"id": "ex3_catch", "type": "catch", "z": "ex3_tab", "name": "エラー捕捉", "scope": ["ex3_func"], "uncaught": false, "x": 290, "y": 180, "wires": [["ex3_debug2"]]}, {"id": "ex3_debug2", "type": "debug", "z": "ex3_tab", "name": "エラー", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "error", "targetType": "msg", "x": 490, "y": 180, "wires": []}, {"id": "ex3_status", "type": "status", "z": "ex3_tab", "name": "状態監視", "scope": ["ex3_func"], "x": 280, "y": 240, "wires": [["ex3_debug3"]]}, {"id": "ex3_debug3", "type": "debug", "z": "ex3_tab", "name": "状態", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "status.text", "targetType": "msg", "statusVal": "status.text", "statusType": "msg", "x": 490, "y": 240, "wires": []} ]

✅ 7. まとめ

🎯 重要ポイント:

⚠️ 注意事項:

🏭 8. 実務活用例

ケース1: HTTP Request の完了監視

外部API呼び出しの完了をComplete で検知し、後続処理をトリガー。

ケース2: MQTT接続状態の監視

Status ノードでMQTTブローカーへの接続状態を監視し、切断時にアラート。

ケース3: 処理時間の計測

開始時刻を記録し、Complete で完了を検知して処理時間をログ。

ケース4: バッチ処理の進捗監視

各処理ステップの Status を監視してダッシュボードに進捗を表示。

📚 Node-RED 公式ドキュメント

🏠