RaspberryPiで室内の温度・湿度の計測をしてみた記録です。
いろいろ調べてみたところ、価格も安価で、RaspberryPiでの事例やAPIも公開されていたSwitchBot 温湿度計が良さそうです。
SwitchBot 温湿度計
これ、コンパクトで液晶表示も見やすく、このまま置いて使っても良さそう。
スイッチボットハブと併用すると、IFTTTにつないで計測値を元にエアコンを制御したり、Googleアシスタント・Amazonアレクサと連携もできます。
今回は、スイッチボットハブを使わず、温湿度計単体でBluetooth通信で計測値をRaspberryPiでの取得することにしました。
SwitchBotアプリの設定
まずは、温湿度計が正常に動作しているか確認のため、SwitchBotアプリの設定を行います。
事前に、スマホのBluetoothがオンになっていることを確認しておきます。
最初に、SwitchBotアプリをダウンロードして起動したら、アプリの左側メニューの「デバイスの追加」をタップします。
デバイスのアイコン一覧が表示されますので、「温湿度計」を選びます。
次に、温湿度計本体で、アプリとの接続待ち受けモードにします。
本体の液晶画面の右上にBluetoothマークが点減するまで、裏面の「°C表示」と「°F」表示の切替に利用する白いボタンを長押しします。
本体のBluetoothマーク点滅を確認した後、アプリの画面下部「次へ」をタップすると、温湿度計の追加が完了して、「成功」の画面が表示されます。
最後にニックネームを設定したら完了です。
登録が完了したら、アプリ画面ですぐに温度、湿度を確認することができます。これだけでも、便利ですね。
温湿度計のBLE MACアドレスの確認
温度・湿度表示エリアの右上の歯車アイコンをタップ、「Meter設定」タイトル右の「・・・」をタップして表示された「BLE MAC」のアドレスをメモしておきます。
これは温湿度計を特定するための機器固有のIDとなります。

これで温湿度計本体の作業は終わりです。
RaspberryPiとBluetooth接続を確認
RaspberryPIにログインして、以下のコマンドで温湿度計にBluetooth接続できることを確認しておきます。
sudo hcitool lescan
実行後、表示される一覧の中に、先ほどメモしたアドレスが表示されていれば大丈夫です。
LE Scan ... . . AB:CD:EF:12:34:79 (unknown) . .
RaspberryPiにbluepyのインストール
RaspberryPiにBluetoothを扱うためのパッケージをインストールします。
apt install glib-2.0 libglib2.0 pip install binascii bluepy
次に、スキャンにはbluepyにSudo権限を設定します。
bluepyのインストールされているフォルダに移動してsetcapコマンドを実行します。
cd /usr/local/lib/python3.7/dist-packages/bluepy sudo setcap 'cap_net_raw,cap_net_admin+eip' bluepy-helper
※私の環境では上記フォルダでしたが、環境によって異なるため注意が必要です。
計測値を取得するpythonスクリプト
参考にさせて頂いたサイトのスクリプトを少し修正して、引数にアドレスを指定して起動できるようにして、スクリプトを1つのファイルにまとめました。
#!/usr/bin/python3
import struct
import sys
from bluepy.btle import Scanner, DefaultDelegate
args = sys.argv
# macアドレスは小文字にする
macaddr = str.lower(args[1])
#Broadcastデータ取得用デリゲート
#class SwitchbotScanDelegate(btle.DefaultDelegate):
class SwitchbotScanDelegate(DefaultDelegate):
#コンストラクタ
def __init__(self, macaddr):
#btle.DefaultDelegate.__init__(self)
DefaultDelegate.__init__(self)
#センサデータ保持用変数
self.sensorValue = None
self.macaddr = macaddr
# スキャンハンドラー
def handleDiscovery(self, dev, isNewDev, isNewData):
# 対象Macアドレスのデバイスが見つかったら
if dev.addr == self.macaddr:
# アドバタイズデータを取り出し
for (adtype, desc, value) in dev.getScanData():
#環境センサのとき、データ取り出しを実行
if desc == '16b Service Data':
#センサデータ取り出し
self._decodeSensorData(value)
# センサデータを取り出してdict形式に変換
def _decodeSensorData(self, valueStr):
#文字列からセンサデータ(4文字目以降)のみ取り出し、バイナリに変換
valueBinary = bytes.fromhex(valueStr[4:])
#バイナリ形式のセンサデータを数値に変換
batt = valueBinary[2] & 0b01111111
isTemperatureAboveFreezing = valueBinary[4] & 0b10000000
temp = ( valueBinary[3] & 0b00001111 ) / 10 + ( valueBinary[4] & 0b01111111 )
if not isTemperatureAboveFreezing:
temp = -temp
humid = valueBinary[5] & 0b01111111
#dict型に格納
self.sensorValue = {
'SensorType': 'SwitchBot',
'MacAddr': self.macaddr,
'Temperature': temp,
'Humidity': humid,
'Battery': batt
}
# macaddr指定した温湿度センサの値を取得
scanner = Scanner().withDelegate( SwitchbotScanDelegate(macaddr) )
#スキャン(timeout=5s)
scanner.scan( 5.0 )
#出力
print('MacAddr = ' + scanner.delegate.sensorValue['MacAddr'])
print('Tempreture = ' + str( scanner.delegate.sensorValue['Temperature']) )
print('Humidity = ' + str( scanner.delegate.sensorValue['Humidity']) )
print('Battery = ' + str( scanner.delegate.sensorValue['Battery']) )
以下のように実行すると、温湿度計から計測値が表示されます。
chmod a+x switchbot-meter.py sudo switchbot-meter.py AB:CD:EF:12:34:79 MacAddr = ab:cd:ef:12:34:79 Tempreture = 25.5 Humidity = 60 Battery = 100
※本記事は、以下のサイトを参考にさせてもらいました。
SwitchBot 温湿度計の測定値を BLE Advertisement パケットから直接読み取る
SwitchBot温湿度計の値をRaspberryPiでロギング
SwitchBot 開発元WanderLabsが公開したBLE 仕様(Meter BLE open API)

