Raspberry PiでBluetoothデータをコンテナ上から受信する

この記事のまとめ:
  • Raspberry Pi上でDockerコンテナを動かし、そのコンテナからBLE (Bluetooth Low Energy) 対応のセンサーデバイスからブロードキャストされる信号を受信する方法をまとめています。
背景

前回、前々回の記事に引き続いて家の中の温湿度を可視化するためにRaspberry PiとBluetooth対応の温湿度センサーを使ってシステムを構築しようと思います。

今回はついにXiaomiの温湿度センサーが届いたので実際にデータが受信できるか試してみます。ただ試すだけでなく、Dockerコンテナで動作させたいと思います。

Raspberry PiでDockerコンテナを動かすということ

Raspberry PiのCPUはarmベースです。つまり、CPUの命令セットがIntel命令セットでなく、arm命令セットです。DockerコンテナはIntel命令セットのカーネル上で開発されているため、Dockerコンテナといえど、ほとんどのコンテナ、というよりもソフトウェアが動かないと思ったほうがよいです。

従ってベースイメージからarm命令セット用に開発されたDockerコンテナを探してきて使う他ありません。

ベースイメージとしてどのようなものが使えるか少し探してみましたが下記あたりが使えそうです。どちらも125MB程度と容量も小さめです。

参考記事

購入したBluetooth対応温湿度センサーについて

購入したセンサーですが、正式名称がよくわからないのですがXiaomi製のスマートホームのラインナップの一つのようで、AliExpressから調達しました。

1つあたり1200円程度でこの手の製品の中では安いほうだったので4つセットで購入しました。単四電池一本で駆動し、バッテリー寿命は1年のようです。説明書も中国語でホームページを見てもその他細かい仕様はよくわかりません。Xiaomi製というだけで、それなりに品質は高いものだろうと思っています。

一応中国語のホームページはこちらです。

ただただ、BLEブロードキャストで温湿度情報を無線で取得できるだけでなく、BLEにつながなくてもLCDで温湿度とバッテリー残量が見れてこの値段はお買い得です。

BLEブロードキャストについては下記の記事などでよくわかると思います。

早速実装

今回これを不安もなく買えたのはすでにこのセンサーのデータをRaspberry PiのBluetoothで受信し、測定結果が取得できたという記事があったためです。それがこちらです。

基本的にはこちらの記事に従って、Dockerfileを作成しました。

FROM balenalib/rpi-raspbian
 
RUN apt-get update && apt-get install -y \
    python3-dev \
    python3-pip \
    git \
    libglib2.0-dev \
    bluez
 
RUN pip3 install bluepy datetime
 
WORKDIR /app
RUN git clone https://github.com/hassiweb/mitemp.git
RUN git clone https://github.com/ChristianKuehnel/btlewrap.git btlewrap-git
RUN mv /app/btlewrap-git/btlewrap /app/mitemp/
RUN rm -rf /app/btlewrap-git
 
CMD ["bash"]
データ受信用Pythonファイルの変更点

データ受信用のPythonファイルは ratcashdev/mitemp を使っていましたが2点変更が必要だったため、hassiweb/mitemp として変更したものを置き直しています。

変更点は下記の通りです。

  1. XiaomiのBluetoothセンサーのMACアドレスの追加
    • Bluetoothからデータを取得するPythonスクリプト demo.py を実行する際、対象センサーの指定にMACアドレスを使うのですがMACアドレスのベンダーコードでアドレスがフィルタリングされています。ただし、今回私が購入したセンサーのMACアドレスが含まれていませんでしたので追加しました。
  2. JSONファイルで保存するPythonスクリプトの追加
    • demo.py では標準出力にしか結果が表示されません。今後の利用のためにJSONファイルとして指定した場所に保存・追記するPythonスクリプト mitemp.py を追加しました。
MACアドレスの検索

まずはセンサーデバイスを特定するためにデバイスのMACアドレスが必要です。hcitool というツールを使って周囲に飛び交っているBluetoothデバイスのMACアドレスとデバイス名を表示できますのでこれを使うことで判別できます。

下記のコマンドを打つと次のように表示されます。「MJ_HT_V1」というデバイスがXiaomiのセンサーです。

$ sudo docker run --rm -it --net host hassiweb/mitemp-container hcitool lescan
LE Scan ...
58:2D:34:**:**:** MJ_HT_V1
4C:65:A8:**:**:** MJ_HT_V1
データの受信・表示

MACアドレスもわかったのでデータを受信してみます。 下記のコマンドで実行すると、次のようにデータを受信し、そのデータが表示されます。上からファームウェアバージョン、デバイス名、バッテリー残量、温度、湿度です。

$ sudo docker run -it --net host hassiweb/mitemp-container python3 mitemp/demo.py --backend bluepy poll 58:2D:34:**:**:**
Getting data from Mi Temperature and Humidity Sensor
FW: 00.00.66
Name: MJ_HT_V1
Battery: 76
Temperature: 28.1
Humidity: 51.0
データの保存

この情報をJSONファイルに保存するためのPythonスクリプトを動かしてみます。

sudo docker run -it --net host -v /home/pi/Docker/TempSensor/data:/data -v /etc/localtime:/etc/localtime:ro hassiweb/mitemp-container python3 mitemp/mitemp.py --backend bluepy poll 58:2D:34:**:**:** /data
Getting data from Mi Temperature and Humidity Sensor
FW: 00.00.66
Name: MJ_HT_V1
Battery: 65
Temperature: 25.8
Humidity: 59.0

タイムスタンプをキーとしたJSONファイルで保存するようにしました。コンテナ実行時にホスト側にJSONファイルを引き渡すためにボリュームのバインドと、タイムスタンプのタイムゾーンをホスト側に合わせるためにボリュームのバインドをしています。

また、引数として、上記の demo.py の引数に加え、JSONファイルの保存先を追加します。

cat data/58\:2D\:34\:**\:**\:**.json
[{"2019/06/08 19:23:23": {"MAC": "58:2D:34:33:D4:6B", "Temperature": 25.8, "Humidity": 59.0, "Battery": 65}}]

ちゃんと保存されていますね。

参考記事


今回は以上です。 最後まで読んでいただき、ありがとうございます。

次回はこのJSONファイルをInfluxDBに挿入し、Grafanaで可視化します。


関連記事



コメント

このブログの人気の投稿

LinuxでのnVidia GPUのオーバークロック・電力チューニング方法

PythonでPinterestのPin (画像)の検索結果を取得する

ネットワーク越しの RTL-SDR で SDR# を使う方法