Node-RED2.2の新機能: システム定義の環境変数

株式会社日立製作所 
サービスコンピューティング研究部
西山博泰

# はじめに

 [Node-RED](https://nodered.org/)はノードと呼ばれる機能ブロックを画面上でつなぎ合わせることでフローと呼ばれるプログラムを簡単に作成できるプログラミングツールです。Node-REDはOSSとして公開されており、部品として利用可能なノードもOSSとして多数[公開](https://flows.nodered.org/)(この記事の執筆時点で約3700ノード)されています。

![Node-RED](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/1610dab6-43ad-3822-12a1-5262c04a3e12.png)

　Node-REDは、Raspberry PiのOSに標準搭載されるなどIoT分野で活用されるとともに、Web APIの呼び出しやデータベースアクセス、データ処理を行うノード、ダッシュボードによるGUI作成機能などを備えており、幅広い分野で活用が進んでいます。
　2022年1月にNode-REDの最新版であるバージョン2.2がリリースされました。Node-RED 2.2では、フローの編集機能などさまざまな新機能が実装されています。一連の記事でNode-RED 2.2の新機能を紹介します。
　この記事では、そのうち筆者が開発に参画したシステム定義の環境変数について紹介します。

# Node-REDでの環境変数

Node-REDにおける**環境変数**(environment variable)とは、ノード内で参照可能な変数であり、フローのデプロイ時にその値が確定し、フロー実行中に変更することはできません。環境変数は同一フローの設定や動作をカスタマイズして再利用性の高いフロー作成を容易化することを目的としています。
環境変数定義の例を以下に示します。この例では、環境変数「`VAR`」の値を文字列「`Hello, World!`」と定義しています。

![環境変数の定義](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/d1b28625-8325-63ab-30fa-53654f9a0b88.png)

定義した環境変数は各ノードの設定などで参照できます。次の例では、Changeノードで`msg.payload`に環境変数`VAR`の値を設定します。

![環境変数の参照](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/7b8fab9b-6290-9cdb-6f50-460fd4cd4376.png)

この例では、`VAR`の値を変更することでChangeノードの出力メッセージを変更することができます。

# システム定義環境変数

フロー中のノードなどは、**名前**や**ID**といった固有の属性値を持っています。これまで、Functionノードなどを除くと、こういった属性値を簡単に参照する仕組みはありませんでした。Node-RED 2.2では、ノード、グループ、タブに対して次の表に示す環境変数がシステムによって予め定義され、ノードの名前やIDを簡単に参照することが可能となります。

|     | 環境変数名 | 概要  |
| --- | --- | --- |
| 1   | NR_NODE_ID | ノードのID |
| 2   | NR_NODE_NAME | ノードの名前フィールドの値 |
| 3   | NR_NODE_PATH | ノードのパス情報(次章参照) |
| 4   | NR_GROUP_ID | ノードの所属グループのID |
| 5   | NR_GROUP_NAME | ノードの所属グループの名前フィールドの値 |
| 6   | NR_FLOW_ID | ノードの所属タブのID |
| 7   | NR_FLOW_NAME | ノードの所属フローの名前フィールドの値 |

簡単な例を見てみましょう。次の例はInjectノードの出力メッセージをデバッグサイドバーに表示する簡単なフローです。

![example00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/1d9f3d24-5c82-fffd-3d9e-6d5527bd96f9.png)

Injectノードの設定を以下に示します。

![inject-node.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/e21d7717-f9a2-0f8c-dd8c-fbb3a5400496.png)

この設定では`msg.payload`の値として以下の[JSONata](https://jsonata.org/)式を指定しています。

```
$env("NR_NODE_NAME") & "からのメッセージ"
```

ここで、`$env`は環境変数の参照を行う関数、`&`は文字列の結合を意味します。よって、この式はノード名に「からのメッセージ」を付け加えた文字列に変換されます。各Injectノードはノード名を除いて同じ設定しており、ノード名の設定に応じて「ノードAからのメッセージ」、「ノードBからのメッセージ」が出力されます。
ノードが所属するグループ名も同じように参照することができます。

![group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/9359c47c-8986-79ef-c382-20e1a960a4d2.png)

この例では、Changeノードで`msg.payload`の値に以下のJSONata式を指定しているとすると、出力として「グループA内のメッセージ」が得られます。

```
$env("NR_GROUP_NAME") & "内のメッセージ"
```

# ノードのパス情報

`NR_NODE_PATH`環境変数では、ノードに対してパスと呼ばれる情報を取得できます。パス情報とは、タブ(フロー)、サブフロー、ノードのIDを`/`で結合した文字列です。パス情報を使うと、大規模なフローで何らかの問題が発生したケースに置いてパス情報を含むログを出力することで問題の発生箇所を特定することが容易になります。なお、グループはパスに含まれません。

例えば、次の例ではChangeノードは、タブ「**フロー**」中で定義されています。このため、Changeノードの`NR_NODE_PATH`のパスは、「*フローのID*`/`*ChangeノードのID*」となります(例: `939e57d8c7e31c60/08cc547728274e31`)。

![path00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/b8301dc5-603c-b878-7716-74a30ec36e6c.png)

ノードのパスとIDの関係について、サブフローが関連する場合に注意が必要です。サブフローの定義(サブフローテンプレート)は、ワークスペースに配置された場合に内部的にコピー(サブフローインスタンス)が作られます。このため、サブフローインスタンス内のノードのIDはコピーされたノードのIDとなります。サブフロー内でコピーされたノードIDをユーザが知ることは難しいため、パス情報としてこのIDを出力することは有用ではありません。そこで、パス情報にはコピー元のノードのIDを含めるようにしています。

以下の例では、サブフロー内のChangeノードの`NR_NODE_PATH`は、「フローのID`/`サブフローのID`/`サブフロー定義内のChangeノードのID」となります(例: `bb16a61c626ee912/e7fce430b7b4a975/4c149d98875beffb`)。

![path01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546217/46fe0dc4-0fea-e782-eb3e-ae74dc617bdb.png)

# おわりに

 Node-RED 2.2で新機能として実現されたシステム定義環境変数を紹介しました。この機能を用いることで、ログ等からノードを特定することが容易になります。大規模なフローを作成する場合に活用してみてください。

# 参考

- [Node-RED2.1の新機能: フローおよびグループに対する環境変数の定義](https://qiita.com/HiroyasuNishiyama/items/ca6a255760e40b247187)
- [Node-RED2.2の新機能: エディタの機能追加](https://qiita.com/k-toumura/items/dcae073e94f41c4ef1c0)


*Node-RED: Node-REDは，OpenJS Foundationの米国およびその他の国における登録商標または商標である。*
*JavaScript: JavaScriptは、Oracleの米国およびその他の国における登録商標または商標である。*