SwitchBot API BLEを使う スマートホームの救世主か?遅延がないから快適!
毎度当ブログ「テック大家さん」をご覧くださいまして、誠にありがとうございます。
このブログで筆者の推しの一つであるSwitchBotに関して、今日はBLE(Bluetooth Low Energy)の観点から推していきます。お付き合い下さい。
筆者がSwitchBot推しの理由に関しては以前投稿した記事(以下のリンク参照)も合わせてご覧いただけると幸いです、はい。
例によって、プログラミングの話です。今回はArduino(C++)を使ってBluetooth Low Energy(BLE)を実装していこうじゃありませんか。
SwitchBot Web APIの課題は遅延が大きいこと
以前の推し記事の中で、SwitchBot社がAPI仕様をネットで公開していることが推しの理由の一つのであると言いました。
公開されているAPIの種類は2つあり、一つはクラウド経由のWeb APIです。もう一つは近距離通信のBluetooth BLE(Bluetooth Low Energy)の仕様です。
1つ目のWeb APIに関しては、別記事でユースケースを詳しくご紹介しています。例えば、下記のリンクでご確認下さい。
Web APIはわかりやすくて便利なのですが、クラウドを経由するとなると、どうしてもレイテンシー(遅延)が気になります。
APIを使ったアプリからなにか操作を行っても、数秒まってからようやく反応がある、といったイメージです。これは、上記の記事でも書いたのですが、SwitchBotクラウドのエンドポイントがUSにあるせいもあるでしょう。日本で何かトリガーを引いたとしてもそのリクエストは一旦米国のどこそこまで行って返ってくるわけです。反応が遅いのも当然でしょう。
BLE (Bluetooth Low Energy)のAPIを使う
そこで今回は、SwtichBot社が公開している第2のAPI、BLE(Bluetooth Low Energy)を使ってみましょう。
BLEはSwitchBotの各機器が家の中でハブや、スマホと通信に使う機能です。例えば、SwitchBot製品を買ってきて最初に使うときにスマホに登録しますが、このときはまだ機器はWiFiのアドレスがわからないからネットにつながりません。ネットにつながらないとスマホにもつながらないはずですよね。少し想像すればわかるのではないでしょうか。
では、どうするか?
BLEがそこを解決します。BLEの近距離通信によってスマホに登録できるというわけです。
Bluetoothは近距離通信の通信規格なので、家の中でしか使えません。逆にいうと、クラウドを使わず眼の前の直接機器同士で通信を行うので、応答はよいのです。
具体的に、Web APIとBLEのAPIの役割の違いを以下の図に示しました。
SwitchBot BLEを使うユースケース(開閉センサー)
さて、今回は一つの実装例として、BLE通信を使ってSwtichBotの開閉センサーのセンサー値を取得してみます。
ユースケースとしては、例えば、夜の暗い中、ドアが開いたら照明を自動でつけるというよくあるパターンです。
Web APIでこれをやろうとすると結構な遅延が発生します、ドアがあいて数秒して「よっこらしょ」と照明が付くようなイメージになります。こういったリアルタイムなユースケースではいまいち使えないのです。
一方、BLEのAPIだと現実的な応答速度で対応できます。
使うのは以下のSwitchBot商品。開閉センサーです。
SwitchBotの開閉センサーは、ドアの開閉だけではなく、ドアの前に人がいるのかいないのか、や、明るさもわかるという商品です。小さいし電池駆動なのにとても頑張った商品です。しかも3千円弱で、安い。
さて、開閉センサー相手に、BLEのAPIを使うと、どんなプログラムでつくれるのでしょう?
公開されているSwitchBot API のBLE版の資料をみてましょう。
以下がSwitchBot API BLE仕様のリンクです。
「API」と言っても、Web APIとは似ても似つかない、全くの別モノです。
APIというよりプロトコル仕様といったほうがよいでしょう。
しかもこの資料、読み込むにも難儀します。
英語で書かれているからという理由ではないでしょう。あまりに不親切に書かれているように感じます。筆者はこの仕様書をみて、どのレイヤのどこのパケットの説明しているのか、読み解くのにかなり苦労しました。
ここでは仕様書の中の一つの例として、開閉センサー(Contact Sensor)のプロトコルを使って得られる情報を読み解いてみます。仕様書のページに書かれている、RESP Packetというパケットの4バイト目までくらいをみてみましょう。
必要なところだけ抜き出すと以下のようになります。
バイト | 意味 | ビットごとの意味 |
---|---|---|
Byte: 0 | 機器タイプ | Bit[6:0]で機器タイプ(ASCII コード、0x64が開閉センサーの意味のよう) |
Byte: 1 | 状態 | Bit[6]: 0で動きなし。1で動きあり。 |
Byte: 2 | 電池残量 | Bit[6:0]: 7ビットを使って電池残量。 |
Byte: 3 | センサー値 | Bit[1:2]: 2ビットを使って、0でドアしまっている。 1でドア開いている。2でドア開きっぱなし。 Bit[0]:1ビット使って、0で暗い。1で明るい。 |
人の動きとかドアの開閉がわかりそうです。どうやら使えそうなことはわかりました。
でも、このパケットはどのように得られるのでしょうか…?
当初、著者によっては、謎でした。
アドバタイズパケットとは
仕様書の上記のテーブルの上に「Contact Sensor Broadcast Message」「The following table is the Service Data of SCAN_RSP」のようにあります。
上記の表の記述は、つまり、BLEのアドバタイズパケットの中身を記したもののようです。
アドバタイズパケットとは、デバイス(開閉センサー)から一方的に送信されるデータです。デバイスはBLEの用語ではペリフェラルとかサーバーとか呼ばれるものです。受ける側はセントラルとかクライアントとか呼ばれます。
今回は、開閉センサーのセンサー値を受けて何かしらの仕事をしたいと考えているので筆者はセントラルの機器を実装しようとしていることになります。
アドバタイズパケットの創出する間隔は機器に依存しますが、SwichBotの開閉センサーの場合は、1秒に1回位は出ているようです。つまり、センサーで扉が開いたことを検知すると私のつくるセントラルには遅くとも1秒後くらいにはその状態が届くイメージです。
ただし、アドバタイズパケットと言ってもその他諸々の情報も含まれていて、上の表はその中でもどこにあるのか?というのが仕様書からなかなか読み取れませんでした。
実際の動作をみながら仕様書の値と見比べて調べたところ、以下の図のようなイメージになっていることがわかりました。
段々に描いていますが、実際にはデータは全て羅列されて送られてきます。
BLEのアドバタイズパケットの仕様により、アドバタイズパケットの中身は複数のセグメント(?)に分かれていて各セグメントの先頭のバイトにはセグメント長が入ります。次のバイトはAD Typeと呼ばれるデータです。この値はBLEの規格で決まった値のようで、上の例だと、0x01がflag、0xffがベンダー固有データ、0x16がサービスデータ…のように決まってるようです。
そして、0x16のサービスデータに関しては、AD Typeの次の2バイトは16ビットのService UUIDと決まっています。このサービスIDはBluetooth Working Groupに登録が必要だそうで、SwitchBotの場合は登録しているのでしょう。仕様書の最初のページにちらっと0xfd3d書かれていました。実際にはエンディアンがひっくり返ってバイト列の並びは 0x3d、0xfdのような順番で並ぶので注意が必要です。
そして、Service UUIDの次のバイトから、SwitchBotの仕様書にあるByte:0…が始まる、というイメージです。
BLEアドバタイズパケットの仕組みを知らないと、SwitchBotの仕様書を読み解くのはハードルが高いです。
ArduinoでBLEの実装 概要と動作の様子
筆者のセントラルは、ArduinoのC++で作成します。
ボードはESP32 WROOMというチップが載ったものです。ESP32はBluetoothとWiFiも両方搭載していて便利に使えます。ネットでも情報が豊富です。Amazonで購入できるWayinTopというメーカーのボードです。
このボードでPlatform IOというプラットフォームを使いArduino(C++)で実装しました。
出力の確認用にブレッドボードでLEDを2つ使った回路を作りました。開閉センサーの前に人が来て動きがあったら赤いLEDが、ドアが開いたときに緑色のLEDが光る、といった動作を実現するためのサンプルです。実際には、LEDを光らせるだけの単純なものにしました。
BLEのセンサーの確認にはちょうどいい題材でしょう。
実際の動作は下の動画で御覧ください。ドアに近づくと赤いLEDが光り、ドアが開くと緑色のLEDが光る(動画では、ドアが閉じたときに緑のLEDが消える)ことがわかります。
ArudinoでBLE〜ソースコード公開
Githubで上記のソースコードを公開しています。
このコードでは、開閉センサーのほか、人感センサーの実装も含めています。センサーに応答して何かしらの作業をする機器の実装をするのに参考になるのではないでしょうか。
さらに踏み込んで…BLE GATTによる制御
ところで、SwitchBotのBLE仕様としては、アドバタイズパケット受信後にペリフェラルとセントラルを「コネクト」してコマンドのやり取りをする仕様も記載されています。BLE規格で言うところのサービス(Services)とキャラクタリスティック(Characteristics)を使った通信(GATT通信)も可能です。
GATTに関しては、別記事にしました。以下のリンクから合わせてご覧いただけると嬉しいです!
本日はここまで。最後までありがとうございました!
ディスカッション
コメント一覧
まだ、コメントがありません