Windows10でBleakを使ってSwitchBotを動かす

# はじめに
この記事は、Windows10でBleakを用いたSwitchBotのBLE通信を行いたい人向けのチュートリアルの記事です。SwitchBotに接続して命令バイトを送信するまでを行います。言語はpythonです。    
　また、今回の記事ではSwitchBotを用いていますが、接続して命令バイトを送信しているだけなので、Bleakを用いたBLE通信として他のBrueTooth機器にも利用できると思います。(おそらく)


# 要件
* Windows10
* python 3.7.6
* bleak 0.7.1
* SwitchBot
* Bluetooth_Dongle 5.0(PCに内蔵の送受信機がなければ必要)

#SwitchBot
Bluetoothによって遠隔で操作できるスイッチです。複数の種類がありますが、今回は以下のSwitchBotを使用します
https://www.switchbot.jp/bot

# BLE通信
BLE(Bluetooth Low Energy)通信はBluetoothバージョン4.0から追加された低電力でBluetooth機器と通信ができる規格です。この辺りは先人の記事を参考にして頂く方が分かりやすいと思います。
https://houwa-js.co.jp/blog/2018/06/20180629/  
https://jellyware.jp/kurage/bluejelly/ble_guide.html


# Windows環境下でpybluesは使用できない
　Windows環境下でSwitchBotのBLE通信を行いたい場合、主に使われているBLE通信のライブラリであるpybluezはWindowsでは使用できません。  
(参考:https://atatat.hatenablog.com/entry/2020/07/09/003000#3-Bleak%E3%81%AE%E5%88%A9%E7%94%A8)  
　おまけに、SwitchBotにはPCでのBLE通信を行うための[github](https://github.com/OpenWonderLabs/python-host)が公開されていますが、そちらはpybluesでのみ対応したコードなので、そのまま使用というわけには行きません。
# Bleakの利用
こちらの[記事](https://atatat.hatenablog.com/entry/2020/07/09/003000#3-Bleak%E3%81%AE%E5%88%A9%E7%94%A8)から、BleakというモジュールがWindows環境下のBLE通信に利用できるとあったため、利用します。以下のpipコマンドを実行します。

    pip install bleak

# SwitchBotのMACアドレスを調べる
　[公式ドキュメント](https://bleak.readthedocs.io/en/latest/#)を参考にしながら、PC上で周辺のBluetooth機器を探索するプログラムを実行します。

```Discover.py
import asyncio
from bleak import discover

async def run():
    devices = await discover()
    for d in devices:
        #見つかった機器のmacアドレス、名前、距離を表示
        print(d.address,d.name,d.rssi)
        print(d)

loop = asyncio.get_event_loop()
loop.run_until_complete(run())
```

ここで、SwitchBotが見つかった場合、SwitchBotのMACアドレスが表示されるのでそれをコピーしておきます。  
見つからない場合、[こちら](https://www.dropbox.com/s/vcvemz9rwr711rl/5.zip)からBluetoothのドライバのダウンロードを行い、SwitchBotが正しく認識されるかを確認してください   
また、SwitchBotの初期不良の可能性もあるので、Android/iOSアプリで提供されているSwitchBotアプリから接続テストを行うことをお勧めします。詳しい方法はSwitchbot同封のクイックスタートガイドに書かれています。

# SwutchBotとの接続
MACアドレスが取得できた場合、BLE通信を使ってSwitchBotに対して接続→命令を送信　を行っていきます。以下のプログラムは作成した接続、送信のサンプルです。

```Bleak_Connect_SwitchBot.py
import asyncio
from bleak import discover

async def run():
import asyncio
from bleak import BleakClient
import time

#switchbotのMacアドレス.[Discover.py]で調べる必要がある
address = " "
#switchbotのUUID.SwitchBotのgithubから発掘した
UUID = "cba20002-224d-11e6-9fb8-0002a5d5c51b"


async def run(address, loop):
    async with BleakClient(address, loop=loop) as client:
        #同期ミスを防止するため一時停止。
        time.sleep(5)

        #以下で接続テスト。[Connected: False]と表示されると接続に失敗している
        x = await client.is_connected()
        print("Connected: {0}".format(x))
        #現在のswitchbotの状態を確認
        y = await client.read_gatt_char(UUID)
        print(y)
        print("接続に成功しました。コマンドを入力してください。\nコマンド → press,on,off,exit")
        while True:
            #入力受け取り。コマンド毎に送信する命令を変更する。exitなら終了する
            command = input()
            if command == "press":
                write_byte = bytearray(b'\x57\x01\x00')
            elif command == "on":
                write_byte = bytearray(b'\x57\x01\x01')
            elif command == "off":
                write_byte = bytearray(b'\x57\x01\x02')
            elif command == "exit":
                #[exit]と入力した場合、1秒後に終了
                await asyncio.sleep(1.0, loop=loop)
                break
            else:
                print("コマンドを入力してください。\nコマンド → press,on,off,exit")
                continue

            #switchbotに命令を送信
            await client.write_gatt_char(UUID, write_byte)
            #現在のswitchbotの状態を確認
            y = await client.read_gatt_char(UUID)
            print(y)
            #同期ミスが起こるので一時停止
            time.sleep(2)


#bleakによるswitchbotとの通信開始
loop = asyncio.get_event_loop()
loop.run_until_complete(run(address, loop))
```

このプログラムでは、接続に成功した場合、標準入出力から入力を待機します。次のコマンドが入力できます。  

* press : SwitchBotのon,offを切り替える (b'\x57\x01\x00')
* on    : SwitchBotをonにする(b'\x57\x01\x01')
* off   : SwitchBotをoffにする(b'\x57\x01\x02')
* exit  : 終了する

行いたい動作に合わせて命令バイトを切り替え、client.write_gatt_char(UUID, write_byte)によってSwitchbotに命令を送信します。SwitchBotが正しく動けば成功です。

# まとめ
Windows環境下でSwitchBotによるBLE通信(python)のやり方について説明しました。本記事で説明した内容は接続と送信しかできておらず、SwtichBotのモード切替などをどのように行うかは自分の勉強不足でまだわかっていません。  
今後公式ドキュメントやgithubからモードの切り替え方法等が見つかった際には追記、別記事にて記述したいと考えています。  

[](
コードをまとめたgithubは[こちら](https://github.com/GoOhira/SwitchBot_Bleak_Connect)(この記事にあるコードしかありません)
)
追記(2020/09/11):SwitchBotAPIではBlueZを使っているためWindowsでは利用できませんでした。https://github.com/RoButton/switchbotpy