switchbot温湿度計の遊び方

スイッチボット温湿度計 PC/デジモノ

ホームIOTデバイスで有名なswitchbotから温湿度計が発売されています。
Linuxマシンを使って、温湿度のデータを読み出す方法を紹介します。

スイッチボット温湿度計とは?

この温湿度計はBLE(BluetoothLowEnergy)が搭載されていてスマホアプリから温度湿度を確認することができます。お値段も2000円程度と値ごろです。
普通はスマホアプリでデータをみて楽しむものなのですが、サンプルプログラムが公開されていてLinuxなどから数値を直接読みだすことができます。私も1年以上使っていて初めて知りました。
データを取り込むだけなら標準のスマホアプリで全く問題ないので自己満足の世界です!

準備

まずは準備です。データを集める母艦はRaspberrypiZeroWを使用しました。
OSは現時点の最新版(2021-01-11-raspios-buster-armhf-lite)です。
以下のコマンドを順に実行してください。
$sudo apt -y install python3-dev
$sudo apt -y install python3-pip
$sudo apt -y install libglib2.0-dev
$sudo pip3 install bluepy
Debian12 bookwormになってからpython3に必要なライブラリbluepyのインストール時にエラーが出るようになってしまいました。現状ではとりあえずひとつ前のBullseyeで使用することをお勧めします。
もしくは無理やり入れるのであれば以下のようにしてください。
$sudo pip3 install –break-system-packages bluepy
breakの前は(-)ハイフンをふたつ続けてください
上記で動かない場合はbluezもインストールしてください。ラズパイなら初期インストール済みです。
$sudo apt install bluez

データの取り出し方

問題は読み出すためのプログラムです。今回参考にしたのはこちらのサイト。
色々と探した中で一番シンプルでわかりやすかったです。感謝です。
Raspberry Piを使ってSwitchBot 温湿度計のデータをMackerelで可視化する | 高木のブログ
この記事は、「Raspberry Pi Advent Calendar 2020」16日目の記事です。 はじめに 最近、SwitchBot 温湿度計を購入しました。 いろいろ連携させるためには別でSwitchBotハブというものが必要みたい...
こちらのコードを参考にさせてもらって少しだけ手を加えました。
import binascii
from bluepy.btle import Scanner, DefaultDelegate
import time
import sys

args = sys.argv
macaddr = args[1]

class ScanDelegate(DefaultDelegate):
  def __init__(self):
    DefaultDelegate.__init__(self)

  def handleDiscovery(self, dev, isNewDev, isNewData):
    if dev.addr != macaddr: return
    for (adtype, desc, value) in dev.getScanData():
      if (adtype != 22): continue
      servicedata = binascii.unhexlify(value[4:])
      battery = servicedata[2] & 0b01111111
      temperature = (servicedata[3] & 0b00001111) / 10 + (servicedata[4] & 0b01111111)
      isTemperatureAboveFreezing = servicedata[4] & 0b10000000

      if not isTemperatureAboveFreezing:
        temperature = -temperature

      humidity = servicedata[5] & 0b01111111

      print(str(battery) + "," + str(temperature) + "," + str(humidity))
      exit()

scanner = Scanner().withDelegate( ScanDelegate() )
scanner.scan(10)
①複数台の温湿度計使うことを想定して引数にMACアドレスをとるように変更
macaddr = args[1]
②CSV形式でバッテリー残量、温度、湿度を吐き出すように変更
print(str(battery) + "," + str(temperature) + "," + str(humidity))
ファイル名はsbm.pyとしています。
このPythonを走らせて記録するシェルスクリプトを作りました。
MACADDRとOUTPUTPATHは適宜書き換えでお願いします。
#!/bin/bash
SCRIPT_DIR=`dirname $0`
cd $SCRIPT_DIR

MACADDR='aa:aa:aa:aa:aa:aa'
OUTPUTPATH=/home/hoge/meter.txt
DATE=`date "+%Y,%m,%d,%H,%M,%S"`
LOOP=3

for((i=0;i<$LOOP;i++));
 do
 Data=$(python3 sbm.py $MACADDR)
 if [ -n "$Data" ]; then
  break
 fi
done

if [ -n "$Data" ]; then
 Result="${DATE},${Data}"
 echo $Result >> $OUTPUTPATH
fi
稀に良く取りこぼしがあるので、3回まではリトライするようにしています。
問題なければ出力先で設定したファイルに以下のような感じで結果が書き込まれているはずです。
2021,02,20,13,42,49,100,18.2,35

使用例

上記スクリプトをsudo crontab -eで登録しておけば定期的にデータを記録できます。
ambientにデータ送信するようにしておけばこんなグラフを自動で作ることもできます。
Switchbot温湿度計で取得したデータをAmbientで表示
Raspberrypi+BME280やESP32+BME280でも同じようなことはできますが、電源とパッケージングの問題で実用はなかな難しいです。市販品をこういう形で利用できるのはありがたいです。
ちなみにSwichbotの温湿度計では気圧までは取れないので、母艦Raspberrypiに接続したBME280で測定し、switchbotの測定値とまとめてambientに送信しています。
switchbotは外部電源不要でどこにでもおけますし、電池もかなり持つようなので家の何箇所かにおいて、Raspberrypiでデータを収集するという使い方が簡単にできてしまいます。ただし、基本的にはグラフを眺めてニヤニヤするぐらいの使い道しかないんですけどね。
なにか素晴らしい使い道があるかたはコメントを残して行ってください!

コメント

  1. とても興味深いです。
    参考にさせていただいたのですが、raspberry piとswitchbotデバイス間のbluetooth接続がうまくいかず、難儀しています。
    考えられそうなのはMACアドレスの設定ミスでしょうか?