Switchbot Meterから温度・湿度を取得して、Muninで可視化するメモ

# 概要

Switchbot Meterから温度と湿度をLinuxサーバで取得して、Muninでグラフにしたメモです。


# Switchbot Meterとは？

SwitchBot社が販売している温湿度計です。見た目は単なるデジタル温湿度計ですが、同社のスマートリモコン製品と連携できたり、BluetoothやWebAPIで温度・湿度の値を取得することができたりと、アイデア次第で様々なことに利用できる製品です。
価格も定価で1980円と、この手の製品としては格安です。また、しょっちゅう10%引きや20%引きのセールをやっているので、安いときには1500円くらいから手に入ります。私はついつい4台購入してしまいました。

https://www.switchbot.jp/products/switchbot-meter

ちょっと余談ですが、私は以前から自宅でPCsensor社のUSB接続の温度計を使って自宅の温度をモニタリングしていました。

参考： USB温度計・湿度計で温度・湿度を可視化していた記事

https://shakemid.hatenablog.com/entry/2017/09/01/191753

それはそれでよかったのですが、USB接続なのでケーブル長に限界があり設置場所が限られました。また、自分で校正する必要があったので、管理が面倒でした。
Switchbot Meterはそれらの課題をクリアすることができ、自宅の温度をモニタリングしたい人にはぴったりの製品だと言えます。両者の違いをまとめると以下のようになります。欲を言えばUSB給電にも対応してほしかったですが、この価格でこの機能を実現しているのは驚異的だと思います。

||Switchbot Meter|PCsensor TEMPer|
|--|--|--|
|価格|1980円|1000～2000円|
|本体画面|あり|なし|
|API|Bluetooth, WebAPI（仕様公開）|USB（公式には仕様非公開）|
|校正|済|ユーザにて実施する必要あり|
|電源|単4電池2本|USB|


# Muninとは？

サーバやネットワーク機器の様々なリソースをグラフ化できるRRDtoolのフロントエンドです。2003年頃から開発され、2021年時点でもメンテナンスが続いている歴史のあるソフトウェアです。
柔軟なプラグインアーキテクチャを採用しているのが特徴で、サードパーティのプラグインも豊富にあります。今回私もSwitchbot Meter用のプラグインを作成しました。

https://munin-monitoring.org/

# Bluetooth編

## 必要なもの

Bluetooth経由でデータを取得するには以下のものが必要です。

- Switchbot Meter（Hubは必須ではありません）
- Switchbotアプリ（iOS/Android）
- Bluetooth(BLE) レシーバー

BluetoothレシーバーはBLEに対応した↓のような製品が使用できます。

https://www.amazon.co.jp/dp/B07NQ5YGDW/ref=cm_sw_em_r_mt_dp_dl_W3TBCK5S1F2RYN5Z172Q

BluetoothはClass2対応なら直線距離だと10～20mくらいは電波が届くことになっていますが、宅内では壁やドアの影響をそれなりに受けます。なるべくレシーバーからSwitchbot Meterまでの見通しがよい場所に設置するなどの工夫が必要かもしれません。

Switchbot Meterの商品ページに↓のような記載があり、これをそのまま受け取るとSwitchbot MeterはClass1で通信できるように読み取れますが、ほんとにClass1で通信できてるのかちょっと自信がありません。

```
※Bluetoothの通信距離は見通しの良い場所で最大120メートルです。
```

Class1に対応しているなら、↓のようなClass1に対応したレシーバーを使うと、感度が向上すると期待できます。Class1に対応した製品は少ないですが、BuffaloのBSBT4D105BKは手元のUbuntu 20.04の環境で動作しましたので共有します。

https://www.amazon.co.jp/dp/B07716SP6N/ref=cm_sw_em_r_mt_dp_7E5BG6GZ565H8WW3EZ1J?_encoding=UTF8&psc=1



## 事前準備

### Muninのインストール

munin, munin-node についてはすでに動作しているものとして進めます。
Redhat系やDebian系のLinuxなら、パッケージを使ってインストールするのが楽だと思います。

http://guide.munin-monitoring.org/en/latest/installation/install.html

### Bluetoothレシーバーの確認

Bluetoothを扱うのでなんらかのBluetoothレシーバーが必要になります。hciconfigコマンドで以下のようにHCIデバイスが見えていれば動作する可能性が高いと思います。

```
$ hciconfig
hci0:   Type: Primary  Bus: USB
        BD Address: 00:1A:xx:xx:xx:xx  ACL MTU: 310:10  SCO MTU: 64:8
        UP RUNNING
        RX bytes:10233604 acl:0 sco:0 events:313292 errors:0
        TX bytes:25868 acl:0 sco:0 commands:3310 errors:0
...
```

### Pythonモジュールのインストール

PythonでBluetoothを扱うのでbluepyモジュールをインストールしてください。
たとえばUbuntuなら以下のようなコマンドでインストールできます。

