2015年12月15日火曜日

Fluent-bit と XBee で作るセンサーネットワーク

この記事は Treasure Data Advent Calendar 2015 の 15日目です。
前々日の記事:Jupyter から見た Treasure Data の使い方
前日の記事:
翌日の記事:


6月に開催された LinuxCon 2015 Tokyo で Treasure Data のエンジニアが Fluent-bit を紹介していました。 Fluent-bit とは、 Fluentd のデザインを継承した、組み込み用途向けの情報収集ツールだそうです。

http://fluentbit.io/


ただ、その時点では利用できる Input プラグインが限られており、そのノードのシステム情報などの取得が中心でした。 XBee 対応もモック状態でしたので、適当にいじって動くようにしてみました。今回は in_xbee がどんな感じに動くかを紹介します。いま Fluent-bit で実現できるすべての入力を紹介します。


1. Fluent-bit + XBee でできること


Fluent-bit は、 Treasure Data 社が作っている、組み込み Linux 向けの IOT データコレクタで、各種センサからの値を取り込むためのツールです。取り込んだデータは、 Fluentd へ送信したり、もしくは Treasure Data 社のサービスへ送り蓄積できます。インプット/アウトプットのモジュールはプラグイン型となっているため、新たなインプットやアウトプットに対応することも可能です。以下は Fluent-bit プレゼンテーションで示されている概要です。

 

XBee は Digi International 社による無線モジュールで、 ZigBee (802.15.3) や WiFi(802.11) など様々なタイプのものがあります。特に、 ZigBee 規格はセンサネットワークを構築する用途に向いています。Fluent-bit から XBee を実際に扱えるような Pull Request をマージしてもらいましたので、いまだと XBee をデータソースとして使えます。



 

XBee にはいくつかの種類がありますが、どのモデルでも下記の入力が扱えます。
  • デジタル/アナログ信号を一定間隔、もしくは変化があったときに送信
  • 接続されたコンピュータ(マイコンやPC)からのシリアル通信内容により送信
今回は、 Fluent-bit と XBee を使ってデータを収集するしくみを作る例、マイコン(Arduino)からFluent-bitにデータを送信する方法を紹介したいと考えています。


2. Raspberry Pi 2 で Fluent-bit を動かす


 XBee との連携について説明する前に、 Raspberry Pi 2 上の Raspbian で Fluent-bit を動かすための最低限の方法について説明したいと思います。

Fluent-bit を GitHub からクローンしてきます。本記事の公開時点では最もあたらしいリリースである v0.5.1 がよいでしょう(私は maser を使いました)。 Fluent-bit をコンパイルするには下記の要領で作業します。


 コンパイルが成功したら下記の要領で動作確認が可能です。

または、下記要領で Fluentd へのログ送信も確認できます。 Fluentd へは "fluent_bit" タグで送信されますので、 Fluentd の設定を済ませておいてください。


3. はじめての XBee


では、 Fluent-bit で XBee を使って情報を集約するために必要なモジュール、部品を揃えていきたいと思います。今回は秋月電子で揃えられる部品で実装しますが、同等品などでも構いません。



今回はXBee Series 2 モデルを 2 台準備しました。

備考:
  • XBee用シリアルインターフェイスは利用前にハンダ付け作業が必要です。
  • XBee用シリアルインターフェイスは最低1個あれば本記事の作業を行えますが、初めてXBeeを扱う場合など、疎通を確認する段階で2個あると便利です。
  • 本稿執筆時に使用したXBeeモジュールはSeries 2、もしくはXBeeZBと呼ばれるモデルですが、XBee Series 1, XBee WiFiなども(たいして変更なく)利用可能と思われます。
  • 相互通信のためには同じシリーズを利用する必要があります。たとえばXBee S1とXBee WiFi, またXBee S2の間は相互通信できません。
  • XBeeのアンテナタイプには外付け、アンテナ付きタイプ、PCBアンテナ(基板に内蔵)タイプがあります。アンテナ付き、もしくはPCB対応がよいでしょう。


