テクノロジの無駄づかい

日々の「ステュディオス」を求めて遠回りしがちなエンジニアの記録

Google Homeでリモコン操作をやってみた。その1

Amazon Echoの招待がなかなか届かないので*1Google Home を買ってみた。 使ってみて、ちょっとしたことを声だけで操作できるのは思った以上に便利だと感じる今日このごろ。

音楽を流したり、ちょっとした質問に答えてくれるのも便利だし、なぞなぞとか早口言葉をやってくれるのも面白いのだが、 やはり家電機器の操作もやってみたい。

とりあえず、最初は定番、電灯のON/OFF。我が家のシーリングライトは赤外線リモコン操作なので、リモコン信号を操作できれば実現できるだろう。

最初から連携するデバイスを購入してしまえばもっと簡単なのかもしれない。 しかしデバイスメーカーのサーバサイドサービスに依存するとサービスが終了した場合に機器ごと使えなくなってしまいかねないので、なるべく自作できるものの組み合わせで実現したい。

で、以下の組み合わせでやってみた。

うーん、どうもやりたいことのシンプルさの割に実現する仕掛けが複雑すぎるように思う。 しかし、2018年正月の時点ではインターネットに晒す自前サーバの運用なし構成ではこれでもシンプルな方かと思う。

以下にそれぞれの連携方法について書く。

Google Assistant -> IFTTT -> beebotte

IFTTTにGoogle Assistant のトリガーが用意されている。 そのトリガーとWebhookを利用して beebotte にメッセージを送る。 ここまでで、Google Assistantへの音声入力をプログラムから扱える形のメッセージに変換することになる。 そこまでを順に説明する。

Beebotte の設定

IFTTTのアプレット登録に、REST APIのエンドポイントが必要になるので先にBeebotteの設定を行う。

Beebotte はIoT向けのクラウドサービス。REST API や MQTTをサポートして、接続された機器にリアルタイムにメッセージを通知することができる。今回はこのサービスをMQTTブローカーとして利用する1。 50,000メッセージ/日までならフリープランで利用できる。個人ユースにはそれで十分であろう。

まずはアカウントを登録する。フリープランならユーザ名、メアドとパスワードだけで登録できる。 アカウントを作成したら、チャネルとリソースを登録するよう促される。 特に迷うところはないと思う。 登録したらこんな感じ。

f:id:HeRo:20180103182319p:plain

Channel名とresource名で REST API や MQTTのエンドポイントが決まる。 また Channel Token が発行されるが、これは後にIFTTTのアプレット登録やNode-REDから接続する場合に必要となる。

IFTTTでのアプレット登録

Google Assistant トリガーは4種類ある。用途に応じて使えば良いが、今回は Say a phrase with a text ingredient を利用する。これは音声入力したテキストをアウトプットに渡せる。今回は電灯の操作なので、オンオフを渡して制御する。

入力項目は次の通り。

設定項目 設定値
What do you want to say? 寝室ライト $
What's another way to say it? (オプションなのでよしなに)
And another way? (これもオプションなのでよしなに)
What do you want the Assistant to say in response? 寝室ライト $ しました。
Language Japanese を選択

What do you want to say? の設定が肝となる。 寝室ライト $と設定したが、「寝室ライト」の部分が 「OK Google,」の後に続くコマンドワードで何をしたいのかを示すキーワードとなる。 「$」はコマンドワードのパラメータとして設定できる音声入力のプレースホルダーで、ここでは「オン」あるいは「オフ」を想定している。 つまり、「OK Google, 寝室ライト オン」とGoogle Homeに話しかければ、このアプレットが起動して、$=オン がセットされるということとなる。

What do you want the Assistant to say in response? は音声コマンドを復唱させることにより、入力が正しいかどうか確認するために設定する。

続いて、アプレットの後半、アウトプットの設定。 このアプレットの目的は beebotte にメッセージをパブリッシュすること。パブリッシュの手段としてはbeebotteのREST APIを利用する。 そのため、アウトプットには Webhookを利用する。

設定は次の通り。

設定項目 設定値
URL http://api.beebotte.com/v1/data/publish/<Channel名>/<resource名>?token=
Method POST を選択
Content Type application/json を選択
Body {"data": [{"room": "bedroom","device": "light","action":"{{TextField}}"}]}

URL にはbeebotteのメッセージパブリッシュのRESR APIを指定する。先に登録した チャネルとリソースをパスにはめこんで、認証のためクエリパラメータtokenChennel token を設定する。 前述の スクリーンキャプチャに合わせると http://api.beebotte.com/v1/data/publish/MyIoT/light_at_bedroomというのがAPIのURLとなる。

Body には、APIに送信するデータを設定する。ここにはJSON形式で、後にNode-REDで処理する時に必要になりそうなパラメータを送信できるようにする。{{TextField}}には $ にセットされたテキスト、すなわち「オン」または「オフ」が入ることになる。

beebotte に Node−REDで接続

前節までで、Google Homeへの音声コマンドが、beebotte 上のメッセージに変換されるところまでができている。 あとは、Node-REDでそのメッセージを受け、処理するだけ。

Raspberry Pi やその上で動くNode-REDの準備は次に書いてあるとおり。

Node-REDではデフォルトで MQTTがサポートされている。 beebotte と連携するには mqtt in ノードを利用する。

mqtt in ノードの設定はこんな感じ。 トピックには [Channel名]/[resource名]を設定する

f:id:HeRo:20180107191427p:plain

mqtt in ノードのサーバ設定は別フォームが開くので次のように設定する。 セキュリティタブで、ユーザ名に token:[Channel Tokem] を設定するのが肝。

f:id:HeRo:20180107190740p:plain

設定項目 設定値
サーバ mqtt.beebotte.com
ポート 8883
SSL/TLS接続を使用 チェックする。TLSの設定は不要
ユーザ名 token:[Channel Tokem]

設定が正しく、beebotte に接続できる場合にはフローのデプロイ後、次のようにノードに 接続済 と表示される。

f:id:HeRo:20180107192117p:plain

動作確認

ここまでの作業を確認すために次のようなストリームを作って、Google Home => Node-REDに届くメッセージを確認する。

f:id:HeRo:20180108000451p:plain

OK Google, 寝室ライト オン」とGoogle Homeに話しかけて、 Debugノードのデバッグ出力に送ったメッセージが出力されれば成功。

さて、

この先は Node−REDでフローを作って、赤外線を発するまでだけど、ここまでで結構長くなったので、続きはまたあとで。

その2に続く。

hero.hatenablog.jp


  1. IFTTTはまあ大丈夫だろうけど、デバイスメーカーのディスコンを嫌う割にbeebotteなどというイマイチ聞いたことないサービスを使って大丈夫か?とも思ったが、いざとなればHerokuでCloudMQTTを動かすという代替策があるので採用した。ただし、CloudMQTTは無料では同時接続デバイスが10と少々少ない。

*1:今はやっと手元に届いたところ。