こんにちは、cloudpack の @dz_ こと大平かづみです。
Prologue – はじめに
Bluemix のドキュメント「IoT サンプル – データの可視化」に、IBM Internet of Things Foundation (以下、IoT Foundation または IoTF ) のデータを可視化する方法が紹介されていたので試しました。
IoT Foundation のデータをどう扱うのかの見本にもなり、ちょうどよかったです。
以下は、ざっくりですが使用した際のメモです。参考になればさいわいです。
サンプルアプリ IoT Visualization
このドキュメントでは、 IoT Visualization という Node.jsアプリケーションを使って、 IoTF のデータを表示します。
- リアルタイムのグラフ表示
- 過去ログのグラフ表示
IoTF のデータはAPI や MQTT で提供されており、Bluemix のダッシュボードからバインドすることでアクセストークンを紐付けてくれます。 (便利!) また、別途アクセストークンを発行してそれを利用することもできます。
取得したデータは、javascriptでグラフ描画します。
データの種類 | 取得方法 |
---|---|
リアルタイム | MQTT |
過去ログ | HTTPS |
IoT Foundation からのデータ取得の方法
IoT Foundation からデータを取得するには、https ベースの API や、MQTT が使えます。
Internet of Things Foundation API を利用する
Internet of Things Foundation API は、IoTF に登録されたデバイスの管理やデータ・診断情報の管理、IoTFの組織に関する情報の取得などができます。
現在は バージョン 2 がサポートされています。
バージョン 1 も引き続きサポートすると書かれていますが、正常に動作しない場合があるのでご注意ください。実際に、ドキュメントに従ってダウンロードしたサンプルアプリではAPIがバージョン1で動かず、リポジトリからバージョン2に対応したソースコードを取得して対応しました。
MQTT で接続する
MQTT については、「メッセージング」に記載されています。
アプリケーションから MQTT に接続してパブリッシュ、サブスクライブする詳細については「MQTT アプリケーション接続」を参照ください。
導入方法
大まかな流れ
- IoT Visualization の IoTF API 1. v2 に対応したソースコードを入手する
- Bluemix で Node.js のアプリを作成する
- 2.で作成したアプリに IoTFサービスをバインドする
- ソースコードを展開する
- 動作確認
実際の手順
今回は手っ取り早く進めるために、DevOps サービス を利用します。
なお、Bluemix のだいたいの操作感や、Node.js と Express で構成されたアプリケーションが理解できる知識がある前提で手順を書きます。ご了承くださいませ。
1. IoT Visualization のソースコードを入手する
Release IBM IOT Foundation Cloud Registered Devices Visualization Sample v0.2.0 から、IoTF API v2 に対応したソースコードを取得します。
のちほど DevOps サービスにアップロードするときに便利なので、zip 形式の方を取得してください。(例: iot-visualization-0.2.0.zip
)
2. Bluemix で Node.js アプリを作成する
Bluemix ダッシュボードから 「Cloud Foundry アプリ」作成に進み、「WEB」を選択してください。
Node.js アプリを選び、任意のアプリ名を入力して作成します。
3. IoTFサービスをバインドする
アプリケーションが起動したら、アプリのダッシュボードから IoTFサービスをバインドします。
4. ソースコードを展開する
アプリのダッシュボードの画面右上にある「GITの追加」から、DevOpsサービスを作成します。
完了したら、同じく画面右上の「コードの編集」をクリックして、DevOpsサービスのコード編集画面へ移動します。
「ファイル」>「インポート」>「ファイルまたは.zipアーカイブ」を選択して、iot-visualization-0.2.0.zip
をアップロードし、指示に従い unzip します。
unzip 直後はこのようなファイル構成になります。
そして、アプリケーションが動くように調整します。ここでは iot-visualization-0.2.0
配下をアプリケーションとして実行するように調整します。(本来は、適宜マージしてください~)最小限の調整で稼働させるにはこれ↓だけでよさそうです。
package.json(参考)
{ "name": "NodejsStarterApp", "version": "0.0.1", "description": "A sample nodejs app for Bluemix", "scripts": { - "start": "node app.js" + "start": "node iot-visualization-0.2.0/app.js" }, "dependencies": { - "express": "4.12.x", - "cfenv": "1.0.x" + "express": "~4.2.0", + "serve-favicon": "~2.1.0", + "morgan": "~1.0.0", + "cookie-parser": "~1.0.1", + "body-parser": "~1.0.0", + "debug": "~0.7.4", + "jade": "~1.3.0", + "stylus": "0.42.3", + "express-session": "^1.8.1" }, "repository": {}, "engines": { "node": "0.12.x" } }
調整が終わったら、画面上部のデプロイアイコンから、アプリケーションをデプロイしてください。
5. 動作確認
デプロイが終わったらアプリケーションみてみましょう!
しかし、アプリケーションを開くと、いくつかエラーが出ているかと思います…(;´・ω・) https://
ではなく http://
でアプリを開くことでエラーは抑えられます。(https で使えるほうがよいので確認中です。)
私の場合、作業時にIoTのモノを動作させてなかったので、過去データを見てみることにします。
デバイスを選択します。
過去データを選択し、表示条件を設定するとグラフが表示さます!(/・ω・)/
ただし、おそらくここでグラフは表示されない方は… データ構造の不一致による不具合であればデバッグして修正したので、トラブルシューティングをご参照ください〜
トラブルシューティング
Historic Data のグラフが表示されない(データの数字(文字列)を認識しない)
IoTデータのパース処理で、値が数値でない場合は扱わないようになっていました。
私のデータ構造では、センサデータの値も “数字” (文字列) で送ってしまっていたので、数字も数値として認識するよう修正しました。私のデータに合わせてるので参考程度にご覧ください。
public/js/historian/historianGraph.js
this.displayHistChart = function(device,histData){ var seriesData = []; var counter = 0; var data = histData.events; for(var i = data.length-1 ; i>=0 ;i-- ){ var key = 0; for (var j in data[i].evt){ + // 数値である場合("数字"も含める) - if (typeof data[i].evt[j] !== 'string') { + if (typeof data[i].evt[j] !== 'string' || isNaN(parseFloat(data[i].evt[j])) === false) { if(i===data.length-1){ seriesData[key]={}; seriesData[key].name=j; seriesData[key].color = this.palette.color(); seriesData[key].data=[]; } seriesData[key].data[counter]={}; + // 数値に変換 - seriesData[key].data[counter].x = data[i].timestamp.$date/1000;// timestamp; - seriesData[key].data[counter].y = data[i].evt[j]; + seriesData[key].data[counter].x = parseFloat(data[i].timestamp.$date/1000);// timestamp; + seriesData[key].data[counter].y = parseFloat(data[i].evt[j]); key++; } } counter++; } this.drawGraph(seriesData); };
(※実験でカウントアップするだけのデータを送っているので、ただただ右肩上がりのグラフです。)
Live Data のグラフが表示されない(データの数字(文字列)を認識しない)
Live Data も試したところ、上記と同じ状況でデータが表示されなかったので、数字も数値にパースするように調整しました。
public/js/realtime/realtimeGraph.js
this.graphData = function(data) { var key = 0; var seriesData = []; var timestamp = Date.now()/1000; var maxPoints = 25; for (var j in data.d) { - if (typeof data.d[j] !== 'string') { + if (typeof data.d[j] !== 'string' || isNaN(parseFloat(data.d[j])) === false) { - this.graph.series[key].data.push({x:timestamp,y:data.d[j]}); + this.graph.series[key].data.push({x:timestamp,y:parseFloat(data.d[j])}); if (this.graph.series[key].data.length > maxPoints) { this.graph.series[key].data.splice(0,1);//only display up to maxPoints } key++; } } this.graph.render(); } this.displayChart = function(device,data){ var key = 0; var seriesData = []; var timestamp = Date.now()/1000; for (var j in data.d) { - if (typeof data.d[j] !== 'string') { + if (typeof data.d[j] !== 'string' || isNaN(parseFloat(data.d[j])) === false) { seriesData[key]={}; seriesData[key].name=j; seriesData[key].color = palette.color(); seriesData[key].data=[]; seriesData[key].data[0]={}; seriesData[key].data[0].x = timestamp; - seriesData[key].data[0].y = data.d[j]; + seriesData[key].data[0].y = parseFloat(data.d[j]); key++; } } this.drawGraph(seriesData); }
これで、リアルタイムのグラフも表示されます。
ボタン押したのがリアルタイムにグラフに表示されるので、ちょっと感動です!
Epilogue – 終わりに
APIのバージョンと、データ構造に気をつければ、いとも簡単に IoT のデータを可視化することができました!
実感が湧いていいですね~!(/・ω・)/
元記事はこちら
「Check! Bluemix で IBM IoT Foundation のデータを可視化しよう!(リアルタイムと履歴表示)」