エンドポイント側 XBee の設定 


エンドポイント(センサデバイス)側として使用する XBee モジュールを USB インターフェイスボードに装着し、 USB ケーブルで作業用 PC に接続します。設定は XCTU と呼ばれるツールを使用します。 XCTU は Digi International 社のサイトから入手してください。紹介するスクリーンショットは OS X 版のものです。

XCTU Software - Product Detail - Digi International
http://www.digi.com/support/productdetail?pid=3352

XCTU で XBee モジュールに End Device API のファームウェアをロードし、下記設定値をプログラムします。




 


 

 


コーディネータ側 XBee の設定


同様に、コーディネータ(Raspberry Pi 2)側として使用する XBee モジュールも、先と同じ要領で設定を行います。こちらのファームウェアは Choordinator API のファームウェアをロードし、下記の設定値をプログラムします。








この時点でエンドポイント用 XBee の電源がオンであれば、5秒毎にデータが送られてきているはずです。ターミナルのアイコンでコーディネータ側 XBee のシリアルポートに接続すると、エンドポイント側から送られてきた IO Data Sample RX Indicator というパケットが見えるはずです。




エンドポイント側からのパケットが届いていることが確認できたら、XCTUを終了し、 USB ケーブルを抜きます。


4. Fluent-bit とコーディネータ側 XBee の接続 


コーディネータ用XBeeをRaspberry Pi 2に接続します。 USB ケーブルで Raspberry Pi 2 に接続すると、 /dev/ttyUSB0 もしくは相当のデバイス名で認識されるはずです。 FTDI の USB Serial ドライバがないとダメですのでカーネルモジュールを削ってしまっている場合はビルドしてロードしてください。


Fluent-bit 設定ファイルの作成


設定ファイル xbee.conf を作成します。



※ XBeeLogLevel を設定した場合は、 XBee の通信に関する細かなログが表示されるようになりますので、うまく動作しない場合にはコメントアウトを解除して試してみてください。


Fluent-bit の起動と XBee パケット 受信確認


Fluent-bit を起動し、実際に XBee のパケットが拾えるか確認してみます。特に設定をしない限り、/dev/ttyUSB0 は root:dialout の権限になっていますので、 sudo を使って root 権限で動作させます(お使いのユーザを dialout グループに所属させてもよいでしょう)。


起動後、XBee エンドポイント側からの定期送信パケットが表示されれば、ここまでは OK です。もしうまく表示されない場合は、 XBeeLogLevel のコメントアウトを解除して、 XBee の受信処理などのメッセージが出力されるか等から、表示がされない原因を切り分けます。


エンドポイント側 XBee からデジタル信号を入力する




 GND ピンと DIO1 ピンをショートさせる "DIO1" として 0 が送られてきます。 DIO1 ピンに 3.3V かけると 1 が送られてきます。たとえば、以下のようなデータが Fluent-bit に出力されます。5秒おきのポーリング結果に加えて、ピン状態が変化したタイミングに特定ピンへのデータが届いているためこのような表示になります。

実際にはドアのスイッチを接続したりすることになるでしょう。たとえばトイレ個室のドア開閉状況を Fluentd で収集し Kibana などに投げてやればトイレのビジー率などをグラフ化できるでしょう。


エンドポイント側 XBee からアナログ信号を入力する


次にアナログピンの実験をしてみましょう。 XBee には、 0V 〜 3.3V の範囲で、どれぐらいの電圧がアナログピンにかかっているかを検出する ADC 機能があります。アナログタイプの照度センサなどのデバイスを使えば、状態を電圧として XBee のアナログピンに入力することができます。

3.3V 端子と AD0 端子を繋ぎ、 Fluent-bit の出力をみると AD0 が 1023 になっています。逆に、 GND 端子を AD0 端子に繋いでみます。すると、今度は AD0 が 0 に近い値になります。 AD0 に 3.3V をあらためてかけると、また AD0 の値が 1023 に戻ります。 実際には日照センサなどを接続することになるでしょう。