```
$ sudo apt install python3-pip
$ sudo pip3 install bluepy
```

## Muninの設定例

Muninのプラグインを作成して、本家のリポジトリにマージしてもらいました。

https://github.com/munin-monitoring/contrib/blob/master/plugins/sensors/switchbotmeterbt

このプラグインをmunin-nodeが動作しているサーバの /etc/munin/plugins 配下などにコピーしてください。git cloneするか↓のような感じでダウンロードしてください。

```
$ curl -o switchbotmeterbt https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/sensors/switchbotmeterbt
```

プラグインの設定ファイルを /etc/munin/plugin-conf.d 配下などに作成してください。
userとenv.macaddrは必須です。MACアドレスは、SwitchBotアプリの温湿度計の設定画面の「デバイス情報」から確認することができます。

```
[switchbotmeterbt]
   user  root
   env.macaddr  aa:aa:aa:aa:aa:aa bb:bb:bb:bb:bb:bb cc:cc:cc:cc:cc:cc
```

こんな感じでプラグイン単体でテストすることもできます。

```
$ sudo env macaddr="ec:a9:xx:xx:xx:xx" ./switchbotmeterbt
multigraph switchbotmeterbt_temp
eca9xxxxxxxx.value 21.9
multigraph switchbotmeterbt_humid
eca9xxxxxxxx.value 61
multigraph switchbotmeterbt_batt
eca9xxxxxxxx.value 100
multigraph switchbotmeterbt_rssi
eca9xxxxxxxx.value -73
```

値が取得できていれば、以下のようなグラフが作成されます。

温度はこんな感じです。部屋によって傾向が違って面白いです。青色のグラフの部屋は西日が入るので、晴れた日の夕方には温度が高くなっています。
![switchbotmeterbt_temp-week.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/95b8cc84-8b00-576d-6419-7f67b9c12239.png)

湿度はこんな感じです。こちらも部屋によって傾向が違いますね。黄色のグラフはカメラの防湿庫の中に置いた機器です。やはり湿度が安定してますね。
![switchbotmeterbt_humid-week.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/73993cbd-b30e-58ba-b9a5-54a5f5bc3229.png)

ついでに信号強度（RSSI）もグラフにしました。青色のグラフは少し離れた部屋に置いている機器なので時折電波が途切れています。-95dBを下回ると受信するのが難しくなるようです。
![switchbotmeterbt_rssi-week.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/1bf40da6-b669-91a8-5bc9-1b8f4eaf17ce.png)

バッテリー残量も取得できるのでこちらもついでにグラフにしました。乾電池なのでどのくらい持つのか気になるところですが、単4電池2本で1年以上は余裕で持つらしいです。1ヶ月ほど使用していますが、まだ100%から減っていません。
![switchbotmeterbt_batt-week.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/4d40d82b-33b8-b127-6eee-3e9ba5ddde8a.png)


## 参考情報

こちらのサンプルコードを流用させていただき、Munin Pluginを作成しました。

https://qiita.com/warpzone/items/11ec9bef21f5b965bce3

https://qiita.com/kentmori-8/items/749678e1fe0e73cf18e6

こちらは公式のAPIドキュメントです。この手の製品で仕様が公開されているのはとてもありがたいです。

https://github.com/OpenWonderLabs/python-host/wiki/Meter-BLE-open-API


# WebAPI編

## 必要なもの

Bluetoothが使えない場合は、WebAPI経由で温度・湿度を取得することも可能です。こちらはクラウドにデータをアップロードする必要があるので、Switchbot Hubが必要になります。

- Switchbot Meter
- Switchbot Hub（クラウド連携のため）
- Switchbotアプリ（iOS/Android）

## 事前準備

### トークンの取得

Bluetoothを使う方法とは異なり、Switchbot OpenAPIというクラウドサービスを利用します。APIを利用するには、アカウントの登録とトークンの取得が必要になります。トークンは以下の手順で取得できます。たとえが古いですが、トークン取得のやり方が昔のファミコンの裏技みたいだと思いました。

1. iOS/AndoroidでSwitchbot Appをインストールする。
2. アカウントを登録する。
3. Switchbot Appから、OpenAPI用のTokenを生成する。
  1. 「プロフィール」画面を開く。
  2. 「設定」画面を開く。
  3. 「アプリバージョン」を10回タップする。
  4. 「開発者向けオプション」が表示されるので、その画面から「トークンを取得」ボタンを押してトークンを生成する。

参考： Switchbot OpenAPIの利用手順・技術仕様

https://github.com/OpenWonderLabs/SwitchBotAPI


### デバイスIDの取得

これでAPIにアクセスできるようになっているので、curlコマンド等でAPIを利用することができます。以下のURLにアクセスすると、デバイスの一覧を取得できるので、目的のSwitchbot Meterの"deviceId"をメモしておきます。devicdIdはMACアドレスから「:」を除いたものなので、Switchbotアプリから確認してもいいです。

