はじめに
SwitchBotから発売されたPlug MiniからBluetooth経由で消費電力を取得する方法についての知見について記載します。
以下のSwitchBotの公式が公開しているpython用のコードを利用できることが前提の説明となります
Plug Miniについて
SwitchBotプラグミニはBluetoothとWi-Fiに対応可能なので、Wi-Fiチップのみのスマートプラグよりデバイスの追加と操作がより簡単に。
既存のSwitchBot PlugではWi-Fi経由でしかデータ取得や操作ができなかったところ,
Bluetoothによる操作にも対応したと謳っており,Wi-Fi環境がなくても使用できるようになった製品です.
また,On/Offしか操作できなかったPlugと比べて、消費電力をAPIを経由して取得可能になるなど,
消費電力を監視して,別のIoT機器を制御するような応用が効くようになりました.
私は,ロボット掃除機の充電台につけて,ロボット掃除機が帰ってきたら拭き掃除のロボットを発進させる機能を,
別メーカーのロボットで実現するために使用しています
python-hostの改造
python3用のswitchbot_py2topy3.pyを改造します
SwitchBotのBluetoothでブロードキャストする機器からデータを取得する際,
L77-L114の処理で
dev_type
で機器を判別してデータを取り出すのが一般的な方法なのですが,
Plug Miniはこの方法ではデータ取得できません
上記によるとUUID
やmacアドレス
を含んだブロードキャストの方でデータを配信していることから,
L133-L134に処理を追加することでデータを取得するように実装する必要があります.
elif desc == 'Manufacturer' and value[0:4] == company_id:
mac = dev.addr
#以下追記
#`xx:xx:xx:xx:xx:xx`はPlugMiniのBluetoothのMacアドレスを小文字表記で`:`で区切った値
if( mac == "xx:xx:xx:xx:xx:xx"):
mode = 0
power = (int(value[24:28].encode('utf-8'), 16) & 0x7fff) / 10.0;
sw = int(value[18].encode('utf-8'), 16 ) >> 3;
param_list.extend([sw, power])
上記を追記しただけだとparam_listがL113-114の処理で初期化されてしまうので,
L113の手前に以下のコードを追加します.(plug miniのdev_type
はj
または g
のようです)
# 追記ここから
elif (model == b'j') or (model == b'g') :
print("do nothing")
# 追記ここまで
else:
param_list[:] = []
次にデータを返すための整形を行います
まずL44-L58の部分で整形用の変数を定義します
def scan_loop(self):
service_uuid = 'cba20d00-224d-11e6-9fb8-0002a5d5c51b'
company_id = '6909' # actually 0x0969
dev_list = []
bot_list = []
meter_list = []
curtain_list = []
contact_list = []
motion_list = []
param_list = []
plug_list = [] #追記
pir_tip = ['No movement detected', 'Movement detected']
hall_tip = ['Door closed', 'Door opened', 'Timeout no closed']
light_tip = ['Dark', 'Bright']
plug_sw = ['Off', 'On'] #追記
そして,L140-L165の処理でデータを返す部分を実装します.
elif dev_type == b'd':
# TODO:
# timeTirgger = datetime.datetime.now() + datetime.timedelta(0, params[3])
# contact_list.append([mac, 'Contact', "%s, %s, %s, Last trigger: %s" %
# (hall_tip[params[0]], pir_tip[params[1]], light_tip[params[2]], timeTirgger.strftime("%Y-%m-%d %H:%M"))])
contact_list.append([mac, 'Contact', "%s, %s, %s" %
(hall_tip[params[0]], pir_tip[params[1]], light_tip[params[2]])])
#追記ここから
elif (dev_type == b'j') or (dev_type == b'g'):
plug_list.append([mac, 'Plug', "%s, %.1fW", %
(plug_sw[params[0]], params[1])])
#追記ここまで
print("Scan timeout.")
#plug_listを追記
return bot_list + meter_list + curtain_list + contact_list + motion_list + plug_list
pass
以上で編集は完了です.あとは sudo python3 switchbot_py2topy3.py
を実行して以下のように表示されれば成功です
Scan timeout.
0 ['6055f922d95a', 'Plug', 'On, 0.5W']