入力したデータの取り扱い


Fluent-bitでデータが入力できたら、 Fluentd によって Treasure Data Serivce 、もしくは Fluentd を介してお好きなミドルウェアに集約することができます。


5. XBee meets MCU


ここまでは、 XBee 自体の機能だけを使い、デジタル/アナログピンの状態をを収集しました。しかし、実際には、センサを動かすためにマイコンが必要であったり、またはセンサからの入力値を送信する過程でマイコンで処理をしなければならない場合も多いでしょう。今回は、そのような状況を想定し、 Arduino を使って情報を収集し、 XBee モジュールを介して Fluent-bit に送信するセンサノードを試作してみます。

今回使用する Arduino Duemilanove は 2010 年頃に流通していたモデルで現在は見かけませんが、現在の Arduino UNO R3 相当品だとお考えください。


in_xbee プラグインが受け取れる MessagePack フォーマット


in_xbee プラグインは、以下の形式で MessagePack でシリアライズされたペイロードを受け取れます。
  • [ time, { key => val, ... } ]
  • { key => val, ... }

タイムスタンプがついていない MessagePack ペイロードの場合 Fluent-bit が受信した時刻がそのペイロードの時刻となります。センサノードやマイコンには、現在の時間を扱うリアルタイムクロック(RTC)が搭載されていないこともしばしばです。時刻が分からないノードの場合は Fluent-bit 側でタイムスタンプを付加させることができます。


サンプルの概要


Arduino と XBee 、そして温湿度センサを使って、 MessagePack でシリアライズしたデータを送信し、 Fluent-bit で受け取るサンプルを作ってみます。
  1. Arduino は I2C バスを介して温度センサ AM2320 から温度、湿度情報を読み取ります。
  2. Arudino は 温度、湿度情報を MessagePack でシリアライズします。
  3. Arudino はシリアライズしたデータを XBee でブロードキャストします。
  4. Fluent-bit で先の MessagePack を受信します。
Arduino から I2C デバイスを制御するには wire という標準ライブラリがありますが、 AM2320 をコントロールするには不十分だったため SoftI2CMaster と呼ばれる別のライブラリを利用しています。取り込んだ値は下記構造で MessagePack でシリアライズします。

{ "degC" => 23.0f, "humidity" => 40.0f }

ワンチップマイコンでは 16bit どころか 8bit アーキテクチャのものも多数あり、またモノによっては POSIX どころか malloc() すら標準提供されていないものも多くあります。また、マイコンによっては浮動小数点フォーマットが IEEE754 ではないとかの機種依存事項もあります。このため msgpack-c のようなライブラリを MCU で使うには、いくらかハードルがあります。

このような環境を想定した MessagePack 実装として、ワンチップマイコン向けの msgpack-mcu を試作しました。 msgpack-mcu は GNU C コンパイラやマイコン向けのベンダ製コンパイラでなんとなくコンパイルでき、各種マイコンで利用できることを想定しており、別に性能もコードもすごくありませんのであしからず。

MessagePack でシリアライズされたデータは XBee を介してコーディネータに送信します。今回は Aruduino スケッチは XBee の API モードでデータをブロードキャストする最低限の実装となっています。


Arduino への XBee, 温度センサの取り付け


Arduino と温湿度センサ、XBeeをArduinoに接続していきましょう。ブレットボードを使えば、半田付け作業なしで回路の試作が可能です。今回はブレットボード上に温湿度センサとXBeeを載せます。下記の要領で SDA/SCL を AM2320 へ、 Arduino の TX を XBee の TX に接続します。



Arduino は 5V でデジタル信号を扱いますが、 XBee は 3.3V のデジタル信号を扱います。 XBee に Arduino の信号をそのまま入力すると死んでしまいますので、5V ←→ 3.3V のレベル変換が必要です。今回は Arduino (5V) → XBee (3.3V) ですのでレベル変換 IC などは使わずに抵抗を利用した分圧で済ませます。 5V を 3V に落とすため、抵抗の比率を1:2にします。

 


