IoTデータをMongoDBとMetabaseで可視化するためのTips


はじめに

はじめまして。Qiita初投稿です!!

センサーで収集した温度・湿度・気圧のデータをクラウドに飛ばして可視化したいと思いました。クラウドはAWS IoT CoreやAzure IoT Hubを使うのが手っ取り早いのですが、お金をかけないでやるために、Databaseと可視化ツール(BIツール)もOSSを使い自前で構築してみました。

使ったOSS

  • Database : MongoDB(v4.2.2)
  • BI Tool : Metabase(v0.33.5.1)

両方ともメジャーなOSSですので、使い方の解説はあちこちにありますが、MongoDB + Metabaseの組み合わせを解説した記事があまりなく、ドキュメントに書いてないハマりどころがいくつかありましたのでそのあたりを解説します。

全体構成

詳細は割愛しますが、以下のようにVM環境もOpenStackを使い、自宅サーバ上で構築しています。

データの流れ

  1. BME280(温度・湿度・気圧)+ ESP32からWi-Fiでデータを送信
  2. IoT-Hub & データブローカーのOM2Mがデータを受信
  3. 新しいデータが届くと、OM2Mがアプリ(ADN-AE)に通知(Notification)
  4. アプリでセンサデータを抽出してMongoDBに格納
  5. BI Tool(Metabase)でデータを可視化
  6. ついでに、M5Stackを使って最新データをモニターできるようにしてみた

MongoDBのTips

データの記述方法

以下のように、JSONを使いデータをキー・バリュー形式でフォーマットします。

{
    "Location" : "Outside", 
    "RSSI" : -55, 
    "TemperatureC" : 10.79, 
    "Humidity" : 79.7, 
    "PressureHpa" : 988.53, 
    "Battery" : 2.78, 
    "CreateDate" : "2019-12-26T21:29:59Z", 
}
  • JSONの「キー」はMongoDBの検索キーにもなりますので、簡潔で分かりやすい名前を付けます
  • 他の人が見ても分かるように名前に単位情報(TempretureC → 摂氏だよ)を入れると親切
  • データの収集時刻(CreateDate)はUTC時間をISO8601形式でフォーマット → UTCで格納しておけば、Metabaseがブラウザの設定に合わせたローカルタイムに変換して表示します
  • 収集時間に加えてセンサーの設置場所も入れておくとよい

MongoDBに日付を認識させる

NoSQL型のDBは、RDBのようにスキーマーを作って各データの属性を定義する必要がないのですが、MongoDBとMetabaseを連携するためには、日付だけは”このデータは日付だよ”という意味付けを行う必要があります。こうしておかないと、Metabaseから日付の範囲を指定したクエリを行った際に、「can’t convert from BSON type String to Date」といったエラーが発生し、データの取得ができませんでした。

そこで、MongoDBに日付データを格納する際には、日付をISODateオブジェクトにする必要があります。そのために、以下のようにサーバー上のアプリで、"CreateDate"からISODateを生成・追加してMongoDBに格納します。

{
    "Location" : "Outside", 
    "RSSI" : -55, 
    "TemperatureC" : 10.79, 
    "Humidity" : 79.7, 
    "PressureHpa" : 988.53, 
    "Battery" : 2.78, 
    "CreateDate" : "2019-12-26T21:29:59Z", 
    "isodate" : ISODate("2019-12-26T21:29:59Z")
}

ISODateの生成・追加は、JavaScriptでは以下のように記述できます

var isoDate =  new Date(jsonData.CreateDate);
jsonData.isodate = isoDate;
  • JSONデータから"CreateDate"フィールドを取り出し、この値を引数にしてDateを生成 → これでISODateになる
  • JSONデータに追加する

MetabaseのTips

Database nameなどの登録

MongoDBと連携するために、MetabaseのDatabase Admin画面で各種の登録を行います。その際の注意点は以下の通りです。

  • Database nameはMongoDBに書き込みを行った際に使用したDB名(コレクション名ではない)
  • Database usernameに加えて、Authentication Databaseを指定する → これを指定しないと認証エラーになり接続できません

MetabaseAdmin → DataModelでデーター毎の属性を設定できますが、特に設定する必要はありません。温度・湿度などは数値データ、isodateは日付情報として認識してくれます。

グラフのソース情報になるテーブルのカラムをいじってはいけない

これが一番ハマった点でした。

データをグラフ化する際は、以下のようにデータの一覧画面から、Visualizationボタンをクリックしてブラフの種類やX-Y軸に表示するカラムの指定を行います。この一覧のカラムは、MongoDBから取り出したキー情報をアルファベット順に並べているのですが、カラムを非表示にしたり表示順序を入れ替えることができます。

最初はこの一覧を見やすくするために、IDを非表示にして日付を左側に持ってきるなどの、表示のカスタマイズを行っていました。表示をカスタマイズした状態からグラフを生成すると、X軸に日付を指定した際に以下の問題がありました。

  • 日付は表示されるが、時刻を表示してくれない
  • バージョンによっては、X軸にIsoDateを指定させてくれない

すなわち、グラフのソース情報になるテーブルのカラムをいじってはいけないということです。こんなことドキュメントには書いてない!!(多分・・)です。

データ数が増えた際の注意点

Metabaseは、DBの登録件数が2000レコードを超えると、デフォルトでは最初の2000レコードを表示するようになります。そのためデータ量が増えた場合は、グラフを描画する際にフィルター条件を設定し「直近の1ヶ月分」など、クエリー範囲を指定する必要があります。

ダッシュボードのサンプル

収集データをグラフ化してダッシュボートに表示した画面の例を以下に示します。結構見栄えがよいグラフを表示してくれます。