スイッチボットCO2センサーの遊び方

スイッチボットCO2センサーとlinuxで遊ぶよ PC/デジモノ

スイッチボットから発売になったCO2センサーを早速解析しました!

今日届きましたのでBluetooth(BLE)のアドバタイズデータ(パケット)を解析して、CO2濃度データを引っこ抜けるようにしました。

前準備

RaspberryPiなどのLinuxマシンを用いてスイッチボットCO2センサーのBluetoothアドバタイズデータの中から測定データを引っこ抜こぬいて遊ぶという趣旨です。

Pythonと関連するライブラリを使いますので、必要に応じて下記記事を参考にしてください。

本プログラムで使用するライブラリのインストールを行います。

$sudo apt -y install python3-dev
$sudo apt -y install python3-pip
$sudo apt -y install libglib2.0-dev
$sudo pip3 install --break-system-packages bluepy
bookworm以降はsudo pip3 install bluepyが使用できなくなりました。
ここではこの点について詳細は述べませんが、上記は奨励されていない、bluepyを無理やりインストールする方法です。これが気持ち悪い方はbullseyeを使用することをお勧めします。bullseyeであればpip3によりbluepyがインストール可能です。

スクリプト

早速ですが、以下のpythonプログラムで動作が確認できました。ベースとなっているのは防水型温湿度計で、その後ろにさらにデータが足されているようです。で、数字とにらめっこしながら正解っぽいものにたどり着きました。

$emacs sbm_c.py
import binascii
from bluepy.btle import Scanner, DefaultDelegate
import time
import sys

args = sys.argv
macaddr = args[1]
battery = 0
humid = 0
temp = 0
CO2 = 0

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):
        servicedata = binascii.unhexlify(value[4:])
        battery = servicedata[2] & 0b01111111
        print(str(battery) + "," + str(temp) + "," + str(humid)+ ","+ str(CO2))
        exit()
      elif(adtype == 255):
        servicedata = binascii.unhexlify(value[16:])
        CO2 = servicedata[7]*256 + servicedata[8]
        humid = servicedata[4] & 0b01111111
        temp = (servicedata[2] & 0b00001111) / 10 + (servicedata[3] & 0b01111111)
        isOverZero=(servicedata[3]&0b10000000)
        if not isOverZero:
          temp=-temp
        continue
      else: continue

scanner = Scanner().withDelegate( ScanDelegate() )
scanner.scan(10)

使い方

対象のスイッチボットセンサーのMACアドレスをaa:bb:cc:dd:ee:ffとすると

$sudo python3 sbm_c.py 'aa:bb:cc:dd:ee:ff'

出力は

100,26.6,65,874

カンマ区切りでバッテリー残量、温度、湿度、CO2濃度の順で得られます。煮るなり焼くなり好きにすればOKです。

簡単な解説

バッテリー残量、温度、湿度に関しては防水温湿度計と同じデータ構造になっていることがわかりました。

CO2メーターの場合は温度湿度データの後ろに二酸化炭素関連のデータが追加される格好になっています。

CO2 = servicedata[7]*256 + servicedata[8]

上記プログラムでいうところの、servicedata[7]を256倍してservicedata[8]を足したものがCO2濃度ppmになっているようです。

なお、CO2メーター本体に表示される値とBLEでアドバタイズされているデータには若干(数分~10分程度?)のズレがあるようです。

まとめ

防水温湿度計は以前の温湿度計とデータ構造が変わっていたので苦労しましたが、CO2メーターに関しては防水温湿度計とほぼ同じだったので意外とすんなりできました。

まだ、何のデータかわからない部分も残っていますのでわかり次第追記します。

参考

Raspberry Piを使ってSwitchBot 温湿度計のデータをMackerelで可視化する | 高木のブログ
この記事は、「Raspberry Pi Advent Calendar 2020」16日目の記事です。 はじめに 最近、SwitchBot 温湿度計を購入しました。 いろいろ連携させるためには別でSwitchBotハブというものが必要みたい...

コメント