スケッチをArduinoへアップロード


以下に AM2320 から I2C で値を読み出して MessagePack でシリアライズし、 XBee API を使ってブロードキャストするサンプルを示します(SoftI2CMasterおよびmsgpack-mcuが必要です)。


このスケッチを Arduino にプログラムしてシリアルポートを見ていると、この配線をした状態であれば Arduino の起動から2秒後に { "i2c_init": 1 } という出力が見えるはずです。すべてがうまく行っていれば温度情報が数秒ごとに MessagePack over XBee API でブロードキャストされます。




Fluent-bitでの受け取り確認


先の Arduino から送られてきた MessagePack ペイロードが Fluent-bit の in_xbee に入力されると、次のようになります。


この表示が得られれば、 XBee を介して Fluent-bit が MessagePack のデータを受信できているはずです。あとは、お手元の Fluentd の Forward ポートへ転送してあげるだけです(もちろん Treasure Data Service に送るのもよいでしょう!)。


セキュリティ上の注意


今回の記事では、データの暗号化を行っていません。実際の利用にあたってはデータの暗号化、また XBee モジュールの無線出力の調整などが必要になるかと思われます。 XBee モジュールは AES による暗号化機能を搭載していますので活用してください。


(おまけ) TWE-Lite


参考までに、 XBee は無線モジュールであり、全モデルに共通して”しっかりしたマイコン”は付いていません。このため何かしようとするとすぐにマイコンを併用することになります。そうなると部品点数が増えますし配線も面倒です。

ここで TWE-Lite がちょっと便利です。モノワイヤレス(株)が販売する TWE-Lite は XBee の別メーカー版のようなかんじで、 ZigBee ベースでメッシュネットワーク ToCoNet が構成できる上に 32 ビットのマイコンも搭載されており、エンドポイントでちょっとしたプログラムを走らせるのに向きます。ZigBee と 32bit マイコンがワンパッケージに収まっていて 2000 円以下で入手できますので、安くセンサネットワークを作るにはアリだと思います。ちょっとした試作であれば TWE-Lite DIP を使うとブレットボード上で作業できます。



当然 TWE-Lite は XBee の API をしゃべるわけではありません。そこで、わたしは個人的に、”ホストからみると TWE-Lite が XBee API を話すような”プログラムをコーディネータ相当の TWE-Lite に書き込んでいます。これを使うと Fluent-bit + in_xbee で ToCoStick (TWE-Lite + USB インターフェイス)が受信した ToCoNet のペイロードをあたかも XBee のネットワークで送られてきたかのように振る舞います。

一方、センサノード側の TWE-Lite DIP には先の msgpack-mcu などを組み合わせて温度センサなどから集めた情報を MessagePack にシリアライズし、 ToCoNet を介してコーディネータに送りつけるようプログラムしてあります。

上記2点のプログラムを組み合わせることで、少ない部品代と部品点数で XBee もどきノードを作り、データを収集して Fluentd + Kibana を動かしてみたのが下のスクリーンショットです。





 



6. まとめ 


今回は Fluent-bit と XBee ネットワークを通じて情報を収集する方法を紹介しました。本記事を通じて、 Fluent-bit どのような事ができるのか、また Treasure Data Service もしくは Fluentd を使ったデータ集約にあたって、Fluent-bit をどのように活用できるのか、イメージを掴んでいただけたのではないかと思います。

Fluent-bitの登場により、Linuxが動作するコンピュータと、数千円で用意できるセンサノードを組み合わせて、(ほとんど)ソフトウェアを書かずにセンサーデータが集約できるようになりました。空間の環境情報、ドアの動きのモニタリングなど、皆さんのまわりで物理的な情報を集約する必要が出てきた場合には、 Fluent-bit の利用を検討してみてはいかがでしょうか。


この記事は Treasure Data Advent Calendar 2015 の 15日目です。
前々日の記事:Jupyter から見た Treasure Data の使い方
前日の記事:
翌日の記事:

0 件のコメント:

コメントを投稿