はじめに
プラットフォームにJava / Raspberry Pi 3Bを選択しましたので、この環境で各種センサーと通信するJavaライブラリを探します。
まず最初に、Bluetooth LEについてです。ここ数年、BLE通信でセンサーデータを取得できるデバイスが出てきています。今回、メジャーどころのテキサス・インスツルメンツ社のSensorTag CC2650を選択しました。CC2650は、温度、湿度、照度、気圧、角速度、加速度、磁気を測定できる、5cm x 4cm程度のボタン電池駆動型のBLEデバイスです。
CC2650の使い方は、以下の流れになります。
- CC2650(ペリフェラル)の電源を入れて、アドバタイズ信号を発信
- セントラルは、アドバタイズ信号をキャッチして、CC2650に接続(CC2650はアドバタイズ信号を停止)
- セントラルは、BLE GATTプロファイルを用いて、CC2650からセンサーデータを取得する
なお、CC2650は、アドバタイズ信号を発信し始めて3分の間に、どこからも接続されないと自動的に電源を切ります。なので、接続に備えるには、再度、電源を入れる必要があります。今回、アドバタイズ信号をJavaでキャッチするにあたり、BLE通信に対応したJavaライブラリとして、bluez-dbusを採用しました。
以前、試験的に、CC2650からセンサーデータを取得するために、Javaでコードを書いたことがありました。その時は、bluez-dbusは未だ無く、他にJavaでBLE通信するためのライブラリとして、ちょうどIntel TinyBがリリースされた頃でした。ただ、リリース間もないTinyBは不安定で、当時、BLEのNotification機能も使えませんでした。何より、bluezが公開しているdbusのI/F定義ファイルをC/C++のコードに自動変換して(1万行を超えるコードが自動生成)、これに更に手を入れてTinyBは作成されており、メンテナンス性はとても低そうに感じました。
BLEをdbus I/Fで使用する場合、dbus自体はUNIXドメインソケットの上で定義されているので、本質的には、このUNIXドメインソケットの部分だけがJNIで書かれ、その上で定義されるbluez用のdbusプロトコルは、このJNIを呼び出す形で実装するのがシンプルなのに、と思っていました。
当時は、仕方なくbluezの各種コマンドを常駐プロセスとして連携させるJavaのコードを書いて、凌いだことがあります。複雑なアーキテクチャで、ダサイなあと思いました。当時のコードは忘れましたが、このダサイ印象だけは今も残っています。
あれから月日は流れ、今では、BLEに対応したbluez-dbusなるライブラリが公開されています。Githubに書かれた開発者の動機を読むと、わたしが思ったのと同じようです。(まあ、そう思いますよね・・・)
そこで、今回はプライベートで、bluez-dbusを採用したシンプルなアーキテクチャでコードを書きました。前置きが長くなりましたが、本文は短いです。基本的に、Githubに書いた内容そのままです。詳細はコードを参照して下さい。
OSインストール
Raspberry Pi 3BのOSには、Raspbian Buster Lite OS (2019-07-10)を使用しています。このOSには、bluez-dbusが対応しているBlueZ 5.50が最初から入っており、改めて、BlueZをビルドする必要がありません。
Javaインストール
ARM版Linux用のJavaは幾つかあると思いますが、わたしはBELLSOFTのjdk11をapt-getで入れました。
# wget -q -O - https://download.bell-sw.com/pki/GPG-KEY-bellsoft | apt-key add -
# echo "deb [arch=armhf] https://apt.bell-sw.com/ stable main" | tee /etc/apt/sources.list.d/bellsoft.list
# apt-get update
# apt-get install bellsoft-java11
bluetooth-scannerとは
BLEアドバタイズ信号をキャッチするためのモジュールです。用途は、セントラルのBLE通信の範囲にBLEデバイスが入ったことを動的に認識することです。具体的には、CC2650が接近して、セントラルがその存在を認識し、接続するためのトリガーにします。
また、接続しているCC2650がセントラルの通信範囲から外れてBLE通信が切断され(アドバタイズ信号を再開します)、その後、再度、接近して、セントラルがアドバタイズ信号をキャッチして自動的にCC2650に再接続するトリガーとしても想定しています。
**bluetooth-scanner**の処理の肝は、dbus-javaが提供するAbstractPropertiesChangedHandler.java
をextends
したクラスを用意して、public void handle(PropertiesChanged properties)
を実装することです。詳細は、Githubのコードを参照して下さい。bluetooth-scannerの使い方のサンプルは以下の通りです。IScanHandler
interfaceを実装してScanProcess.java
のインスタンスを作成し、start()
を呼び出します。
import com.github.hypfvieh.bluetooth.DiscoveryFilter;
import com.github.hypfvieh.bluetooth.DiscoveryTransport;
import com.github.hypfvieh.bluetooth.wrapper.BluetoothDevice;
import io.github.s5uishida.iot.bluetooth.scanner.IScanHandler;
import io.github.s5uishida.iot.bluetooth.scanner.ScanData;
import io.github.s5uishida.iot.bluetooth.scanner.ScanProcess;
public class MyScan {
public static void main(String[] args) throws IOException, InterruptedException {
Map<DiscoveryFilter, Object> filter = new HashMap<DiscoveryFilter, Object>();
filter.put(DiscoveryFilter.Transport, DiscoveryTransport.LE);
ScanProcess scanProcess = new ScanProcess("hci0", new MyScanHandler(), filter);
scanProcess.start();
}
}
class MyScanHandler implements IScanHandler {
private static final Logger LOG = LoggerFactory.getLogger(MyScanHandler.class);
@Override
public void handle(BluetoothDevice device, ScanData data) {
LOG.info(device.toString());
LOG.info(data.toString());
}
}
実行ログの例は以下の通りです。なお、行の先頭を省略しています。
MyScanHandler handle - BluetoothDevice [device=org.bluez:/org/bluez/hci0/dev_24_71_89_06_9D_82:interface org.bluez.Device1, adapter=/org/bluez/hci0, getBluetoothType()=DEVICE, getDbusPath()=/org/bluez/hci0/dev_24_71_89_06_9D_82]
MyScanHandler handle - [hci0] 24:71:89:06:9D:82 name:CC2650 SensorTag rssi:-63 txPower:0 date:2019-09-03 22:40:25.483
一連の記事
このシリーズは、以下の記事から構成されます。
- 動機とコンセプト
-
Bluetooth LEアドバタイズ信号をJavaでキャッチする(Bluetooth LE / bluez-dbus)(今回)
関連するGithubはこちら。 -
TI SensorTag CC2650から温度/湿度/照度などをJavaで取得する(Bluetooth LE / bluez-dbus)
関連するGithubはこちら。 -
MH-Z19BからCO2濃度をJavaで取得する(シリアル通信 / jSerialComm)
関連するGithubはこちら。 -
PPD42NSからPM2.5濃度をJavaで取得する(GPIO / Pi4J)
関連するGithubはこちら。 -
産業オートメーション機器の稼動情報をJavaで取得する(OPC-UA / Eclipse Milo)
関連するGithubはこちら。 -
簡易ツールにまとめる
関連するGithubはこちら。 - 後記
追記
[2019.11.16]
簡易ツールの最新情報は、こちらをご参照下さい。