前々回、前回と「Node-RED User Group Japan」様の『はじめてのノード開発』を練習してみました。いよいよ自前のノードを作ってみます。最初はちんまりと、流れてくるデータの中で「過去最大」とか「過去最小」とかチェックしてくれるだけのノードを作ってみます。ポイントはコンテキストへのアクセスね。
※「ブロックを積みながら」投稿順 index はこちら
※動作確認にはRaspberry Pi 3 model B+のRaspberry Pi OS(32bit)上にインストールした以下を使用しています。
-
- Node-RED v2.0.5
- node-red-dashboard 3.2.0
今回参照させていただいているノード開発のチュートリアル的ドキュメントは「Node-RED User Group Japan」様の以下のページです。
自前 data-check ノードの仕様
上流から次々に流れてくる msg.payload(実数値想定、整数でも数値化できる文字列でも可。数値化できんものは無視)の数値にたいし、
-
- 最大値を更新したら msg.MAXDATA というプロパティにその数値を載せ
- 最小値を更新したら msg.MINDATA というプロパティにその数値を載せ
- ついでに処理したデータ数を msg.NDATA に載せる
というだけのノードです。msg.payloadの値はそのままなので、プロパティが追加される形っす。
package.json
開発用のディレクトリ data-check を掘って、npm initで作った package.json に手を加えたものが以下に。前回、mochaを使ったユニットテストを勉強したというのに、今回は test のところ、手抜きです。mochaも練習しないとな。
{ "name": "jhalfmoon-data-check", "version": "1.0.0", "description": "Node-RED node, check data limits and so on.", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "J.Halfmoon", "license": "ISC", "node-red": { "nodes": { "lower-case": "data-check.js" } } }
data-check.js
さて、処理の本体であるJavaScriptファイルです。以前のデータの最大、最小、データ点数などを履歴を残しておかないことには何もできません。そのためノードの context を使いたいと思ったのです。しかし functionノード のコンテキストの説明を読んだら、自作ノードではfunctionノードのように定義済みのコンテキスト変数は存在しないとあります。以下のページを読んで変数を作るところから始めよと。
上記を参照させていただきながら書いたスクリプトが以下に。
module.exports = function(RED) { function DataCheckNode(config) { RED.nodes.createNode(this, config); var node = this; node.on('input', function(msg) { var nodeContext = this.context(); var nData = nodeContext.get('nData')||0; var minData = nodeContext.get('minData')||Number.MAX_VALUE; var maxData = nodeContext.get('maxData')||-Number.MAX_VALUE; var inputData = Number(msg.payload); if (!isNaN(inputData)) { nData++; if (inputData > maxData) { maxData = inputData; msg.DATAMAX = maxData; nodeContext.set('maxData', maxData); } if (inputData < minData) { minData = inputData; msg.DATAMIN = minData; nodeContext.set('minData', minData); } msg.NDATA = nData; nodeContext.set('nData', nData); } node.send(msg); }); } RED.nodes.registerType("data-check", DataCheckNode); }
data-check.html
ノードの「見た目」を左右するhtmlファイルが以下に。今回は前々回のサンプルスクリプトをコピペして一部のお名前などを書き換えただけ。
<script type="text/javascript"> RED.nodes.registerType('data-check', { category: 'function', color: "#fdebd0", defaults: { mane: {value:""} }, inputs:1, outputs:1, icon: "file.png", label: function() { return this.name||"data-check"; } }); </script> <script type="text/html" data-template-name="data-check"> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> <script type="text/html" data-help-name="data-check"> <p>Checking MIN/MAX values in the data flow.</p> </script>
自前ノードのインストール
上記3ファイルの作成後、自前ノードのインストールは .node-redディレクトリ内にて
$ npm install /devノードへのPATH/dev/jhalfmoon-data-check
インストール後、node-redを再起動。
$ node-red-restart
動作確認用フロー
「とりあえず」な動作テストのためのフローが以下に
-
- Injectノードでタイムスタンプを送る(動作の切っ掛け)
- randomノードは切っ掛けもらったら乱数を生成して流す
- data-checkノードは上記で決めた動作をする
- debugノードはmsgの内容をデバッグウインドウへダンプ
random ノードの設定が以下に。上流からmsgが到来する度に実数(double型だと思います)0から1範囲の乱数を1個生成。
念のため、自前 data-checkノードのプロパティ画面が以下に。Nameも設定してません。
動作確認
まず乱数1個目を送った後の様子です。payloadに0.3031…という数値が到着してます。同時に途中のdata-checkノードが追加で載せたプロパティ DATAMAX、DATAMIN、NDATAも到着してます。初回データなのでMAXもMINも同じデータとなってます。
つづいて2個目。今度は0.8547… です。DATAMAXが更新されてます。そしてNDATAは2と。一方DATAMINはそのままなのでプロパティは追加されません。
3個目、0.2317… とな。こんどはDATAMINが更新されました。NDATAは3とな。
このようにdata-checkノードをデータの流れに挟みこんでおけばMIN/MAXは監視できると。次回はも少し機能を拡張したいデス。