#データフォーマット
データフォーマットみて実装できる人はここを見よう
公式のWikiに詳しく書かれています。
https://github.com/OpenWonderLabs/python-host/wiki/Meter-BLE-open-API
Index | Byte[0] | Byte[1] | Byte[2] | Byte[3] | Byte[4] | Byte[5] |
---|---|---|---|---|---|---|
Description |
Enc Type Dev Type Bit[7]予約済み Bit[6:0]デバイスタイプ |
Status Bit[7:4]予約済み Bit[3:0]デバイスグループ |
Update UTC Flag Battery Bit[7]予約済み Bit[6:0]バッテリー残量 |
alarm flag the fraction part of temperatrue value (WoSensorTH) Bit[7:6]温度アラートの状態 Bit[5:4]湿度アラートの状態 Bit[3:0]温度の小数点以下 |
temperature mode Positive/Negative temperature flag the integer part of temperature value (WoSensorTH) Bit[7]マイナスかプラスか Bit[6:0]温度の整数値 |
humidity value (WoSensorTH) Bit[7]温度スケール Bit[6:0]湿度の整数値 |
##Byte[0]
###Bit[6:0]のデバイスタイプ
製品名 | Hex(16進数表記) | Ascii | 備考 |
---|---|---|---|
SwitchBot Bot (WoHand) | 0x48 | H | |
WoButton | 0x42 | B | |
SwitchBot Hub (WoLink) | 0x4C | L | addMode |
SwitchBot Hub (WoLink) | 0x6C | l | Normal |
SwitchBot Hub Plus (WoLink Plus) | 0x50 | P | addMode |
SwitchBot Hub Plus (WoLink Plus) | 0x70 | p | Normal |
SwitchBot Fan (WoFan) | 0x46 | F | addMode |
SwitchBot Fan (WoFan) | 0x66 | f | Normal |
SwitchBot MeterTH (WoSensorTH) | 0x74 | t | addMode |
SwitchBot MeterTH (WoSensorTH) | 0x54 | T | Normal |
SwitchBot Mini (HubMini) | 0x4D | M | addMode |
SwitchBot Mini (HubMini) | 0x6D | m | Normal |
##Byte[1]
###Bit[3:0]のデバイスグループ
#####グループ分け
Bit | Group |
---|---|
Bit[3] | Group D |
Bit[2] | Group C |
Bit[1] | Group B |
Bit[0] | Group A |
#####値
値 | 状態 |
---|---|
0 | デバイスがこのグループに含まれていない |
1 | デバイスがこのグループに含まれています |
##Byte[2]
Bit[6:0]はバッテリー残量を0~100の値で表します、単位は%です。
##Byte[3]
#####温度アラートの状態
値 | 状態 |
---|---|
0 | アラートなし |
1 | 低温度アラート(温度が下限以下) |
2 | 高温度アラート (温度が上限以上) |
3 | 温度アラート(温度は下限以上、上限以下) |
#####湿度アラートの状態
値 | 状態 |
---|---|
0 | アラートなし |
1 | 低湿度アラート(湿度が下限以下) |
2 | 高湿度アラート (湿度が上限以上) |
3 | 湿度アラート(湿度は下限以上、上限以下) |
公式Wikiには higher than
とか lower than
とか書いてあったからより高い
と未満
だと思って湿度で検証したら以上
と以下
じゃね~かよ。
低湿度アラートを(0~39%)高湿度アラートを(39~99%)にしたら3が出力されたよ!!
##Byte[4]
###Bit[7]
値 | 説明 |
---|---|
0 | マイナスの温度 |
1 | プラスの温度 |
##Byte[5]
###Bit[7]
値 | 説明 |
---|---|
0 | 摂氏スケール |
1 | 華氏スケール |
スケールによってByte[3]の温度が変わるわけではなく、華氏スケールでの温度が提供される。
摂氏に変換する場合は
摂氏スケール温度=(華氏スケール温度*1.8)+32
となる。
#実装例
##環境
- Raspberry Pi 4 Model B 4GB
- Raspbian 10
- Python 3.7.3
##コード
import toml
import binascii
from bluepy.btle import Scanner, DefaultDelegate
config = toml.load('config.toml')
macaddr = config['Device']['MACAddress']
mask_7Bit = 0b01111111
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
data = binascii.unhexlify(value[4:])
if(data[0] != 0x54):break
battery = data[2] & mask_7Bit
decimal_temperature = data[3] & 0b00001111
temperature = float(data[4] & mask_7Bit) + decimal_temperature/10
subzero = (data[4] & 0b10000000) != 0b10000000
humidity = data[5] &mask_7Bit
if subzero :
temperature = -temperature
print(battery,end='% \n')
print(temperature,end='C \n')
print(humidity,end = '% \n')
scanner = Scanner().withDelegate(ScanDelegate())
scanner.scan(0)
[Device]
MACAddress="ff:ff:ff:ff:ff:ff"
まずはSwitchBotMeterのMACアドレスでフィルタリングをかけるので、SwitchBotのスマートフォンアプリからMACアドレスを取得してきます。
例としてff:ff:ff:ff:ff:ffを書いていますので環境に合わせて書き換えてください。
Macアドレスはコード内にそのまま書いても問題ないです。
個人のポリシーでconfig.tomlに書いています。
adtypeが22の場合に温度や湿度の情報がパケットに含まれているのでadtype22でフィルタリングします。
valueの最初の4桁は使わないのでスライスで5桁目(インデックスでいうと4)以降を参照します。
その値を、binascii.unhexlify()
でバイト列に変換します。
その後は上記で紹介した表に合わせてバイト列の値に対してビット演算でマスクを掛けています。
例えばバッテリー残量はByte[2]の0から6ビットまでの値で取得できるので
battery = data[2] & 0b01111111
で取得できます。
##実行
pip3でbinasciiやbluepyをインストールしてからroot権限で実行します。
sudo Python3 Meter.py