Google Homeを自由に喋らせたい

Pocket

raspberry pi 3

Google HomeとNature Remoでスマートホーム化した我が家です。

我が家のスマートホーム化計画

その中でもお気に入りはGoogle Home+IFTTTを使って、LINEをするという仕組みです。子供達がGoogle Homeに喋った内容が、パパとママのLINEに通知されます。

しかし、外出中のパパやママは、子供達へ返事をすることができませんでした。Google Homeはデフォルトでは喋ってくれる機能が(2018/2/24現在は)無いのです。

ということで、Google Homeを、外出先から、自分が指示した言葉を喋らせたい、というのが今回のテーマです。

子供達が「一緒にお風呂入ろう」とLINEで送ってきたのに対して、「いますぐ帰るよ、待っててね」とGoogle Homeに喋らせるようにするのです。

これを実現するために、google-home-notifierというNode.jsモジュール(プログラム)を利用します。このプログラムはPC上で動かすこともできますが、自宅のLAN内で動かし続ける必要があるので、PCより、Raspberry Piなどの省電力なサーバがあるとなお良いでしょう。

我が家では、外部からngrok経由で自宅LAN内のRaspberry Pi 3(google-home-notifier)へ喋らせたい内容(text)をPOSTすると、google-home-notifierがtextをGoogle Homeへ渡して喋らせる、という構成を採用しています。

前々から興味のあったRaspberry Pi 3 Model Bですが、それを買う大義名分がやっとできました。Macを立ち上げっぱなしだと結構電気代かかりですし。

さて、Raspberry Pi 3を手に入れたら早速MicroSDにRaspbianをインストールします。と思ったけど面倒だったのでNOOBS経由でインストールしました。なお、MicroSDカードにはRaspberry Piと相性が悪いものが存在するようなので注意が必要です。TOSHIBAのは大抵問題ないようなので、自分は以下のカードを利用しています。

NOOBSを利用するとGUIで簡単にインストールが出来るのですが、ラズパイを初期設定するのにHDMIで繋がるディスプレイやUSBキーボード、USBマウスが必要になります(上記写真)。逆に初期設定さえ一回済ましてしまえば、sshでアクセス出来るようになるので、ラズパイに必要なのは電源のみとなります(下記写真)。

raspberrypi

とまあ、ラズパイを初期設定したり、Node.jsやnpmの最新版をインストールしたりした結果、無事に外部からGoogle Homeを自由に喋らせることに成功しました。

https://xxxxxxxx.ngrok.io/google-home-notifier?text=こんにちは

みたいなURLを叩くのが1番簡単な起動方法です。自分はIFTTTと連携させて、メールを書くとその内容がPOSTされて、Google Homeを喋らせるという方式にしました。

Google Homeの喋り方(イントネーション)が少し変わっているのが想定外でしたが、なかなかいい感じ。子供達も驚いてくれました。

コレで(LINEなど通信手段を持たない)子供達とも双方向のコミュニケーションが取れるようになりました。

以上でスマートホーム的な話を終わります。せっかくなので、ここから先は、自分が、今回の設定で躓いたところを紹介します。どなたかの参考になれば、と。

ngrok

ngrokはe-mansionのような多段ルータ構成でも外部からアクセスできる便利なツールです。google-home-notifierをインストールした際にngrokも同梱されていて、その存在を知ったのですがとても便利ですね。

ngrok(google-home-notifier)を起動すると、https://xxxxxxxx.ngrok.io/google-home-notifierのようなアドレスが与えられ、このURLを利用して(我が家のLAN内のRaspberry Piへ)GETやPOSTを行います。

しかし、ngrokは一定の時間が立つと、勝手に我が家のRaspberry Piとの接続(トンネル)を解除してしまい、https://xxxxxxxx.ngrok.io/google-home-notifierが無効になってしまうため外部から接続できなくなってしまいます。

対策としてngrokで無料のアカウントを作成します。作成したアカウントでngrokのwebページへログインするとConnect your accoutというところにauthtokenが表示されます。これをgoogle-home-notifierを起動する前にngrokへ通知してやれば、時間がたってもトンネルが解除されることがありません。

具体的には以下のようなコマンドをexample.jsを起動する前に叩けばOKです。

/home/xxxx/google-home-notifier/node_modules/ngrok/bin/ngrok authtoken xxxxxxxxxxxxxxxxxxxxx(自分のアカウント用トークン)

有料アカウントを取得するとわかりやすいサブドメイン取得できて、かつオフラインになってもそのサブドメインが確保されるので便利なのですが、まあ無料でも充分でしょう。ありがたや。

なお、24時間example.jsを動かしっぱなし(永続化)にするために、forever(Nodeアプリをdaemon化)を利用しています。

Timeout問題

raspberry piでgoogle-home-notifierを動かすにあたって1番苦労したのが、タイムアウト問題です。

example.jsを実行して、試しに「テスト」と喋らせようとすると、以下のエラーが出ます。

{ text: ‘テスト’ }
FetchError: network timeout at: https://translate.google.com
at Timeout._onTimeout (/home/xxxx/google-home-notifier/node_modules/node-fetch/index.js:126:13)
at ontimeout (timers.js:458:11)
at tryOnTimeout (timers.js:296:5)
at Timer.listOnTimeout (timers.js:259:5)

実はコレ、解決していません。起動してから20分くらい経過する(もしくは5回くらいPOSTする)と、このエラーは出なくなります。なぜNode.jsを起動した時はダメで、そのうち出来るようになるのかは謎のままです。解決策が定まってなくて気持ち悪いけど、とりあえず現状利用できているのでよしとしておきます。

ではでは、今度こそ以上になります。ラズパイ、面白いですね。

Pocket