こんにちは、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 アプリケーション接続」を参照ください。

導入方法

大まかな流れ

  1. IoT Visualization の IoTF API 1. v2 に対応したソースコードを入手する
  2. Bluemix で Node.js のアプリを作成する
  3. 2.で作成したアプリに IoTFサービスをバインドする
  4. ソースコードを展開する
  5. 動作確認

実際の手順

今回は手っ取り早く進めるために、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」を選択してください。

d7c6cab9-ea5a-eb72-baf9-ae6c9389b60a

Node.js アプリを選び、任意のアプリ名を入力して作成します。

5b0137e0-73a7-85dc-f8c1-e0d7b6394e32

3. IoTFサービスをバインドする

アプリケーションが起動したら、アプリのダッシュボードから IoTFサービスをバインドします。

d6643e3f-0b1f-acda-5cc1-3ac779eced43

4. ソースコードを展開する

アプリのダッシュボードの画面右上にある「GITの追加」から、DevOpsサービスを作成します。

29019d7b-69dd-2afc-eff2-21de08679141

完了したら、同じく画面右上の「コードの編集」をクリックして、DevOpsサービスのコード編集画面へ移動します。

「ファイル」>「インポート」>「ファイルまたは.zipアーカイブ」を選択して、iot-visualization-0.2.0.zip をアップロードし、指示に従い unzip します。

b4289bc1-be7a-51b7-e44e-26dca96146ee

unzip 直後はこのようなファイル構成になります。

9b4cb768-e6e6-235f-2d50-e08427a233ac

そして、アプリケーションが動くように調整します。ここでは iot-visualization-0.2.0 配下をアプリケーションとして実行するように調整します。(本来は、適宜マージしてください~)最小限の調整で稼働させるにはこれ↓だけでよさそうです。

2decf03a-13f7-e741-d0e9-1bf0153e7873

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. 動作確認

デプロイが終わったらアプリケーションみてみましょう!

61b888f1-eca2-bfef-2693-17b8de047a00

しかし、アプリケーションを開くと、いくつかエラーが出ているかと思います…(;´・ω・) https:// ではなく http:// でアプリを開くことでエラーは抑えられます。(https で使えるほうがよいので確認中です。)

私の場合、作業時にIoTのモノを動作させてなかったので、過去データを見てみることにします。

デバイスを選択します。

229c3622-5e80-0c40-5a00-58b8a8bbf537

過去データを選択し、表示条件を設定するとグラフが表示さます!(/・ω・)/

dada81ac-46e0-20d2-70ac-e1b13987514d

ただし、おそらくここでグラフは表示されない方は… データ構造の不一致による不具合であればデバッグして修正したので、トラブルシューティングをご参照ください〜

トラブルシューティング

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);

};

64737b45-c71f-33a2-50ec-bcb5575f155b

(※実験でカウントアップするだけのデータを送っているので、ただただ右肩上がりのグラフです。)

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);
}

これで、リアルタイムのグラフも表示されます。

fba8b233-70c1-5492-9502-03493e2abc86

ボタン押したのがリアルタイムにグラフに表示されるので、ちょっと感動です!

Epilogue – 終わりに

APIのバージョンと、データ構造に気をつければ、いとも簡単に IoT のデータを可視化することができました!

実感が湧いていいですね~!(/・ω・)/

元記事はこちら

Check! Bluemix で IBM IoT Foundation のデータを可視化しよう!(リアルタイムと履歴表示)