サブフローを作ってみる
今回はサブフローを作ってみます。ドキュメントはこちら。サブフローは自前でノードを定義してパレットに登録する機能です。フローを再利用する際に使います。一般的なプログラミングで言えば、関数を作るイメージですね。同じ処理が複数箇所に出てきたらサブフロー化を考えると良さそうです。
サブフローの追加
まずはメニューからサブフローを追加します。サブフローを編集するためのエディタが表示されます。
サブフローの編集
今回作成するフローの仕様は以下のとおりです。
- 入力はmsg.payload1つ(数値)
- 出力もmsg.payload1つ(数値)
- 入力値に環境変数Xをかけた値を出力する
- 出力値と同じ値をステータスに設定する
まずは、エディタ上部で入力と出力をそれぞれ「1」に、ステータスノードのチェックを「ON」にします。エディタ上には「input」、「output」、「status」というノードのようなものが追加されます。これらの間に処理を挟んであげればサブフローの完成です。
続いて、画面左上の「プロパティを編集」を選択します。この画面はサブフローに設定可能なプロパティを定義します。画面左下の「+追加」ボタンからプロパティ(環境変数)を追加して名前を「X」にした上で「数値型」に変更します。デフォルト値はとりあえず2としておきます。最後に「完了」を選択して保存します。
続いて計算部分を実装します。今回はFunctionノードを使ってみます。フローエディタ上にFunctionノードを追加してプロパティを開きます。「コード」に以下のような内容を記述します。先ほど追加したプロパティには環境変数としてアクセスできるようです。
最後に、冒頭の画面のようにFunctionノードをinput、output、statusの間に挟み込んで編集完了です。
サブフローを使う
本体のフローエディタのパレット上に作成したサブフローがノードとして追加されるので、これをエディタ上にドラッグ&ドロップして使います。
フローエディタ上にはinjectノードとdebugノード、作成したサブフローノードを2つ追加指定可のように繋げます。
injectノードのプロパティはこんな感じにします。
サブフローノードのプロパティはこんな感じにします(デフォルトのまま)。
debugノードはmsgオブジェクト全体を出力するようにします。デプロイしてinjectノードからフローを実行します。サブフローノードは入力値を2倍したものを次のノードに渡してステータスに同じ値を出力します。
まとめ
サブフローをうまく使うと複雑な処理をきれいに整理できそうです。カッコいいフローを作るには必須の機能かと思います。最後に今回作成したフロー定義のJSONを貼り付けておきます。
[
{
"id": "ec5fae59.42a3b",
"type": "tab",
"label": "フロー",
"disabled": false,
"info": ""
},
{
"id": "6702e3f0864d3685",
"type": "subflow",
"name": "サブフロー:X倍",
"info": "入力(msg.payload/数値)にプロパティXをかけた値をmsg.payloadに設定して出力する",
"category": "",
"in": [
{
"x": 60,
"y": 40,
"wires": [
{
"id": "738a9b6484067e95"
}
]
}
],
"out": [
{
"x": 360,
"y": 40,
"wires": [
{
"id": "738a9b6484067e95",
"port": 0
}
]
}
],
"env": [
{
"name": "X",
"type": "num",
"value": "2"
}
],
"meta": {
"module": "X倍",
"version": "0.0.1",
"author": "hoge@example.com",
"desc": "テストのモジュール",
"license": "Apache-2.0"
},
"color": "#DDAA99",
"status": {
"x": 360,
"y": 120,
"wires": [
{
"id": "738a9b6484067e95",
"port": 0
}
]
}
},
{
"id": "287c7229b54c2672",
"type": "subflow:6702e3f0864d3685",
"z": "ec5fae59.42a3b",
"name": "",
"env": [],
"x": 400,
"y": 80,
"wires": [
[
"2973daca310b555d"
]
]
},
{
"id": "8ba19b6276616d7d",
"type": "inject",
"z": "ec5fae59.42a3b",
"name": "",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "10",
"payloadType": "num",
"x": 250,
"y": 80,
"wires": [
[
"287c7229b54c2672"
]
]
},
{
"id": "86d805a71c368735",
"type": "debug",
"z": "ec5fae59.42a3b",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 730,
"y": 80,
"wires": []
},
{
"id": "738a9b6484067e95",
"type": "function",
"z": "6702e3f0864d3685",
"name": "X倍",
"func": "let x = env.get(\"X\");\nmsg.payload *= x;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 210,
"y": 40,
"wires": [
[]
]
},
{
"id": "2973daca310b555d",
"type": "subflow:6702e3f0864d3685",
"z": "ec5fae59.42a3b",
"name": "",
"x": 580,
"y": 80,
"wires": [
[
"86d805a71c368735"
]
]
}
]









コメント
コメントを投稿