このガイドでは、Node-REDのChangeノードについて、初心者の方でも理解できるように詳しく説明します。
Changeノードは、メッセージのプロパティを変更・設定・削除・移動するノードです。 日常生活で例えると、郵便物の宛名書き換えや転送サービスのようなものです。
📮 郵便局の仕分け作業に例えると:
Changeノードは、入力メッセージを受け取り、指定したルールに従って プロパティを変更して出力します。 Functionノードを使わずに、シンプルなデータ操作が可能です。
プロパティに新しい値を設定
文字列の一部を検索して置換
プロパティを完全に削除
プロパティを別の場所に移動
| 設定項目 | 説明 | 使用例 |
|---|---|---|
| 操作タイプ | Set/Change/Delete/Moveから選択 | 代入、置換、削除、移動 |
| 対象プロパティ | 操作対象のプロパティを指定 | msg.payload, flow.count |
| プロパティタイプ | msg/flow/global から選択 | メッセージ、フロー変数、グローバル変数 |
| 値 | 設定する値(Setの場合) | "Hello", 123, true |
| 値のタイプ | 値の型を指定 | 文字列、数値、JSONata等 |
| 検索文字列 | 置換対象(Changeの場合) | "old", /pattern/g |
| 置換文字列 | 置換後の値(Changeの場合) | "new" |
| 移動先 | 移動先プロパティ(Moveの場合) | msg.data, msg.result |
Changeノードの「Set」操作では、様々なタイプの値を設定できます。
| タイプ | 説明 | 例 |
|---|---|---|
| str | 文字列 | "Hello World!" |
| num | 数値 | 123, 3.14 |
| bool | 真偽値 | true, false |
| JSON | JSONオブジェクト | {"name": "Alice", "age": 30} |
| msg. | 他のmsgプロパティの値 | msg.topic, msg.payload.name |
| flow. | フローコンテキスト変数 | flow.count, flow.config |
| global. | グローバルコンテキスト変数 | global.settings |
| env | 環境変数 | HOME, NODE_ENV |
| JSONata | JSONata式で動的に計算 | payload & ", World!" |
📥 サンプルフローのインポート方法:
このサンプルフローには、以下で説明する全パターンの実例が含まれています。
参照元:NodeREDエディター内サンプルフロー
用途: メッセージのプロパティに固定の値を設定
📌 動作の流れ:
設定例:
用途: 1つのChangeノードで複数のプロパティを一度に設定
設定例:
用途: 既存の値を加工して新しい値を設定
📌 JSONataの活用例:
payload & ", World!" - 文字列結合payload * 2 - 数値計算$now() - 現在時刻取得$uppercase(payload) - 大文字変換設定例:
用途: システムの環境変数をメッセージに設定
設定例:
用途: フロー内で共有する変数の設定・参照
📌 カウンターの実装:
$flowContext("count")+1設定例(初期化):
設定例(カウントアップ):
用途: 不要なプロパティをメッセージから削除
設定例:
用途: プロパティを別の場所に移動(元は削除される)
設定例:
📝 課題:
ChangeノードでJSONオブジェクトをmsg.payloadに設定してください。
🎯 要求仕様:
📊 期待される動作:
✅ 成功の条件:
name: "Alice" と age: 25 の両プロパティが含まれるage が文字列ではなく数値型(25)として表示されるInjectノードの設定:
Changeノードの設定:
Debugノードの設定:
📝 課題:
JSONオブジェクトの一部のプロパティだけを変更してください。
🎯 要求仕様:
📊 期待される動作:
✅ 成功の条件:
sensor.temp の値が 25(数値型)になっているsensor.humidity の値が 0(初期値のまま)になっている1つ目のChangeノードの設定:
2つ目のChangeノードの設定:
📝 課題:
メッセージ内の文字列を検索して置換してください。
🎯 要求仕様:
📊 期待される動作:
✅ 成功の条件:
"Hello, World!" が表示される"Node-RED" が出力に含まれていない"Hello, " と "!")がそのまま残っているInjectノードの設定:
Changeノードの設定:
📝 課題:
複数のルールを組み合わせて、センサーデータを整形してください。
🎯 要求仕様:
📊 期待される動作:
✅ 成功の条件:
temp: 25.5、humidity: 65、timestamp の3プロパティを持つオブジェクトが表示されるraw_temp と raw_humidity プロパティが出力に含まれていないtimestamp の値がISO 8601形式の日時文字列になっているtimestamp の値が更新されるInjectノードの設定:
Changeノードの設定(複数ルール):
JSONata式のポイント:
payload.raw_temp / 100$now()Changeノードをマスターしたら、以下のノードも学んでみましょう:
| 問題 | 原因 | 解決方法 |
|---|---|---|
| 値が設定されない | プロパティパスの誤り | msg.を含めた完全なパスを確認 |
| JSONataでエラー | 構文エラー | JSONataエディタ(J:アイコン)で検証 |
| 数値計算ができない | 値が文字列になっている | 値タイプを「数値」に変更、または$number()で変換 |
| 置換が動作しない | 大文字小文字の違い | 正規表現で /pattern/i を使用 |
| flow変数が取得できない | 初期化されていない | デフォルト値を設定、または初期化フローを作成 |
| ネストしたプロパティが作れない | 親オブジェクトが存在しない | 先に親オブジェクトを作成してから子を設定 |
JSONata は、JSONデータを変換・問い合わせするための軽量な式言語です。Changeノードの値タイプで 「J:」(JSONata式) を選択すると、動的な値の計算やデータ変換を1つのルールで実現できます。
msg. を省略して payload と書きます(msg.payload ではなく payload)以下では、このサイトの各ノードガイドの演習問題で実際に使われているJSONata式をカテゴリ別に紹介します。
| 関数 / 演算子 | 説明 | 実用例 | 使用箇所 |
|---|---|---|---|
&(結合) |
文字列を連結する演算子。+ ではなく & を使う |
"処理済: " & payload |
Commentガイド演習2、UDPガイド演習2 |
$string() |
数値やその他の型を文字列に変換する | payload.host & ":" & $string(payload.port) |
YAMLガイド演習3、Watchガイド演習3、Splitガイド演習3、Debugガイド演習3 |
$uppercase() |
文字列をすべて大文字に変換する | $uppercase(payload) |
Splitガイド演習4 |
$trim() |
文字列の前後の空白・改行を除去する | $trim(payload) |
Execガイド演習2 |
$join() |
配列の要素を結合して1つの文字列にする | $join(['テストメール送信時刻: ', $now()]) |
Emailガイド演習1 |
+ ではなく & を使います。+ は数値の加算専用です。数値を文字列に結合する場合は $string() で明示的に変換してください。
topic & ": " & $string(payload) & "円"(Splitガイド演習3で使用)
| 関数 / 演算子 | 説明 | 実用例 | 使用箇所 |
|---|---|---|---|
四則演算+ - * / |
加算・減算・乗算・除算 | payload.raw_temp / 100 |
本ガイド演習4 |
$floor() |
小数点以下を切り捨てて整数にする | $floor($random() * 40 + 20) |
Dashboard2 Layoutガイドサンプル |
$random() |
0以上1未満のランダムな数値を返す | $floor($random() * 100) |
Dashboard2 Layoutガイドサンプル |
$round() |
指定した桁数に四捨五入する | $round(payload, 1) |
Sortガイド演習 |
$count() |
配列の要素数を返す | $count(payload.users) |
YAMLガイド演習4 |
$floor($random() * N) で0からN-1のランダム整数を生成できます。テストデータの生成に便利です。
$floor($random() * 30 + 10) → 10から39のランダム整数
$now() は現在の日時を返す関数です。オプションでフォーマットパターンを指定できます。
| 式 | 出力例 | 使用箇所 |
|---|---|---|
$now() |
2024-12-16T10:30:00.000Z |
本ガイド演習4 |
$now('[Y0001]-[M01]-[D01]') |
2024-12-16 |
(参考) |
$now('[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f001]Z') |
2024-12-16T10:30:00.000Z |
Watchガイド演習3 |
$now('[D01]/[M01]/[Y0001] [H01]:[m01]') |
16/12/2024 10:30 |
(参考) |
[Y0001]=年4桁、[M01]=月2桁、[D01]=日2桁、[H01]=時2桁、[m01]=分2桁、[s01]=秒2桁、[f001]=ミリ秒3桁
| パターン | 説明 | 実用例 | 使用箇所 |
|---|---|---|---|
| オブジェクト構築 | 新しいオブジェクトを組み立てる | {"host": payload.database.primary.host, "port": payload.database.primary.port} |
YAMLガイド演習3、XMLガイド演習3 |
| ネストアクセス | 深い階層のプロパティにドットでアクセス | payload.database.primary.host |
YAMLガイド演習3 |
| バッククォート | 特殊文字を含むプロパティ名をエスケープ | payload.item.`$`.id |
XMLガイド演習3 |
$、テキストコンテンツは _ というプロパティ名に格納されます。JSONataでこれらにアクセスするには、バッククォート(`)で囲む必要があります。
{"id": payload.item.`$`.id, "name": payload.item.name[0], "price": payload.item.price[0].`_`}
| パターン | 説明 | 実用例 | 使用箇所 |
|---|---|---|---|
| フィルタリング | 条件に合う要素だけを抽出する | payload.users[role="admin"].name |
YAMLガイド演習4 |
| プロパティ抽出 | 配列の各要素から特定のプロパティを取り出す | payload.users.name |
YAMLガイド演習4 |
$append() |
配列に要素を追加する | $append($A, [payload]) |
Joinガイドサンプル |
配列[条件] で条件に合う要素を抽出し、.プロパティ名 を続けることで特定のフィールドだけを取り出せます。SQLの SELECT name FROM users WHERE role = 'admin' に近い感覚で使えます。
| 関数 | 説明 | 実用例 |
|---|---|---|
$flowContext("変数名") |
フローコンテキストの値を取得 | $flowContext("count") + 1 |
$globalContext("変数名") |
グローバルコンテキストの値を取得 | $globalContext("config") |
$env("変数名") |
環境変数の値を取得 | $env("API_KEY") |
flow.変数名 や global.変数名 を直接指定する方法もあります。$flowContext() などの関数は、JSONata式の中で他の計算と組み合わせたい場合に使います(例: $flowContext("count") + 1)。
| パターン | 説明 | 実用例 |
|---|---|---|
| 三項演算子 | 条件に応じて異なる値を返す | payload > 30 ? "高温" : "正常" |
| 複合条件 | and / or で複数条件を組み合わせ |
payload >= 20 and payload <= 30 ? "適温" : "注意" |
| やりたいこと | JSONata式 |
|---|---|
| 文字列を結合する | "prefix: " & payload |
| 数値を文字列にする | $string(payload) |
| 大文字に変換する | $uppercase(payload) |
| 空白を除去する | $trim(payload) |
| 現在時刻を取得する | $now() |
| 小数を切り捨てる | $floor(payload) |
| 四捨五入する | $round(payload, 2) |
| ランダムな整数を生成する | $floor($random() * 100) |
| 配列の要素数を数える | $count(payload) |
| 配列を条件で絞り込む | payload[price > 1000] |
| 新しいオブジェクトを作る | {"key1": payload.a, "key2": payload.b} |
| 条件で値を切り替える | payload > 30 ? "高" : "低" |
| フロー変数を参照する | $flowContext("変数名") |
このガイドが役に立ちましたら、実際のプロジェクトで練習してみてください!
Changeノードはフローの中で最もよく使われる基本ノードの一つです。
参照元:NodeREDエディター内サンプルフロー