ブログ

κυσο βλογ

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

Switch Botとは

実世界の物理スイッチを押すためのIoTデバイスである。プロジェクトページのURLには「世界最小の無線ロボット」(switch-bot-the-worlds-smallest-remote-robot)という文字が埋め込まれている。

www.kickstarter.com

KICKSTARTERで出資していたものが製品となって届いた。素晴らしい。2個で59US$(7077円)だった。
amazonで探すと、一個7000円くらいで売ってる転売屋が見つかるけど、今なら上の公式サイトから飛べる
https://www.indiegogo.com/projects/switch-bot-the-world-s-smallest-remote-robot#/
で1個25US$で注文できる。量産効果でだんだん価格が下がっているようだ。
公式サイトの The journey of Switch Bot, please find more in our gallery.という写真↓
https://ksr-ugc.imgix.net/assets/014/378/118/10d8a35cf74342236b38988a76e63285_original.jpg?w=680&fit=max&v=1478196260&auto=format&q=92&s=ec09861a971e3700ec29d2330e0a5b3b
から試行錯誤と進歩の歴史が垣間見られて興味深い。

開封

Switch Bot本体2個と、お礼の紙、クイックスタートガイド、固定用両面テープ(交換用)二枚が頑丈な紙のケースに入ってきた。この紙ケースは小物の収納に使えそうなので捨てない。
f:id:XX-Prime:20170701202437j:plain

どうでもいいがお礼の紙にCEOの手書きサイン(の印刷)があるが、きったなすぎて何と書いてあるのか全く読めないw
f:id:XX-Prime:20170701202541j:plain
b~???

スマートフォンアプリで動作テスト

バッテリー絶縁用のテープを引き抜くとSwitch Botが起動する。この状態でSwitch Bot用のスマートフォンプリを開くと、自動的にBLE Scanが行われてスマートフォンのBLE通信範囲内にあるSwith Botがアプリ上に表示される。

f:id:XX-Prime:20170701202047p:plain

バイスアイコンをタップすると数秒のラグの後にモーターが動作して腕(?)が一回動作する。モーターのトルクはかなり強く、硬めのスイッチでも問題なく操作できそうである。スイッチを押すことだけに特化しているので、このあたりの調整はかなりの経験の蓄積を感じさせる。
バイスアイコンの下にある歯車マークで詳細設定を行える。デバイスの名前を変えられるので、操作対象をデバイス名にすると分かりやすい。上のイメージでわかるように、デバイス名には日本語を入力しても正しく表示される。
設定を変更するとDFU(たぶんDevice Firmware Updateの略)と表示されて通信が開始される。
詳細設定からBattery Levelも確認できるが、これは詳細設定ではなくデバイスリストに直接表示したほうが良いと思う。つまりBLEアドバタイズにBattery Levelを含ませてしまった方が良いと思う。

セキュリティ

工場出荷状態ではスマートフォンアプリをインストールして、BLE通信範囲内に入れば誰でもSwitch Botを操作できるようになっている。このままでは、悪意のある第三者においしいモーニングコーヒーを淹れられる事案が発生したりする恐れがある。
これでは問題がある場合は、スマートフォンアプリからデバイスにパスワードを設定できる。パスワードを知らないデバイスは操作できないので、一応のセキュリティは確保できている。
パスワード設定でどの程度の暗号化が行われるかは未調査。

Single Board Computerから動作テスト

むしろこっちが私にとっては本命の操作方法である。公式にpythonオープンソースライブラリが用意されているのでBLE信号を傍受して解読する手間は要らない。
github.com
日本の企業にもこのオープン性は見習って欲しいと思う。

GithubページにはRaspberry Pi3がデバイス例として挙げられているが、情報追加の目的でBeaglebone Green Wireless(BBGW)でやってみる。

$ sudo apt-get install python-pexpect
$ git clone https://github.com/OpenWonderLabs/python-host.git
$ cd python-host/

では実行!

$ sudo python switchbot.py
Scanner inited
Start scanning...
scan timeout
No SwitchBot nearby, exit

(しーん)
はい動かないー。ばんざーい。
試しにRaspberry Pi3でもやってみたが同様にscanに失敗して動作しない。
仕方ないのでswitchbot.pyの中身を少し見てみる。

    def scan_loop(self):
        self.con = pexpect.spawn('hciconfig')
        pnum = self.con.expect(["hci0",pexpect.EOF,pexpect.TIMEOUT])
        if pnum==0:
            self.con = pexpect.spawn('hcitool lescan')
            self.con.expect('LE Scan ...', timeout=10)
            print "Start scanning..."
        else:
            raise Error("no bluetooth error")
        exit_counter=0
        #some bluetooth dongles may upload duplicates
        repeat_counter=0
        dev_list  = []
        while True:
            pnum = self.con.expect(["WoHand",pexpect.EOF,pexpect.TIMEOUT], timeout=5)

lescanをしてWoHandという文字列を含む応答が返ってくることを期待しているようである。
試しにlescanしてみる。

$ sudo hcitool lescan
LE Scan ...
AA:BB:CC:DD:EE:FF (unknown)
AA:BB:CC:DD:EE:FF (unknown)
FF:EE:DD:CC:BB:AA (unknown)
FF:EE:DD:CC:BB:AA (unknown)

