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 でダッシュボードを用意してやれば完成です。

温度計本体は、適当に袋を被せて室外に置いてみました。