SwitchBotは簡単な設定でスイッチをIoT化してくれるデバイスですが、2017年9月の時点ではIFTTT等のウェブサービスと連動させる事が困難です。そこで、この記事では簡単さをできるだけ失わないようにすることを重視しつつ、Raspberry Pi(ラズベリーパイ)をSwitchBotのハブにしてIFTTTから操作できるように公式のpythonライブラリ(下記)を利用した方法を書いていきます。そして、この方法で「帰宅したらスイッチを入れる」という動作を設定してみます。

GitHub - OpenWonderLabs/python-host: The python code running on Raspberry Pi or other Linux based boards to control SwitchBot.

https://github.com/OpenWonderLabs/python-host

SwitchBotがどんな端末で、一体何ができるのかは以下の記事を見ればよくわかります。

スイッチを出先・外からネット経由で押してON/OFFしてあらゆる家電を遠隔操作できる「SwitchBot」レビュー - GIGAZINE



今回はGmailをチェックし、設定されたタイトル(例えば「PUSH!」)のメールがあればSwitchBotにスイッチを押させる、というコードを用意しました。このコードを使うことで特定のメールをトリガーにして「SwitchBot」を操作できます。「帰宅」の判定にはIFTTTの「自分のAndroidスマートフォンが家のWi-Fiに接続された時」というトリガーを使い、帰宅時にIFTTTからメールを自動送信することで「帰宅」→「メール」→「SwitchBot」と操作していきます。

Raspberry Piがメールを読むために必要なGmailのアプリパスワードを取得します。2段階認証がオフだとアプリパスワードを発行してもらえないためオンにしていきます。アカウントのログインとセキュリティのページにある2段階認証プロセスをクリック。



スマートフォン等の電話番号を入力して「次へ」をクリック。



SMSでスマートフォン等に送られてきたコードを入力すれば設定完了。先ほどの画面に戻ると新たに「アプリパスワード」の項目が出現しているのでクリックします。



アプリパスワードに名前を付けます。アプリパスワードの名前は後で見たときに何に使っているものか分かるものであれば大丈夫。



アプリパスワードが生成されました。後で使いますのでメモしておきましょう。ブラウザを閉じてしまった場合は再確認できないので一度削除して再度生成する必要アリ。



次にRaspberry Piを使ってSwitchBotのMACアドレスを取得します。コンソールを立ち上げ、


sudo hcitool lescan 



と入力すると、ラズベリーパイが周囲のBluetoothデバイスをスキャンして教えてくれます。


XX:XX:XX:XX:XX:XX 



という形式でMACアドレスが表示されます。もし複数の候補が表示された場合、どれがどのSwichBotかを調べることはできないため、順番に試して確かめるほかありません。例えばSwitchBot3個を含めBluetoothデバイスがたくさんある状況下では、下の画像のように候補が多くなってしまいました。



引き続きRaspberry Pi上で作業していきます。以下のURLに置いてあるコードをダウンロードし、テキストエディタで開きます。

(Pythonソースコード)

http://i.gzn.jp/img/2017/09/07/switchbot-raspberry-pi/timeline.py

このコードはGmailの受信BOXを30秒ごとにスキャンして、メールのタイトルにPUSH_TRIGGER、HOLD_ON_TRIGGER、HOLD_OFF_TRIGGERに設定されたワードがないか確認し、もし設定したワードが見つかれば、SwitchBotを動作させ、さらに当該メールを削除するというものです。

※意図せぬ動作を引き起こす可能性があります。実行は必ずデータが消えても大丈夫なGmailアカウントで行ってください。

コードは以下のサイトを参考に作成しました。

Switch Bot が届いたのでSingle Board Computerから操作してみた - ブログ

http://xx-prime.hatenablog.com/entry/2017/07/01/211509

「##この中を書き換える##」というコメントのすぐ下にあるGMAIL_USERとGMAIL_APP_PASSWORDの欄を先ほど設定したGmailのアドレスとアプリパスワードに書き換え、SWITCHBOT_MAC_ADDRESSの欄を取得したMACアドレスに書き換えます。


#######この中を書き換える#######
GMAIL_USER="your@email.address"
GMAIL_APP_PASSWORD="gmailapppassword"
SWITCHBOT_MAC_ADDRESS="BT:MA:CA:DD:RE:SS"
PUSH_TRIGGER="PUSH!"
HOLD_ON_TRIGGER="switchboton"
HOLD_OFF_TRIGGER="switchbotoff"
################################ 



実際に動かしてみます。コンソールを立ち上げ、先ほどのtimeline.pyを実行します。



自動的に待機状態になるので、この状態でタイトルが「PUSH!」のメールを送ってみます。するとSwitchBotがボタンを押すと同時にコンソールにログが出力されました。



このコードを使用することで、メールを使ってSwitchBotを操作できるようになりました。続いてIFTTTで「スマホが特定のSSIDに接続された時にSwitchBotを操作するためのメールを送信する」という設定をしていきます。まずはIFTTTのサイトにアクセス。初めての場合以下のような画面が表示されるので「Continue with Google」をクリックします。



Googleアカウントと接続するためのポップアップが出ます。アカウントをクリック。



IFTTTの権限を確認して許可をクリックすればログイン完了です。



画面上部の「My Applets」を選び、続いて右端の「New Applet」を選択。



まず「+this」を選びます。



検索欄に「android」と入力し、「Android Device」をクリックして……



「Connect」をクリックします。GoogleアカウントでIFTTTにログインしていれば自動で接続されます。



家のWi-Fiに接続したときにメールを送りたいので、「Connects to a specific WiFi network」を選択。



Wi-FiのSSIDを入力し、「Create trigger」をクリックすれば設定完了です。大文字と小文字は区別されるので注意。



トリガーが設定できました。続いてメールを送るという動作の設定をしていきます。「+that」をクリック。



「Gmail」を使います。



IFTTTにGoogleアカウントでログインしていればこれも「Connect」を押すだけでOK。



「Send yourself an email」を選ぶことで自分にメールを送れます。



Subjectの欄にtimeline.pyに書き込んだSwitchBotをOnにするワードを書いて「Create action」をクリック。



設定を再確認して下の「Finish」を押せば完了です。



コードの中でSwitchBot本体とのやりとりをしているのはtrigger_device関数です。引数としてaddにはSwitchBotのMACアドレス、commandには「push」「on」「off」のいずれかを設定します。腕に自信のある方はぜひ改造してみてください。


def trigger_device(add,command):
    print ('Start to control')
    con = pexpect.spawn('gatttool -b ' + add + ' -t random -I')
    con.expect('\[LE\]>')
    print ("Preparing to connect.")
    con.sendline('connect')
    #To compatible with different Bluez versions
    con.expect(['\[CON\]','Connection successful.*\[LE\]>'])
    print ('Write command')
    if command == 'push' :
        con.sendline('char-write-cmd 0x0016 570100')
    if command == 'on' :
        con.sendline('char-write-cmd 0x0016 570101')
    if command == 'off' :
        con.sendline('char-write-cmd 0x0016 570102')
         
    con.expect('\[LE\]>')
    con.sendline('quit')
    print ('Trigger complete')