これら2つはSwitch Botなのだが、BBGWでやってもPi3でやっても同様にunknownになっている。それは先に進まんわけだ。
scan自体には成功しているので、Switch Botの腕(?)を動かすメソッドで直接BLEアドレスを指定してやれば動きそうである。
switchbot.pyの当該部分は以下の通りである。

def trigger_device(add):
    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'
    con.sendline('char-write-cmd 0x0016 570100')
    con.expect('\[LE\]>')
    con.sendline('quit')
    print 'Trigger complete'

なるほど。ではまずgatttoolで直接やってみよう。

$ gatttool -b AA:BB:CC:DD:EE:FF -t random -I
[AA:BB:CC:DD:EE:FF][LE]> connect
Attempting to connect to AA:BB:CC:DD:EE:FF
Connection successful
[AA:BB:CC:DD:EE:FF][LE]> char-write-cmd 0x0016 570100
Command Failed: Disconnected

うーん失敗。connectしてからコマンドを手で入力しているうちに切断されているような感じである。よってconnectの後にConnection successfulが返ってきた直後にchar-write-cmdを実行してみると

[AA:BB:CC:DD:EE:FF][LE]> connect
Attempting to connect to AA:BB:CC:DD:EE:FF
Connection successful
[AA:BB:CC:DD:EE:FF][LE]> char-write-cmd 0x0016 570100

(ちゅぃーん)
成功した!よって、trigger_device(add)に直接アドレスを指定するように、switchbot.pyを以下のように変えてみた。

def main():
    trigger_device('AA:BB:CC:DD:EE:FF')
    sys.exit()

これで実行すると

$ sudo python switchbot.py
Start to control
Preparing to connect.
Write command
Trigger complete

(ちゅいーん)
成功した!ただし、正常終了しない場合は永久に待ち状態になってしまうので適切にタイムアウトを設定する必要がある。

このように、switchbot.pyはまだまだα版のような状態なので、適切なメソッド群だけをライブラリとして別ファイルに追い出したり、スキャンの方法を変えたりと色々と改善の余地がある。Switch Bot用のvendor idが分かれば、Switch Botのみをスキャンすることができるはずで、恐らくスマートフォンアプリはその方法を採用しているはずである。
とは言え骨格部分はすでに完成しているので修正や改善は困難な仕事ではない。
が、バッテリーレベルの取得コマンドやセキュリティまわりが不明なので、それを自力で解明しようとするのはやや大変そうである。

スキャン失敗の追記(2017/07/03)

中の人にコメントを送ってみた所、

Oops, the github project is out of date now and unable to find bots since the SwitchBot broadcast format has been changed... We will fix this later...

Regards
Wonderlabs

と返信があり、問題は把握済みで直す予定とのことである。

Single Board Computer を持ってない普通の人専用デバイス

こんな所まで読み進めてきたド変態はSingle Board Computerの数枚や数十枚なら持っているだろうけど、そうでない正常な人用にはSwitch-LinkというBLE/Wi-Fiゲートウェイが公式に用意されている。
https://ksr-ugc.imgix.net/assets/014/448/371/cc3b44fc97d42800453826c8a2b97db1_original.png?w=680&fit=max&v=1478698927&auto=format&lossless=true&s=32cd3aca41e2b33d5ab25b37ae13f729

固定方法の提案

モーターのトルクに負けないようにかなり強力な両面テープ(剥離紙には3MのVHBと書いてある)で固定するようになっているが、これは剥がすのがなかなか大変で、最悪の場合壁面を破壊する恐れがある。
そこで私はこれ↓を固定に使うことを提案する。
コマンド™ タブ
3Mのコマンドタブは、強力に接着できる両面テープであるが、タブを引っ張っていくときれいに無理なく剥がせるという製品である。これの開発者は相当賢い。脳の一部を分けてもらいたい。
家の中、勤務先、工場内などで色々なものをこれで固定してきたが、今のところ問題が起きたことはない。天井にEnOceanのモーションセンサをコマンドタブで固定して2年以上経過したが、落ちてくる気配は今のところない。
Switch Botには一番小さいタイプSSを二枚か、タイプSを一枚で適切に固定できるはずである。
タブが見えると気になって発狂するという人には透明タイプのコマンドタブもあるよ。

応用

IFTTTと連携させるといくらでも複雑なことをできそうだし、Amazon Dashをわざわざこれで押すというネタで一笑い取るというのもアリ。
個人的な例では、温湿度センサと連動して換気扇を自動操作したいので早速実用を開始している。

感想

既存機器をIoT化できる製品としての完成度は高い。スマートフォンアプリも良くできていて、説明書を読まずに誰でも使える水準に達している。
価格は正直に言ってまだまだ高いとは思うが、あらゆるモノを遠隔操作できる可能性について少しでも考える人であれば購入するに足るものだと思う。しかし転売屋から一個7000円というボッタクリ価格で買うのは馬鹿げている。
最後に、スイッチが動作したことを確認する手段が無いので、生命維持用途とかには使わないほうがいいだろう。