Visual IoTツール Node-REDには、データセットや基本的な制御構造がありますので、簡単なプログラムならコーディングなし(設定だけ)でプログラムを書くことができます。
しかし、少し複雑な処理になるとファンクションノードが便利です。ファンクションノードはjavascriptでコーディングできますので、複雑な処理をフローにまとめることができ、シンプルなわかり易いフローが書けます。
1.基本
まずは基本的な内容から。
1.1 名前をつけよう
ノードには日本語で名前を付けることができます。処理内容を表す名前を付けておくとフローが読み易くなります。「XXに変換する」「msg.cnt++」などわかり易い名前を付けてください。
1.2 入力は最大一つ、出力は複数可能
ファンクションノードの入り口は一つだけです。デフォルトの出力は一つですが、下部にある出力数を変更して増やすことができます。出力が複数場合は戻り値を配列で返します。出力しない出口にはnullをセットします。条件によってどれか一つに値を出力するだけなら、スイッチノードに渡した方が、修正が楽な場合もあるでしょう。
(追記:バージョン0.17以降では端子に名前をつけるとマウスオーバーで表示できますので、入出力などをわかり易く書いておくと良いでしょう。)
1.3 javascriptでコーディング
内蔵エディタはjavascript構文を理解してエラーやワーニングを表示してくれます。Node-REDが動作するNode.jsのバージョンの文法で記述します。msgオブジェクトを受け取って処理し、リターンバリューがmsgオブジェクトになります。
2.あらかじめ定義されたオブジェクト
msgオブジェクト以外のあらかじめ定義されたオブジェクトを説明します。
2.1 グローバルオブジェクト
プログラム全体で利用可能なグローバル変数が使えます。
global.get(‘オブジェクト名’)で取得し、 global.set(‘オブジェクト名’,値)で値を設定します。現在は永続化されないので、再起動で初期化されます。
2.2 フローオブジェクト
タブ内で有効なフロー変数もあります。
flow.get(‘オブジェクト名’)で取得し、flow.set(‘オブジェクト名’)で値を設定します。
永続化されないので、再起動で初期化されます。
2.3 node.send()
一つの出口に複数返す場合や、無名関数内で終了する場合は、returnでなく、 node.send(msgオブジェクト)を用います。returnは最後の一度死活変えませんし、無名関数内のreturnは全体の戻りではないからです。
2.4 requireはsetting.jsで
ファンクションノード内で requireできません。requireが必要な場合は、setting.jsのfunctionGlobalContextにrequireを追加します。Node-REDを再起動すると、設定したオブジェクトを global.get(‘オブジェクト名’) で取得できます。もちろん、必要に応じてユーザーディレクトリ( ホームディレクトリ/.node-red)で、モジュールをnpmインストールする必要があります。
3. オブジェクトの管理
簡単に見えるNode-REDプログラミングですが、意外とハマるのがオブジェクトの管理です。
3.1 msg.payloadは基本
標準的な出力はmsg.payloadですが、破壊されることも多いです。payload以外のプロパティを使えば多くの場合は大丈夫です。しかし、新しいmsgオブジェクトが生成される場合は、フロー変数やグローバル変数を使います。
3.2 新しいmsgオブジェクトで返す
受け取ったmsgオブジェクトを渡したくない場合は、「return {payload: 値};」とすると新しいオブジェクトのmsg.payloadとして値を返すことができます。ただし、後続の処理で、受け取ったmsgオブジェクトの値を渡せないので注意してください。特にhttp inが出力するmsgオブジェクトには、http responseに必要な情報が含まれますので注意してください。
3.3 コピーされるオブジェクト
「return [msg, msg];」のようにmsgオブジェクトを複数同時に返すと、オブジェクトッがコピーされ、別々のオブジェクトが渡されます。また、一つの出口から複数のノードに繋いだ場合もコピーされます。大量データを扱う場合には注意してください。新しいmsgオブジェクトを生成するか、node.send()で出力すると参照が渡されます(参照を渡すと想定外に内容が破壊されてしまうことがありますので注意してください)。
4.おわりに
簡単に始められるNode-REDプログラミングですが、ドキュメントをきちんと読んだり、色々試さないとわからないことがあります。ここに挙げた内容がわかっていれば、少し複雑な処理もスラスラと書けると思います。
詳しくは、公式ドキュメントの確認や、実際に動かすなどしてください。それでも困った時は、ユーザー会、slackやメーリングリストなどで聞いてみると良いと思います。