🌡️
温湿度センサからBluetoothでデータを取得する
Bluetooth通信が可能な温湿度センサからPythonで温湿度データを取得するプログラムです。
使用したセンサ
取得方法、参考にしたサイト
どちらのセンサもBLE(Bluetooth Low Energy)通信のAdvertisementフレームに温湿度、バッテリ残量の情報がのっているので、この情報を取得します。メーカーや製品によってのっている場所が違うので、下記サイトを参考にしつつ、最後は実測値とプログラム上で取得したバイト列を眺めて試行錯誤で正解にたどり着きました。
コード
早速コードです。Bluetoothの通信ライブラリとしてbleakを使ってます。
import asyncio
from bleak import BleakScanner
import time
async def main():
stop_event = asyncio.Event()
# TODO: add something that calls stop_event.set()
def callback(device, advertising_data):
# TODO: do something with incoming data
temp = 0
humid = 0
battery = 0
if(device.address == "SwitchBotのMACアドレス"):
data_manu = advertising_data.manufacturer_data.get(1)
if(data_manu[2]&0b10000000 == 0b10000000):
temp_t = (data_manu[2]&0b01111111) * 256*256 + data_manu[3] * 256 + data_manu[4]
temp = 0 - ((temp_t - (temp_t % 1000)) / 10000)
else:
temp_t = data_manu[2] * 256*256 + data_manu[3] * 256 + data_manu[4]
temp = (temp_t - (temp_t % 1000)) / 10000
humid = (temp_t % 1000) /10
battery = data_manu[5]
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " , temp=" + str(temp) + ", humid=" + str(humid) + ", battery=" + str(battery) )
elif(device.address == "GoVeeのMACアドレス"):
data_manu = advertising_data.manufacturer_data.get(2409)
data_srv = advertising_data.service_data.get('0000fd3d-0000-1000-8000-00805f9b34fb')
temp = (data_manu[9] & 0b01111111) + (data_manu[8] & 0b00001111) / 10
humid = data_manu[10]
isOverZero=(data_manu[9] & 0b10000000)
if not isOverZero:
temp = 0 - temp
if(data_srv != None):
battery = data_srv[2] & 0b01111111
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + " , temp=" + str(temp) + ", humid=" + str(humid) + ", battery=" + str(battery) )
pass
async with BleakScanner(callback) as scanner:
# Important! Wait for an event to trigger stop, otherwise scanner
# will stop immediately.
await stop_event.wait()
# scanner stops when block exits
print("stop")
asyncio.run(main())
Discussion