SwitchBotで赤外線リモコン Web APIでリモートから機器操作
さて、本日も例によって、筆者の最近の推しであるSwitchBotのネタです。これまでいくつかSwitchBot関連の記事を本ブログ「テック大家さん」で取り上げてきました。SwitchBotはスマートホームを実現する、文字通り"スマート"な製品群の総称なのですが、本日はその中でも、どこのご家庭にも1つや2つある「赤外線リモコン」(略して、リモコン)をスマートにしてしまう、という内容です。
よろしくお付き合い下さい。
この記事で目指すところ
この記事では、SwitchBotのハブ2という製品を使って、どこのご家庭にもある「赤外線リモコンが同梱されている製品」を遠隔操作します。
そのような機器として、何が思いつきますか?
テレビ、エアコン、扇風機、照明器具、などなど色々とあることでしょう。このような機器は赤外線リモコンが同梱されています。リモコンを使うと、目には見えないけれども、明らかにリモコン発射される「赤外線」という光が機器を操作します。ですので、この光が届かない範囲に機器があるとリモコンのボタンを押しても操作できない、というのは日々体験していることでしょう。
このような機器をネット経由で遠くから操作してみましょう。しかも、自分でプログラムを書いて、より賢いコントロールまで実現してしまおう、というのが本日の記事の目指すところです。
そんなことできるのでしょうか?
それを実現するのがSwitchBot ハブ2という製品なのです。
SwitchBot ハブ2の謎めいた名前と機能に関しては、別記事にて詳しく書いています。こちらも併せてお読みいただけるとより理解が深まります↓
SwitchBotでリモコンをスマートにするには
SwitchBot ハブ2は、リモコンの代わりになる製品です。
ハブ2から「赤外線」が送出されます。「リモコンの代わりになる」とは言え、テレビなどのリモコンのようにたくさんのボタンが付いているわけではありません。ではどのように使うのかというと、スマホのアプリに表示される画面上のボタンを押すのです。
仕組みを図で説明したほうがわかりやすいでしょう。
WiFiなどにつながるスマートフォン経由でSwitchBotハブ2にコマンドが送られます。このコマンドをハブ2がリモコンの赤外線に変換してくれるわけです。つまり、ハブ2から出てくる赤外線はリモコンが出すものと同じ、というわけです。
また、家の中にはテレビのリモコンやエアコンのリモコンなど複数のリモコンがあるでしょう。ところが、このSwitchBotハブ2はそれらの複数のリモコンの仕事をこれ一台でやってくれるスグレモノ。大抵の機器のリモコンコードが登録されているので、お客さんはその中から自分が操作したい製品を選んで操作することが出来ます。
明らかにマイナーな製品をお持ちの場合でも大丈夫です。SwitchBotには、リモコンコードの学習機能があります。操作したい機器に付属してきたリモコンのボタンをハブ2に向けて「これを覚えろ!」とやると、そのコードを記憶してくれ、リモコンの代わりをやってくれるといのです。
さて、ここまでの説明でハブ2がリモコンの代わりになるのはご理解いただけたかと思いますが、「スマホで操作するのは面倒だから自分には不要だ」と思ったら大間違いです。
SwitchBot製品は後述のWeb API(Application Programming Interface) と言う仕組みがあり、仕様が公開されています。これを使うと、誰でも自由にプログラムが書けます。プログラムを書くことで自動で機器を動かしたり、何かをきっかけに機器を操作したり、いくつかの機器を同時に動かしたり、といったことが可能になります。
自分でプログラムなんて書かないよ、という方でも大丈夫。
誰でも自由にプログラムが書けるということは、誰かが書いた便利なプログラムを使えるということです。そういう意味で、APIの仕様が公開されているのは大きなメリットなのです。
APIが公開されているのが筆者の「SwitchBot推し」ポイントで、以下の記事に詳しく書いています。合わせて御覧ください↓
Web APIの仕組み
ここからは、実際にWeb APIをつかった簡単なプログラミングで、SwitchBotハブ2から赤外線リモコンのコマンドを送出してみましょう。
まずは全体像から。
上の図でいうと、この記事で作ろうとするのは、図中①、パソコンで動作するプログラムです。
自分の目の前にあるリモコン式の扇風機を動かすために、わざわざSwitchBotのクラウドを経由するという大げさな構成です。でも、この仕組みでプログラムをつくると、実はパソコンが家の外にあってもネットにつながってさえいれば、家の中の扇風機(だけではない!)を操作できるという仕組みになっているのです。
①のパソコンで動作するプログラムは②で表している、SwitchBot クラウドが定義しているWeb API を呼び出します。SwitchBotクラウドは何かしらの仕組みで(非公開)家の中にあるSwitchBotハブ2とやり取りします(③)。その結果、④にあるようにハブ2から赤外線コマンドが送られて、扇風機が動作する、という流れです。
実際にプログラミングしているときはこのような図を意識する必要はないかも知れません。ですが、プログラムが動作しないときに、どこに原因があるのか理解するのに役立つでしょう。
Web APIでリモコン機器を操作する準備
SwtichBotの機器をWeb APIを使って操作する場合、最初にSwitchBotアプリで機器登録をするなどいくつか手順が必要です。
一つずつ見ていきます。
SwitchBotアプリで機器の登録する
Web APIを使うと、後述のように家に設置したSwtichBot機器をリストアップすることができます。しかし、そのためにはあらかじめSwitchBotのアカウントを作成し、そのアカウントでログイン後、機器の登録が必要になります。
機器の登録としては、以下の2つの手順が必要です。
- SwitchBotハブ2を登録する
- ハブ2上で「赤外線リモコン」の登録をする
まずは、SwitchBotアプリの「デバイスの追加」画面で購入したSwitchBotハブ2を登録します。手順はアプリ上でわかりやすく提示されるので、それに従うと簡単にできます。
次に、ハブ2の設定画面を開き「赤外線リモコン」の登録を行います。リモコンの「学習」の方法は複数ありますが、画面に従って行うと登録できるでしょう。
赤外線リモコンで操作したい場合はこのような二段階の登録作業が必要になります。
設定後のハブ2の設定画面です(下図)。まるでマークしたところが登録した赤外線機器になります。
ちなみに、ここまでの操作はWeb APIを使うかどうかにかかわらず、SwitchBot製品で赤外線制御したいときは必要になる作業です。したがって、この設定が終わると、SwtichBotアプリから機器の操作ができるようになります。
SwitchBotアプリからトークンとシークレットを取り出す
以上でSwitchBotアプリから機器操作ができるようになったわけですが、Web API経由で使うためにはもうひとつ準備が必要です。
それは、開発者用の情報(トークンとクライアントシークレット)の取得です。
やり方は、SwitchBot Web API仕様のGetting startedに情報があります。
曰く、
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
どこかで聞いたことのあるような方法ですが、設定画面の「アプリバージョン」を10回タップして「開発者向けオプション」を開くと「トークン」と「クライアントシークレット」が得られます。
Web APIでリモコン機器を遠隔操作する
トークンとシークレットが得られると、いよいよWeb APIを使ったコードが動作する状態です。
ここから先は、SwitchBot Web APIの仕様のとおりに、REST 形式のAPIを呼び出していきます。プログラミング言語に関しては、JavaScript (NodeJS)を使っていきますが、HTTP/HTTPSの呼び出しと、JSON形式のデータを扱える言語であれば大抵の言語で使えるでしょう。
ここでは、赤外線リモコンを操作する機器にリモコンコマンドを送る手順を説明します。手順としては、
- デバイスリスト(機器一覧)を取得し、リストから対象機器のデバイスIDを取得する
- デバイスIDをパラメータに含めてコマンド送信のAPIを呼び出す
ということをやります。
赤外線機器のデバイスIDを取得する
まずは、REST APIのエンドポイント、baseUrl = 'https://api.switch-bot.com’に対して、GETメソッドで、/v1.1/devicesを呼び出します。
実際のコードは以下のようになります。
ここで、HTTPのヘッダに含めるtoken、sign、nonce、tといった変数は、SwitchBot Web APIの仕様にある認証のための実装例をそのままのを使って代入しています。上で取得したトークンやシークレットも認証のコードで使用します。
const devices = () => {
const url = baseUrl + '/v1.1/devices'
const method = 'GET'
fetch(url, {
method: method,
headers: {
"Authorization": token,
"sign": sign,
"nonce": nonce,
"t": t,
'Content-Type': 'application/json',
}
}).then((r) => r.json()).then((json) => {
console.log('------ devices -----')
console.log(JSON.stringify(json, null, ' '))
})
}
上のコードを実行して正しくSwitchBotクラウドに認証されると、以下のようなJSON形式の出力が得られます。
{
"statusCode": 100,
"body": {
"deviceList": [
{
....
},
{
"deviceId": "XXXXXXXXXX",
"deviceName": "新ハブ2",
"deviceType": "Hub 2",
"enableCloudService": true,
"hubDeviceId": ""
},
{
...
}
],
"infraredRemoteList": [
{
"deviceId": "01-202406271346-YYYYYY",
"deviceName": "リビング扇風機",
"remoteType": "DIY Fan",
"hubDeviceId": "XXXXXXXXXX"
},
{
"deviceId": "01-202407311539-ZZZZZZ",
"deviceName": "サウンドバー",
"remoteType": "DIY Speaker",
"hubDeviceId": "XXXXXXXXXX"
}
]
},
"message": "success"
}
構造としては、bodyの下に、「deviceList」と「infraredRemoteList」という2種類のリスト(配列)が見られます。
deviceListには、登録したSwitchBotの製品が並びます。
infraredRemoteListには、ハブに登録した「赤外線リモコン」(機器)のリストが並びます。
どちらも、スマホのSwitchBotアプリで登録操作をした項目ですね。このリストの各デバイスを表すオブジェクトの中のプロパティdeviceIdの値を使っていきます。例えば、「リビング扇風機」で登録した機器にコマンドを送る際はリビング扇風機のdeviceIdとして、上の例だと、"01-202406271346-YYYYYY"が必要になります。
もう一つ注意しておきたいプロパティはremoteTypeの値です。上のJSONの例だと、DIY Speakerや DIY Fanとなっている箇所です。コマンドを送る際にこのタイプによって打てるコマンドが異なるようですので、すこしだけ意識しておきましょう。
SwtichBotハブ2からAPIで赤外線コマンドを送る
今回のテーマは、赤外線リモコンをSwitchBotハブ2で置き換えるというテーマなので、上記の機器一覧の中でも、infraredRemoteListに並んでいる機器のdeviceIdを使っていきます。
コマンドの送り先は、baseUrl + "/v1.1/devices/${deviceId}/commands
“という宛先で、HTTPのPOSTでコマンドを送ります。deviceIdが上の機器一覧で取得したdeviceIdプロパティの値になります。
POSTのbodyにはJSON形式のオブジェクトを含めるのですが、この内容は仕様書を注意深く参照する必要があります。仕様の「Command set for virtual infrared remote devices」という項目に表があります。この表のdeviceTypeという箇所が、先の機器一覧で取得した際にあったremoteTypeの値のようです。(登録の仕方によって"DIY"という文字列が付くようですが、ここの仕様はどこにも記載がなさそうです)。
例えば、上の例でremoteType="DIY Fan"となっている「リビング扇風機」について考えてみましょう。仕様を見るとdeviceType がFanの項目として以下のような一覧になっています。(表の行は、deviceType, commandType, Command, command parameter, Description、のように並んでます)
たとえば、扇風機のリモコンに「一番遅い回転数」にするボタンを送りたければ、lowSpeedというコマンドを送る必要があるという風に読めます。
この表の情報から、HTTP POSTのbodyには、JSON形式の以下を含めればよいというわけです。
{
commandType: 'command',
command: "lowSpeed",
parameter: 'default',
}
ということで、扇風機の回転数を変更するコマンドは、以下のようなコードで送出されます。
const fanSpeed = (deviceId) => {
const url = baseUrl + `/v1.1/devices/${deviceId}/commands`
const method = 'POST'
const body = JSON.stringify({
command: "lowSpeed",
parameter: 'default',
commandType: 'command'
})
fetch(url, {
method: method,
headers: {
"Authorization": token,
"sign": sign,
"nonce": nonce,
"t": t,
'Content-Type': 'application/json',
'Content-Length': body.length,
},
body: body,
}).then((r) => r.json()).then((json) => {
console.log(`------ fan speed command (deviceId: ${deviceId}) -----`)
console.log(JSON.stringify(json, null, ' '))
})
}
さて、API仕様の同じ表の一番最初の項目は以下のようなものです。
deviceTypeは「All home appliance types except Others」と書かれています。つまり、大抵の家電は電源Onと電源Offが必要だよね、ということですね。
これに従うと、電源を入れるコマンドは、deviceTypeにかかわらず、以下のようなJSONを送ればよいわけです。
{
commandType: 'command',
command: "turnOn",
parameter: 'default',
}
だいたい、わかりましたでしょうか?
筆者はこの仕組みを使って、Fitbit Versa4 というスマートトラッカー(スマートウォッチ?)のアプリを作り、腕から扇風機を操作するアプリを作ってみました。ご興味があれば、そちらの記事も読んでみて下さい↓
では本日は、この辺で…
ちなみに、本日の記事はハブ2を用いましたが、温度計のついていない「ハブミニ」でも同じようにWeb APIは使えます。
ディスカッション
コメント一覧
まだ、コメントがありません