```
$ curl -s -H 'Authorization:xxxxxx' https://api.switch-bot.com/v1.0/devices | jq .
{
  "statusCode": 100,
  "body": {
    "deviceList": [
      {
        "deviceId": "ECA9xxxxxxxx",  # ←これ
        "deviceName": "温湿度計 xx",
        "deviceType": "Meter",
        "enableCloudService": true,
        "hubDeviceId": "F944xxxxxxxx"
      },
...
```

こんな感じでJSONでデータを取得することができます。JSONをシェルスクリプトで扱うにはjqコマンドが便利です。

```
$ curl -s -H 'Authorization:xxxxxx' https://api.switch-bot.com/v1.0/devices/ECA9xxxxxxxx/status | jq .
{
  "statusCode": 100,
  "body": {
    "deviceId": "ECA9xxxxxxxx",
    "deviceType": "Meter",
    "hubDeviceId": "F944xxxxxxxx",
    "humidity": 63,
    "temperature": 28.1
  },
  "message": "success"
}
```

今回は温度と湿度の取得しかしていませんが、OpenAPIを使うと、curlコマンド等でSwitchbot Hubに接続された製品を操作できるので楽しいです。REST APIでエアコンのON/OFFなどができて夢が広がります。詳しくは参考情報のURLをご参照ください。


## Muninの設定例

Muninのプラグインを作成して、こちらも本家のリポジトリにマージしてもらいました。

https://github.com/munin-monitoring/contrib/blob/master/plugins/sensors/switchbotmeter

このプラグインをmunin-nodeが動作しているサーバの /etc/munin/plugins 配下などにコピーしてください。git cloneするか↓のような感じでダウンロードしてください。

```
$ curl -o switchbotmeter https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/sensors/switchbotmeter
```

プラグインの設定ファイルを /etc/munin/plugin-conf.d 配下などに作成してください。env.tokenとenv.deviceidは必須です。

```
[switchbotmeter]
  env.token     xxxxxxxx
  env.deviceid  xxxxxxxx
  env.interval  900
```

1点注意点があります。Switchbot OpenAPIは、呼び出し回数を1日1000回に制限しています。munin-nodeはデフォルトだと5分に1回APIにアクセスするので、1日288回アクセスすることになります。アクセス回数が気になる場合は、env.intervalを指定することでアクセス頻度を下げることができます。上記の例だと900秒（15分）間は結果をキャッシュするようになるので、アクセス回数は1日あたり96回になります。

値が取得できていれば、以下のようなグラフが作成されます。Bluetoothとは異なり、取得できる値は温度と湿度のみで、受信強度やバッテリー残量は取得できませんでした。

![switchbotmeter-week.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/b5669c62-e794-f304-b8f8-155075c25917.png)

## (2023-12-07追記)

2022/9にSwitchBot OpenAPIがv1.1になっていたことに気づいたので新たにプラグインを作り直しました。
本家のリポジトリにマージしてもらいました。Muninは歴史あるソフトウェアですが、プルリクを送るとわりとすぐに反応してくださる感じがします。

https://github.com/munin-monitoring/contrib/blob/master/plugins/sensors/switchbotmeter_multi

主に以下の変更を行いました。
- SwitchBot OpenAPI v1.1 に対応
- 複数台に対応（最新の防水温湿度計にも対応しています）
- バッテリー残量のグラフを追加（以前は非対応でしたが、v1.1で対応したようです）

こんな感じのグラフを作成することができます。

![switchbotmeter_multi_temperature-day.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/f9246261-0845-7e06-6081-83db3dacd959.png)

![switchbotmeter_multi_humidity-day.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/14be4ff1-fac4-a7a0-846e-120a6e14a198.png)

![switchbotmeter_multi_battery-day.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317213/77b3d15d-3008-9542-2ca5-7bc6fb8f58d4.png)

若干補足ですが、v1.1になって認証方式が少し複雑になりました。以前はtokenだけで認証できたのですが、t, nonce, sign というパラメータも必要になっています。シェルスクリプトでの実装の参考になるかもしれませんので、該当箇所をリンクしておきます。

https://github.com/munin-monitoring/contrib/blob/48c42758514960f559c09a31b5f74fc4301f141f/plugins/sensors/switchbotmeter_multi#L158


## 参考情報

Switchbot OpenAPIの利用手順・技術仕様

https://github.com/OpenWonderLabs/SwitchBotAPI

# まとめ

Switchbot Meterから温度・湿度を取得して、Muninで可視化する方法をご紹介しました。Pythonやシェルスクリプトでハードウェアを操作できるのは楽しかったです。
自宅のリモコンがある家電製品はほとんど全てSwitchbot Hubで操作できるようにしたので、私の自宅はスマートホーム的なものに近づいたように思います。ちょっと未来を感じました。