前回の記事では、Arduinoで取得した気温と照明のセンサーデータをさくらのIoTでクラウドにアップして、WebSocketで見えるようにするところまで作業を進めました。
そのあと、MQTTも試してみたのですが、いまのところ、どうも上手く動きません・・・。
そこで、WebSocketで取得できるデータをIBM Bluemix上で動作しているNode-REDで処理してCloudantに蓄積するところまで、やってみました。
Bluemix上でNode-REDを動かす
BluemixではNode-REDが簡単に動作します。後でCloudant(NoSQLデータベース)も使うので、Internet of Things Platform Startarというボイラープレートで簡単に環境構築できます。
このボイラープレートでは、Node-REDの動作環境となるCloud Foundaryアプリの他、CloudantとWatson IoT Platformという2つのサービスが自動的に追加されます。
本当は、Watson IoT PlatformでMQTTを受信してCloudantに蓄積するという流れをNode-REDで作りたかったのですが、そこは断念・・・。
Cloudantに蓄積するNode-REDフロー
ざっと、こんな感じのフローをつくります。
arduino_sakura
というノードはWebSocketの受信です。msg.payload
にWebSocketで受信した内容(JSON)が入っているので、jsonノードでJavaScriptオブジェクトに変換します。
さくらのIoT PlatformのWebSocketは、実際の値がセットされているメッセージ以外に、接続維持用のメッセージも流れてくるので、switchノードで後者を捨てます。msg.payload.typeがchannels
は前者、keepaliveが後者のメッセージです。
convertファンクションが肝心です。下記のようなコードを書きます。
var temperature = null;
var light = null;
for (var i = 0; i < msg.payload.payload.channels.length; i++) {
var data = msg.payload.payload.channels[i];
if (data.channel == 0) {
temperature = data.value;
break;
}
}
for (var i = 0; i < msg.payload.payload.channels.length; i++) {
var data = msg.payload.payload.channels[i];
if (data.channel == 1) {
light = data.value;
break;
}
}
msg.payload = {
"module": msg.payload.module,
"datetime": msg.payload.payload.channels[0].datetime,
"temperature": temperature,
"light": light
}
return msg;
Arduino側からは、いくつかのデータをまとめてクラウドにアップする形になっているので、channelsが複数まとめて来るのですが、気温(channel:0)と照明(channel:1)の先頭だけを取得する形にしています。
最後のsakura_iotノードで、Cloudantに格納しています。
Bluemixのコンソール画面からアクセスできるCloudantダッシュボードを見ると、きちんとデータが格納されていることが分かります。