Node-RED Advent Calendar 2018の22日目の記事です。
非同期でやってきたJSONを1つにまとめる話をします。
「そんなの当たり前だろ」というツッコミが聞こえてきそうですが、個人的に地味に悩み、かつ、かなりシンプルに解決できたので記事にしました。誰かの何かの役に立てば幸いです。
#動機:別々のAPIの結果を集約したかった(Wio Node)
Wio NodeというGrove(刺すだけで使えるセンサ)を刺すだけで簡単にAPIを立てられるモジュールがあり、スイッチサイエンスにて買ってみました。
Wio Nodeについてはこちらの記事がとても参考になります。
「Wio Node」で半田付けなしの電子工作!温度計作りでIoTはじめの一歩
Wio Nodeがあれば半田付けは勿論、RaspberryPiもブレッドボードも不要です。おうちのルーターとスマホがあればスマホアプリで設定するだけでAPIが立てられてしまいます!
そこでWio Nodeに温湿度気圧センサとダストセンサをそれぞれ繋げて部屋の快適さを取得できるAPIを作ることにしました。(左に温湿度センサ、右にダストセンサを繋げました。)
これで家から遠隔でエアコンのスイッチを入れた時、今これでどれぐらい部屋があったまっているかを即座に確認できます。またDBに蓄積し未来予測をすれば季節の変わり目にひいてしまいがちな風邪も事前に予防できるかもしれません。
しかしながら、WioNodeにて全てのセンサ情報を取得するためには温度、湿度、気圧、高度、ダストそれぞれ別のAPI発行しなければなりません。
これを全部集めてきて1個のJSONにして返してくれないかな、と思ったのが発端です。
実際に集約しようとしたフローが以下です。
JSONがバラバラに返ってくる…
#結論JOINノードでJSONを結合できた
「functionノードで待ち合わせてタイマーを作って…グローバル変数に書きながら溜まったらまとめて…など工夫しなければ…!!」と色々悩んでいたのですが、JOINノードの設定だけでシンプルに解決しました。
JOINノードは、配列などをSPLITノードで分割し、加工した上でJOINノードで戻す、といったことでよく用いられています。このJOINノードの設定を少し変えるだけでJSONの集約が簡単にできました。
バラバラだったJSONが1つにまとまった
#設定画面
これがそのJOINノードの設定画面です。
「Mode」がデフォルトでは「Automatic」になっています。SPLITノードと組み合わせる時はそのままで良いのですが、今回は「manual」に変更します。
また、「to Create」がデフォルトでは「a String」になっていますが、これを「a merged Object」に変更します。
「After a number of message parts」は組み合わせたいJSONの数(今回は5つのセンサ)、
「After a timeout following a first message」はJOINを諦める時間を設定します。(Wio Nodeではそんなに待たされることはないですが念のため5秒ぐらいにしておきました。)
これにより、ひとつのJSONにまとめられたので、例えば不快指数(温度と湿度から求められる数値)などセンサ同士の計算もうしろのノードで即座にできました。また、このJSONをDBに入れれば検索取出しも楽になります。
今回の例はWioNodeのサーバから取った複数センサの集約でしたが、BLEやGPIO側で取ったセンサ値の集約や、気象情報など異なる外部のAPIの集約にも使えそうです。