📋 サンプルフロー(クリックで展開)
参照元:NodeREDエディター内サンプルフロー
[
{
"id": "8621e9e599dbd8c4",
"type": "tab",
"label": "switch",
"disabled": false,
"info": "",
"env": []
},
{
"id": "b7186f3313abd22b",
"type": "comment",
"z": "8621e9e599dbd8c4",
"name": "1. Select output port based on input message value",
"info": "Switch node can route input message according to predefined rules.",
"x": 290,
"y": 60,
"wires": []
},
{
"id": "d09ce5ea3faeb00e",
"type": "switch",
"z": "8621e9e599dbd8c4",
"name": "正負判定",
"property": "payload",
"propertyType": "msg",
"rules": [
{"t": "lt", "v": "0", "vt": "num"},
{"t": "eq", "v": "0", "vt": "num"},
{"t": "gt", "v": "0", "vt": "num"}
],
"checkall": "true",
"repair": false,
"outputs": 3,
"x": 360,
"y": 140,
"wires": [
["9a2832922762fa33"],
["279dc77e3fb2b221"],
["a224bd3ca936ad73"]
]
},
{
"id": "72691bd5277734f1",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "負の数",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 660,
"y": 100,
"wires": []
},
{
"id": "a224bd3ca936ad73",
"type": "change",
"z": "8621e9e599dbd8c4",
"name": "Positive",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "positive", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 180,
"wires": [["df0910ad02232f15"]]
},
{
"id": "279dc77e3fb2b221",
"type": "change",
"z": "8621e9e599dbd8c4",
"name": "Zero",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "zero", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 490,
"y": 140,
"wires": [["d0da15ce4ce14957"]]
},
{
"id": "9a2832922762fa33",
"type": "change",
"z": "8621e9e599dbd8c4",
"name": "Negative",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "negative", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 100,
"wires": [["72691bd5277734f1"]]
},
{
"id": "d0da15ce4ce14957",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "ゼロ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 650,
"y": 140,
"wires": []
},
{
"id": "df0910ad02232f15",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "正の数",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 660,
"y": 180,
"wires": []
},
{
"id": "867413ec6823fdf5",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "-10",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "-10",
"payloadType": "num",
"x": 210,
"y": 100,
"wires": [["d09ce5ea3faeb00e"]]
},
{
"id": "0abb6c42a3426e8d",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "0",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "0",
"payloadType": "num",
"x": 210,
"y": 140,
"wires": [["d09ce5ea3faeb00e"]]
},
{
"id": "6105705b4b8476a0",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "10",
"props": [{"p": "payload"}, {"p": "topic", "vt": "str"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "10",
"payloadType": "num",
"x": 210,
"y": 180,
"wires": [["d09ce5ea3faeb00e"]]
},
{
"id": "comment_topic",
"type": "comment",
"z": "8621e9e599dbd8c4",
"name": "2. Route based on msg.topic",
"info": "Switch node can route a message based on msg.topic.",
"x": 230,
"y": 280,
"wires": []
},
{
"id": "f2cbd8ce34c4c8",
"type": "switch",
"z": "8621e9e599dbd8c4",
"name": "センサー振り分け",
"property": "topic",
"propertyType": "msg",
"rules": [
{"t": "eq", "v": "temperature", "vt": "str"},
{"t": "eq", "v": "humidity", "vt": "str"},
{"t": "eq", "v": "pressure", "vt": "str"}
],
"checkall": "true",
"repair": false,
"outputs": 3,
"x": 390,
"y": 380,
"wires": [
["50651c06281524"],
["278638931cc5c8"],
["e4db256da80ca8"]
]
},
{
"id": "c4de36a5f14bc8",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "温度",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "temperature",
"payload": "27",
"payloadType": "num",
"x": 190,
"y": 340,
"wires": [["f2cbd8ce34c4c8"]]
},
{
"id": "96073ecd9207f",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "湿度",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "humidity",
"payload": "45",
"payloadType": "num",
"x": 190,
"y": 380,
"wires": [["f2cbd8ce34c4c8"]]
},
{
"id": "11b023ef147c9c",
"type": "inject",
"z": "8621e9e599dbd8c4",
"name": "気圧",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "pressure",
"payload": "1013",
"payloadType": "num",
"x": 190,
"y": 420,
"wires": [["f2cbd8ce34c4c8"]]
},
{
"id": "50651c06281524",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "Temperature",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 610,
"y": 340,
"wires": []
},
{
"id": "278638931cc5c8",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "Humidity",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 600,
"y": 380,
"wires": []
},
{
"id": "e4db256da80ca8",
"type": "debug",
"z": "8621e9e599dbd8c4",
"name": "Pressure",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 600,
"y": 420,
"wires": []
}
]
プロパティ: msg.payload
ルール1: < 0 → 出力1
ルール2: == 0 → 出力2
ルール3: > 0 → 出力3
全ルールを確認: 有効(複数条件に一致する可能性がある場合)
プロパティ: msg.topic
ルール1: == "temperature" → 出力1
ルール2: == "humidity" → 出力2
ルール3: == "pressure" → 出力3
演習2: コマンド処理中級
📝 課題:
文字列コマンド(start/stop/restart)を判定し、それぞれ異なる処理を行うフローを作成してください。
🎯 要求仕様:
- msg.payloadにコマンド文字列が入力される
- "start" → 「システムを起動します」
- "stop" → 「システムを停止します」
- "restart" → 「システムを再起動します」
- その他 → 「不明なコマンドです」
📊 期待される動作:
- Changeノードでメッセージを設定し、Debugで表示
✅ 成功の条件:
"start" を送ると、デバッグパネルに "システムを起動します" が表示される
"stop" を送ると "システムを停止します"、"restart" を送ると "システムを再起動します" が表示される
"hello" など未定義のコマンドを送ると "不明なコマンドです" が表示される
- 各コマンドに対して1つのメッセージのみが出力され、他の出力ポートには届かない
💡 ヒント
Switchノードの設定:
- プロパティ: msg.payload
- ルール: 文字列の完全一致(==)を使用
- 最後に「otherwise」で不明コマンドをキャッチ
Changeノードの設定:
- 各出力ポートにChangeノードを接続
- msg.payloadを対応するメッセージに変更
✅ 解答例フロー
[
{
"id": "ex2_inject_start",
"type": "inject",
"name": "start",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "start",
"payloadType": "str",
"x": 150,
"y": 80,
"wires": [["ex2_switch"]]
},
{
"id": "ex2_inject_stop",
"type": "inject",
"name": "stop",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "stop",
"payloadType": "str",
"x": 150,
"y": 120,
"wires": [["ex2_switch"]]
},
{
"id": "ex2_inject_other",
"type": "inject",
"name": "unknown",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "hello",
"payloadType": "str",
"x": 150,
"y": 160,
"wires": [["ex2_switch"]]
},
{
"id": "ex2_switch",
"type": "switch",
"name": "コマンド判定",
"property": "payload",
"propertyType": "msg",
"rules": [
{"t": "eq", "v": "start", "vt": "str"},
{"t": "eq", "v": "stop", "vt": "str"},
{"t": "eq", "v": "restart", "vt": "str"},
{"t": "else"}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 320,
"y": 120,
"wires": [
["ex2_change_start"],
["ex2_change_stop"],
["ex2_change_restart"],
["ex2_change_unknown"]
]
},
{
"id": "ex2_change_start",
"type": "change",
"name": "起動メッセージ",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "システムを起動します", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 520,
"y": 60,
"wires": [["ex2_debug"]]
},
{
"id": "ex2_change_stop",
"type": "change",
"name": "停止メッセージ",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "システムを停止します", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 520,
"y": 100,
"wires": [["ex2_debug"]]
},
{
"id": "ex2_change_restart",
"type": "change",
"name": "再起動メッセージ",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "システムを再起動します", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 530,
"y": 140,
"wires": [["ex2_debug"]]
},
{
"id": "ex2_change_unknown",
"type": "change",
"name": "不明メッセージ",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "不明なコマンドです", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 520,
"y": 180,
"wires": [["ex2_debug"]]
},
{
"id": "ex2_debug",
"type": "debug",
"name": "結果",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 710,
"y": 120,
"wires": []
}
]
演習3: 温度アラート中級
📝 課題:
温度センサーの値に応じて、正常/警告/危険のアラートレベルを判定するフローを作成してください。
🎯 要求仕様:
- 範囲チェックを使用
- 18〜26度: 正常(緑)
- 26〜30度または10〜18度: 警告(黄)
- 30度以上または10度以下: 危険(赤)
📊 期待される動作:
✅ 成功の条件:
- 22度を入力すると
"正常" 系のメッセージが表示される
- 28度を入力すると
"警告" 系のメッセージが表示される
- 35度や5度を入力すると
"危険" 系のメッセージが表示される
- 境界値(18度、26度、30度、10度)が正しいカテゴリに分類される
💡 ヒント
Switchノードの設定:
- プロパティ: msg.payload
- 「is between」条件を使用
- 複数の条件を組み合わせる
条件の順序:
- より具体的な条件を先に配置
- または「最初に一致で終了」を使用
✅ 解答例フロー
[
{
"id": "ex3_inject_normal",
"type": "inject",
"name": "22度",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "22",
"payloadType": "num",
"x": 150,
"y": 80,
"wires": [["ex3_switch"]]
},
{
"id": "ex3_inject_warning",
"type": "inject",
"name": "28度",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "28",
"payloadType": "num",
"x": 150,
"y": 120,
"wires": [["ex3_switch"]]
},
{
"id": "ex3_inject_danger",
"type": "inject",
"name": "35度",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "35",
"payloadType": "num",
"x": 150,
"y": 160,
"wires": [["ex3_switch"]]
},
{
"id": "ex3_switch",
"type": "switch",
"name": "温度判定",
"property": "payload",
"propertyType": "msg",
"rules": [
{"t": "btwn", "v": "18", "vt": "num", "v2": "26", "v2t": "num"},
{"t": "btwn", "v": "10", "vt": "num", "v2": "18", "v2t": "num"},
{"t": "btwn", "v": "26", "vt": "num", "v2": "30", "v2t": "num"},
{"t": "else"}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 320,
"y": 120,
"wires": [
["ex3_change_normal"],
["ex3_change_warning_low"],
["ex3_change_warning_high"],
["ex3_change_danger"]
]
},
{
"id": "ex3_change_normal",
"type": "change",
"name": "正常",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "🟢 正常: 快適な温度です", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 490,
"y": 60,
"wires": [["ex3_debug"]]
},
{
"id": "ex3_change_warning_low",
"type": "change",
"name": "警告(低)",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "🟡 警告: 温度が低めです", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 100,
"wires": [["ex3_debug"]]
},
{
"id": "ex3_change_warning_high",
"type": "change",
"name": "警告(高)",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "🟡 警告: 温度が高めです", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 140,
"wires": [["ex3_debug"]]
},
{
"id": "ex3_change_danger",
"type": "change",
"name": "危険",
"rules": [{"t": "set", "p": "payload", "pt": "msg", "to": "🔴 危険: 異常温度です!", "tot": "str"}],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 490,
"y": 180,
"wires": [["ex3_debug"]]
},
{
"id": "ex3_debug",
"type": "debug",
"name": "アラート",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 670,
"y": 120,
"wires": []
}
]
演習4: 配列の正負分離上級
📝 課題:
数値の配列を入力し、正の数と負の数を別々の配列に分離してください。
🎯 要求仕様:
- Split、Switch、Joinノードを組み合わせる
- 入力: [3, -2, -1, 1, -3, 2]
- 出力1: [3, 1, 2](正の数)
- 出力2: [-2, -1, -3](負の数)
📊 期待される動作:
✅ 成功の条件:
- デバッグパネルに2つのメッセージが表示される(正の数の配列と負の数の配列)
- 正の数の配列が
[3, 1, 2](順序は入力順)になっている
- 負の数の配列が
[-2, -1, -3](順序は入力順)になっている
- 0が入力に含まれた場合、どちらの配列にも含まれない(0は正でも負でもない)
💡 ヒント
フローの構成:
- Inject: JSON配列を入力
- Split: 配列を個別メッセージに分割
- Switch: > 0 と < 0 で振り分け
- Join: 各出力を配列に再結合(autoモード)
Joinノードの設定:
- モード: 自動(Splitとペアで使用)
- msg.partsを使用して自動再結合
✅ 解答例フロー
[
{
"id": "ex4_inject",
"type": "inject",
"name": "数値配列",
"props": [{"p": "payload"}],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "[3, -2, -1, 1, -3, 2]",
"payloadType": "json",
"x": 160,
"y": 100,
"wires": [["ex4_split"]]
},
{
"id": "ex4_split",
"type": "split",
"name": "分割",
"splt": "\\n",
"spltType": "str",
"arraySplt": 1,
"arraySpltType": "len",
"stream": false,
"addname": "",
"x": 310,
"y": 100,
"wires": [["ex4_switch"]]
},
{
"id": "ex4_switch",
"type": "switch",
"name": "正負判定",
"property": "payload",
"propertyType": "msg",
"rules": [
{"t": "gt", "v": "0", "vt": "num"},
{"t": "lt", "v": "0", "vt": "num"}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 460,
"y": 100,
"wires": [
["ex4_join_positive"],
["ex4_join_negative"]
]
},
{
"id": "ex4_join_positive",
"type": "join",
"name": "正の数",
"mode": "auto",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"x": 620,
"y": 80,
"wires": [["ex4_debug_positive"]]
},
{
"id": "ex4_join_negative",
"type": "join",
"name": "負の数",
"mode": "auto",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"x": 620,
"y": 120,
"wires": [["ex4_debug_negative"]]
},
{
"id": "ex4_debug_positive",
"type": "debug",
"name": "正の配列",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 790,
"y": 80,
"wires": []
},
{
"id": "ex4_debug_negative",
"type": "debug",
"name": "負の配列",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"x": 790,
"y": 120,
"wires": []
}
]
複数センサーからのMQTTメッセージ
↓
Switchノード(msg.topicで判定)
├─ sensors/temperature → 温度処理フロー
├─ sensors/humidity → 湿度処理フロー
├─ sensors/pressure → 気圧処理フロー
└─ otherwise → ログ記録
※ センサー種別ごとに異なる処理を実行
HTTP Inノード
↓
Switchノード(msg.req.methodで判定)
├─ GET → データ取得処理
├─ POST → データ作成処理
├─ PUT → データ更新処理
├─ DELETE → データ削除処理
└─ otherwise → 405 Method Not Allowed
※ RESTful APIのルーティング
エラーメッセージ受信
↓
Switchノード(msg.payload.levelで判定)
├─ "critical" → 緊急通知 + 自動復旧
├─ "error" → アラート送信
├─ "warning" → ログ記録
└─ "info" → 統計更新のみ
※ ログレベルに応じた処理の分岐
ユーザーリクエスト
↓
Switchノード(msg.user.roleで判定)
├─ "admin" → 全機能アクセス
├─ "editor" → 編集機能のみ
├─ "viewer" → 閲覧のみ
└─ otherwise → アクセス拒否
※ 権限ベースのアクセス制御