SwitchBot Web APIで究極のDIYスマートホームの可能性を探る
前回の投稿で、IoTスマートホームを実現するSwitchBot製品の紹介をしました。
筆者がSwitchBotを選択する3つの理由を述べたのですが、その中の一つの要素としてAPI (Application Programming Interface)が公開されている、というポイントを上げました。
スマートホームというぐらいなので、この手のIoT製品はスマホで操作できたり、Google HomeやAmazon Echoのようなスマートスピーカーから利用できます。また、もっと高度な使い方をしたければIFTTTというサービスと連携することも可能です。
条件によって機器を動かしたり、止めたり、操作したり、という自動化がスマホの設定次第で可能になります。例えば、ドアに開閉センサーを開けておいて、ドアが空いたときに近くのスマート電球を点灯する、などの連携などはいかがでしょう。
スマホで設定が面倒でなければ、このくらいのことは簡単に実現でできてしまうというわけです。
ですが、ソフトウェア大好き「テック大家さん」としてはそれでは飽き足らず、自分でプログラムを書いて、自由にコントロールしたいのですよ。それが定め(!)なのです。
SwitchBot製品のWeb APIが公開されているということは、それができることを意味します。
そうです。それこそが、究極のDIYスマートホームと言えるでしょう!
というわけで、前置きが長くなりましたが、本日はSwitchBot Web APIを使ってどんなことができるのか探求してみようではありませんか。
Web APIについて理解する
Web APIといきなり言われてもなんのこと?という方のために少し説明しましょう。わかっているよ、という方は、以下のSwitchbot APIの見出しにジャンプしてください。
多少なりともWebの技術をご存知であれば、HTTPとかHTTPSというプロトコルのことは聞いたことがあるかも知れません。URLの先頭にある文字列で、https://〜〜という表現で有名なのでご存知でしょう。
プロトコルとは、サーバーとクライアントの間の手順を決めたものです。人と人とのコミュニケーションでは、英語だったり日本語だったりと言語違い、というのがあります。プロトコルもそんなようなもので、HTTPとかFTPとか、Sambaとか世の中にはさまざまなプロトコルがあります。ちょうど言語違いのようなイメージで複数あるわけです。
数あるプロトコルの中でも、WebサーバーとWebブラウザ(ChromeやEdgeなど)との間で最もよく使われるプロトコルが、HTTP(最近ではセキュリティが考慮されたHTTPSが普通)なのです。
ただし、WebサーバーとWebブラウザの間でやり取りするデータは、これまた多少なりともWebの技術をご存知であればHTMLやCSSといった形式でやり取りされる、というのはご存知ではないでしょうか。
Webブラウザというのは、いうなれば「HTML表示アプリ」です。HTTPを使ってサーバーから取得したHTMLを表示するアプリということです。
さて、話をWeb APIに戻します。Web APIというのは一般的には、HTTP/HTTPSを通信に使ってサーバーからデータを取得するためのインターフェース(機能)です。だた、クライアントはWebブラウザではありません。「取得したデータを解釈できるのであれば」どんなアプリでもいいのです。
HTML/CSSの表示は人間にとっては美しく読みやすい形式ですが、アプリのようなプログラムがデータ処理に使おうとすると少々複雑です。無駄なデータも多いです。そこで、アプリにとって使いやすい形式をやり取りする方法が考えられました。それがサーバーを呼び出すインターフェースとしてのWeb APIというアイディアだったのです。
JSONについて理解する
HTML/CSSは人間にとって良い形式、ということでしたが、では、アプリにとって都合がいい形式とは何でしょう?
その一つが、JSON(JavaScript Object Notation)と呼ばれるものです。
JSONはその名の通り、JavaScriptでプログラムを記述するときに、オブジェクトに値を詰めるときに書く形式。つまり、この形式で書くと、それ自体がJavaScriptのプログラムの一部になるということなのです。
「わしゃ、Pythonが好きだからJavaScriptなんて知らない」
という、方もいるかも知れません。でも、名前とは異なり、最近は、たいていどんなプログラミング言語でもJSON形式を扱いやすくするライブラリが存在します。
この形式があまりに(?!)便利なのでどのプログラミング言語でも、この表現形式だけを採用するようになりました。
例えば、以下のようなものです。
{"type": "dog",
"name": "Hachi",
"age": 3,
"parents: [
{"type": "dog",
"name": "John",
"age": 10,
},
{"type": "dog",
"name": "Mary",
"age": 11
}]
}
パラメータの名前(typeなど)とそのパラメータの値(dogなど)が「:(コロン)」で区切られるようなフォーマットです。これで、文字列、数字、配列、構造体など、基本的なデータ構造は表現できます。
一般にWeb APIと呼ばれるものが扱うデータ形式は、アプリが処理しやすければ何でも良いのです。昔は、XMLなどといった形式が流行った時期もありました。
ただ、昨今のWeb APIでは、サーバへのリクエストも、サーバーからの応答も、JSON形式を使ってやり取りすることが多いようです。その方が、クライアントでもサーバーでも動作するソフトウェアを開発する言語を選ばないわけです。先程述べたように、どのコンピューター言語でもJSONを解釈できる仕組みが揃っているからです。
そして、以下で説明するSwitchBotのAPIもまさに、JSON形式でインターフェースの仕様が定義されているのです。
SwitchBotのAPIの仕組み(ハブが必要)
SwitchBotのWeb APIはSwitchBot社が運用している、SwitchBotクラウドを呼び出すためのインターフェースです。SwitchBotの製品はすべて、スマホの「SwitchBotアプリ」(Google Play Store、App Store)で設定して操作するのが普通の使い方です。
このSwitchBotアプリが画面上に表示している機器の情報や、アプリから実行しているコマンドがあります。これをプログラム的に呼び出すことができるようにしているのが、SwitchBotのWeb APIです。
全体像は下図のようなイメージです。
この図にある、クライアント(自分でアプリを作ると想定している)とSwitchBotクラウドサーバーの間のインターフェースがSwitchBot のWeb APIになります。
Web APIを使うためには、ユーザの家の中にあるSwitchBotの製品群とクラウドが何かしらの方法でひも付いていなければなりません。そのひも付けを行うのが、SwitchBot製品群の中でもひと際異彩を放つ「ハブ」という製品です。ハブに関してはより詳細な解説記事を書きました。こちらもご参照ください。
クラウドサーバーを呼び出す際には、以下で認証について詳説するようにユーザーのアカウトにひも付く形で情報が取得できます。
これによりクラウドサーバーは筆者の所有するSwitchBot製品を見つけることができるというわけです。
SwitchBotのAPIはなにができるのか?
それでは、さっそくSwitchBot Web APIとはどんなものか、そして、なにができるのか見ていきましょう。
公開されている仕様は、以下のリンク(英語)にあります。
この資料、ひとつのファイルがパット見すごく長くて、ひるむかも知れません。ただ、それほど難しいことはないです。
ざっくり全体像を説明しますと、以下のようになことが整理されています。
- 認証(authentication)
- 機器一覧の取得(Get device list)
- 機器の状態の取得(Get device status)
- 機器に対するコマンドの送信(Send device control commands)
- シーンの操作(Scenes)
- 機器からの通知(Webhook)
ひとつひとつ詳しく見ていきましょう。
認証(authentication)
認証は少し複雑な工程です。一般的にWeb APIで認証が必要になる場合、HTTPのヘッダ部分にTokenと呼ばれる「鍵」のような文字列を渡すことが多いです。
SwitchBotのAPIの場合は、そのようなTokenに加えて、APIの呼び出しごとに異なる署名がつくような仕組みを考えているようです。API仕様の最初の方に、各プログラミング言語ごとに、実装例が書かれています。
signやnonce や現在時刻(tと表現)といったキーワードでその作り方や使い方を実際のコードで説明ています。このコードを使うと簡単に認証機能を実現できます。
Tokenを入手するには、SwitchBotアプリが必要です。仕様書に以下の記載があります。
Please follow these steps,
SwitchBot API v1.1仕様より
- Download the SwitchBot app on App Store or Google Play Store
- Register a SwitchBot account and log in into your account
- Generate an Open Token within the app a) Go to Profile > Preference b) Tap App Version 10 times. Developer Options will show up c) Tap Developer Options d) Tap Get Token
- Roll up your sleeves and get your hands dirty with SwitchBot OpenAPI!
簡単に言うと、アプリにログインして、Profile > Preferenceのページに進み、App Versionの部分を10回タップすると、Developer Optionsが表示されます。そこからTokenを取得するという流れです。
簡単でよいですねぇ。
機器一覧の取得(Get device list)
SwitchBot製品を購入すると、すべてSwitchBotアプリに登録することになります。
SwitchBotアプリに登録した機器はWeb APIからも一覧として取り出すことができます。機器一覧の取得APIは、これらの機器の一覧を取得する基本的なインターフェイスです。
結果は以下のようなJSON形式で得られます。
deviceNameの値は、SwitchBotアプリで表示されるもです。わかりやすいですね。
また、deviceIdというパラメータがあります。これは、後ほど、各機器の状態取得や操作を行うために必要になる機器固有のIDです。後のAPI呼び出しを行うには、この一覧で操作したい機器のdeviceIdを知る必要があります。
それぞれの機器の情報として、deviceTypeというパラメータもあります。これは、各機器がどの製品なのかを示すものです。以下の例では、スマートプラグ(コンセント)には「Plug Mini (JP)」とありますし、スマート電球には「Color Bulb」と値が設定されています。
感のいい方はおわかりのように、deviceTypeごとに、状態取得や操作でできることが異なるのでその仕様は機器ごとに定義されています。
例えば、機器をOnにしたりOffにしたりするのはスマートコンセントもスマート電球も一緒ですが、色を変えたりするのはスマート電球しかできませんよね。その違いはdeviceTypeで表現しているわけです。
{
"statusCode": 100,
"body": {
"deviceList": [
{
"deviceId": "XXXXXXXX",
"deviceName": "プラグミニ(JP) ",
"deviceType": "Plug Mini (JP)",
"enableCloudService": true,
"hubDeviceId": ""
},
{
"deviceId": "YYYYYYYY",
"deviceName": "スマート電球",
"deviceType": "Color Bulb",
"enableCloudService": true,
"hubDeviceId": ""
},
{
"deviceId": "ZZZZZZZZ",
"deviceName": "スマート電球2",
"deviceType": "Color Bulb",
"enableCloudService": true,
"hubDeviceId": ""
},
...
機器の状態の取得(Get device status)
デバイスID(deviceId)がわかると、その機器の状態を取得することができます。
機器の状態は、スマート電球なら今光っているのか消えているのか、開閉センサーなら今開いているのか閉じているのか、といった内容になります。
Get device statusで記載されている仕様では、デバイスタイプごとに、どのような情報が状態として取得可能なのかを定義しています。
仕様書にあるように、HTTPのGETコマンドのURLに上の機器一覧で得られたdeviceIdを指定してあげると指定した機器の状態が得られます。
GET /v1.1/devices/{deviceId}/status
仕様書にあるように、deivceIdが示す機器が温湿度計であれば、以下のような状態が取得できます。
{
"statusCode": 100,
"body": {
"deviceId": "C271111EC0AB",
"deviceType": "Meter",
"hubDeviceId": "FA7310762361",
"humidity": 52,
"temperature": 26.1
},
"message": "success"
}
この例では、温湿度計の湿度(humidity)が52%、温度(temperature)が26.1度ということがわかるわけです。便利ですよねぇ。
機器に対するコマンドの送信(Send device control commands)
機器を操作するためには「コマンド」を機器に送ります。受け取る側の機器も製品カテゴリによりコマンドが異なります。
例えば、スマート電球なら「色」を指定して電球をつけてほしいし、スマートプラグであればオンにしたいのか、オフにしたいのか、指示したいです。つまり、コマンドの送信にはこちらから送るパラメータが必要になります。
したがって、HTTPプロトコルのPOSTにより、JSON形式でパラメータをクライアントから送る形のインターフェースとなっています。
POST https://api.switch-bot.com/v1.1/devices/F7538E1ABCEB/commands
のようにデバイスID(deviceId)指定でコマンドを送ります。機器の種類(deviceType)によって受け付けるコマンドが異なります。
以下の例ですと、相手はBotです。「オン」コマンド(turnOn)を送っています。
{
"command": "turnOn",
"parameter": "default",
"commandType": "command"
}
このコマンド送信の仕組みを使うと赤外線リモコンで反応する機器は、SwitchBot Web APIから制御できます。筆者は、Fitbitというスマートトラッカーに扇風機を制御するアプリを組み込んでみました。ソースコードも公開しています。こちらも合わせてご覧ください。
シーンの操作(Scenes)
シーンは、SwitchBot製品を組み合わせて同時に目的の状態にするためのSwitchBot固有の機能です。
例えば、「朝」というシーンを作っておき、朝に作成した「朝」シーンを実行すると、カーテンが開いて、掃除機が動き出し、エアコンのスイッチをいれ、コーヒーメーカーをオンにする、みたいな一連の動作をさせることができます。(それが有益か同かはともかく…笑)
SwitchBotのWeb APIを使うと、シーンを一覧したり、その一覧の中からIDを取り出して「実行」することができます。
シーンは、SwitchBotアプリでつくる(設定する)のですが、Web APIでは一覧の取り出しと実行のみで、つくることはできないようです。
筆者はシーンについてあまり有用に感じないのと、上の機器の操作に関する一連のAPIが理解できれば、シーンのAPIも理解できるはずです。よってここでは詳細の説明は省きます。
機器からの通知(Webhook)
さて、これまでの説明でSwitchBotのWeb APIを使うと、クライアント(例えば自作のアプリ)から機器の操作や状態の様子を知ることができることはご理解いただけたのではないでしょうか。
しかし、機器側の状態が変わった場合、それを知るにはどうするのでしょう?
具体例にいうと、開閉センサーがドアが開いたことを検知したというケースです。
SwtichBot製品には人感センサーや開閉センサー、温湿度計など、センサーがついていてそれ自体の状態が勝手に変わったり、状態を検知したりする機能を持つ製品があります。
クライアント(アプリ)側で機器側の変化を検知して、なにか別のタスクを実行したい。そんなケースも往々にしてあるでしょう。
そんなときに使うのがWebhookです。Webhookという言葉自体はWeb技術の一般的な用語です。これの意味するところは通知をWebサーバーが受けとることができる、というものです。
一般的に、HTTPはクライアントからサーバーを呼び出す、という方向で通信が成立します。しかしながら、なにかの状態を持っているのがサーバーでそれをクライアントに伝えたい場合は、逆方向の通信が必要になります。
これを実現するための技術がWebhookです。
Webhookのトリガーを引くサーバーは、あらかじめクライアント(ユーザー)からURLの指定を受けておきます。サーバーで何かイベントが発生した場合に、サーバーから登録されたURLを呼び出す、ということで通知を送信します。
SwitchBotのWebhookも同様なのですが、他のAPI操作とは異なりWebhookを利用するにはちょっとしたコツがあります。
それは、クライアント側がURLを持っていないといけないということです。通知を受け取る側が、インターネット上のサーバーとしてURLがついている必要があるのです。クライアントなのにサーバー機能でないといけいないわけです。
したがって、Webhookによる通知を受ける取るのは、スマホアプリだとちょっと難しいです。
できないことはないでしょうが、インターネット上のどこからでもアクセス可能な一意のURLをスマホが持っていないといけない、つまりサーバーソフトをスマホ内に作らなければいけません。仮にサーバーをスマホ内に作ったとしても、スマホがどのネットワークにつながっているかによって動作したりしなかったり、状況が変わる可能性もあります。このブログ「テック大家さん」でも記事にしたことがあるややこしい話になってしまいます。技術的なハードルが1段高い話になります。
Webhookの仕組みを利用してSwitchbot機器のイベントを受け取るためにはインターネット上で何かしらサーバーを自ら立てるのが現実的です。そのサーバーのURLを持って初めてSwichBot機器からの通知が得られます。
SwitchBotのWeb APIのWebhook機能は、ユーザー、つまり「APIの利用者が用意したサーバー」のURLを登録するためのものです。
SwichBotのWeb APIの仕様としては、以下のようなHTTPコマンドが用意されています。これによりURLの登録ができます。
POST https://api.switch-bot.com/v1.1/webhook/setupWebhook
登録すると、仕様書の「Receive events from webhook」という章で説明されているパラメータ付きでそのサーバーが呼ばれることになります。
筆者は、SwitchBotのWebhookを使って機器からの通知を受ける実装をしてみました。つまり、サーバー側のプログラミングです。その詳細を別途記事にしました。以下のリンクからご覧いただけると幸いです。
さて、使ってみると、いくつか問題があります。
まず、登録するURLはSwitchBotクラウドではリスト(配列)で持つような仕様になっているのですが、実際にやってみると登録できるURLは一つだけでした。バグなんでしょうか?
また、このように登録するサーバーは、誰でもアクセス可能にしか作れない、ということです。Webhookの仕様として、認証のような仕組みはありません。例えば、SwitchBotクラウドのIPアドレスからしかアクセスできないようにするなど、別の工夫が必要になるということです。
それだけではありません。
次の節で示すようなパフォーマンス上の課題もあるのです。
技術的には面白い仕組みだと思いますが、実用的なものが作れるかというと、ユースケースによっては難しいでしょう。
以下も合わせてお読み下さい。
課題はクラウドの反応が悪いことか?!
api.switch-bot.comと言うサーバーはpingコマンドを使って確認すると、Amazon AWSのus-east-1にあるとのこと。
つまり、日本でSwitchBotのAPIを叩くと要求は米国の東海岸にあるデータセンターまで行ってしまうということのようです。ということは結構反応が悪い可能性があります。いえ、可能性ではなく実際やってみると、あまり反応がよくありません。
ユースケースによりますが、リアルタイムに応答しないと不自然に感じるようなシナリオを実現しようとすると実用的に耐えないでしょう。
具体例をあげると、開閉センサーの応答をWebHookで受けてコンセントの電源をいれるとか、というシナリオだとドアを開けてから数秒経って、カチっと電源が入るみたいな感じになるかと思います。この体感で変に感じないようならよいのですが、リアルタイムに電源入ってほしいですよね、きっと。
ですので、ユースケースは検討が必要です。
どうしてもリアルタイムに反応してほしい、という場合は別の方法があります。SwitchBot製品は全てではありませんが、Bluetoothのプロトコル仕様(BLEの仕様)が公開されています。それを使うと、クラウドを経由することなく機器の操作ができますので、レスポンスが全然違います。
SwitchBotのBLEの仕様に関しては長くなるので別途記事にしています。以下のリンクで解説しておりますので合わせてご覧いただけると幸いです。
ディスカッション
コメント一覧
まだ、コメントがありません