Node-RED obniz ノードの起動時の処理はノード内の初期化処理に書いたほうが良いというメモ

この記事は obniz Advent Calendar 2020 11日目の記事です。

Node-RED obniz ノードの起動時の処理はノード内の初期化処理に書いたほうが良いというメモです。

気づいた流れ

image

このようなフローがありまして I2C のデバイスを連携しています。inject ノードで起動後 1 秒待って、接続後に該当する処理を実行するようにしています。

image

これが、ローカルの Node-RED だとうまく動くものの、なぜか enebular や IBM Cloud で動かすときに、このように "TypeError: Cannot read property 'clear' of undefined""Error: i2c0 is not started" といったエラーが出るようになっていました。

[{"id":"4125079.4431ff8","type":"inject","z":"12059dc8.9fee32","name":"起動時","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":380,"y":120,"wires":[["9b489c5f.6a5c2"]]},{"id":"9b489c5f.6a5c2","type":"obniz-function","z":"12059dc8.9fee32","obniz":"b0d84422.4c91f8","name":"obniz 準備","code":"obniz.display.clear();\r\nobniz.display.print(\"Hello World\");\r\n\r\n// 黒:0番\r\nobniz.io0.output(false)\r\n// 赤:1番\r\nobniz.io1.output(true)\r\n\r\nobniz.i2c0.onerror = function(err) {\r\nconsole.error(err)\r\n}\r\n\r\n// 接続が整うまでに待ち時間が必要\r\nawait obniz.wait(100);\r\n\r\n// I2C接続\r\nobniz.i2c0.start({mode:\"master\", sda:2, scl:3, clock:400000 });","x":590,"y":120,"wires":[[]]},{"id":"b0d84422.4c91f8","type":"obniz","z":"","obnizId":"0000-0000","deviceType":"obnizboard","name":"","accessToken":"","code":""}]

検証のためフロー JSON を残しておきます。

どうも、obniz の接続が、inject ノードで起動後 1 秒待っても、準備が出てきていなくて、主要な関数が呼び出せてない。obnizのオブジェクトはなさそうという感じですね。なので I2C の宣言もコケている。なるほど。

obniz ノードの起動時の処理はノード内の初期化処理に書いたほうが良い

はい。表題の通りです。起動時の処理はノード内の初期化処理に移したら解決できました。

image

見た目上、全く一緒ですが、中身は変わっています。

image

obniz ノードが変わっています。

image

もともとのobniz ノードでは、obniz-functionノードのコード欄で実行して inject ノードで絡めることで Node-RED の起動後のきっかけ(1秒後)に動くようになってました。

image

このコードを、まるっと切り取ります。obniz-function ノード側からはなくなります。このコードを obniz ノード自体の設定に移動します。

image

こちらの赤枠で囲われている鉛筆マークをクリックします。

image

obniz ノードの各デバイスの設定画面になるので初期化処理の欄にペーストしてコードを移動します。こうすることで、正常に obniz が接続された後に初期化されるのでうまく動くようになりました。obniz repeat も初期化後に動作するので期待通りの動作になりました。

image

この確信が得れた段階で、CambrianRobotics 木戸さんに直接質問してみたところ、

「合ってますよー!」

とのことで、今後はこの理解でいきます!

[{"id":"4125079.4431ff8","type":"inject","z":"12059dc8.9fee32","name":"起動時","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":380,"y":120,"wires":[["9b489c5f.6a5c2"]]},{"id":"9b489c5f.6a5c2","type":"obniz-function","z":"12059dc8.9fee32","obniz":"b0d84422.4c91f8","name":"obniz 準備","code":"","x":630,"y":120,"wires":[[]]},{"id":"b0d84422.4c91f8","type":"obniz","z":"","obnizId":"0000-0000","deviceType":"obnizboard","name":"","accessToken":"","code":"obniz.display.clear();\r\nobniz.display.print(\"Hello World\");\r\n\r\n// 黒:0番\r\nobniz.io0.output(false)\r\n// 赤:1番\r\nobniz.io1.output(true)\r\n\r\nobniz.i2c0.onerror = function(err) {\r\nconsole.error(err)\r\n}\r\n\r\n// 接続が整うまでに待ち時間が必要\r\nawait obniz.wait(100);\r\n\r\n// I2C接続\r\nobniz.i2c0.start({mode:\"master\", sda:2, scl:3, clock:400000 });"}]

うまくいったフローを残しておきます!