SwitchBot温湿度計をGrafanaで可視化
Bluetooth で通信できる”SwitchBot 温湿度計”を利用して、Go で温湿度を取得・Prometheus へメトリクスを投げ込み、Grafana で可視化する話です。
説明書によると単 4 電池 2 本で 1 年持つらしいです。すごい。
一応 URL https://www.switchbot.jp/meter
BLE
よく出回っている他の温湿度計(tuya home 等)は、ほとんど BLE 通信が暗号化されており、利用者が自由に内容を参照することが出来ません。 生活周期だとかのパーソナルデータなので、当然といえば当然の流れなんですが寂しい。 そんな中、SwitchBot は技適付き・暗号化なしというプログラマーフレンドリーな仕様です。
ペイロード内容も公開されており、その内容は非常にシンプルです。
サービス UUID cba20d00-224d-11e6-9fb8-0002a5d5c51b
で 8byte 読んで、その内容をパースするのみです。
詳しい内容は以下を参照してください。
https://github.com/OpenWonderLabs/python-host/wiki/Meter-BLE-open-API
ハマった箇所としては、PassiveScan だと ServiceData を返さないようで、データを取得するためには ActiveScan を行う必要が有るということでした。 こちらの記事で記述されており非常に助かりました。
https://qiita.com/warpzone/items/11ec9bef21f5b965bce3
Go での記述
Python での取得コードは上の GitHub リポジトリで公開されているのですが、どうしても Go で書きたいという気持ちがあったので温湿度を取得するコードを Go で記述しました。 Prometheus へとストアしたいので、Exporter の実装も合わせて行っています。
https://github.com/kamijin-fanta/temperature-collector/blob/master/main.go
最初は BLE ライブラリに https://github.com/paypal/gatt を利用しようと思っていたのですが、ActiveScan を行う方法が無く、独自の HCI コマンドを送信するのも難しそうなので https://github.com/go-ble/ble を利用しています。
Prometheus, Grafana
Raspberry Pi 3 で動かしたかったので、 GOOS=linux GOARCH=arm GOARM=7
をつけてビルドを行い、以下のような雑な Systemd Unit ファイルを作成してデーモンとして動作させます。
#cat /etc/systemd/system/temperature-collector.service
[Unit]
Description=Temperature prometheus collector
After=network-online.target
[Service]
Type=simple
Restart=always
LimitCORE=infinity
ExecStart=/home/pi/temperature-collector_armv7
PermissionsStartOnly=true
StandardOutput=null
[Install]
WantedBy=multi-user.target
適当に Prometheus の設定も追記しておきます。
scrape_configs:
- job_name: "temperature"
static_configs:
- targets:
- hostname:2112
Grafana でダッシュボードを用意してやれば完成です。
温度計本体は、適当に袋を被せて室外に置いてみました。