私は都下に住んでおり、家からバス停が近いので、バスを使うことが多いです。
ですが、都心部よりもバスの頻度が低いし、遅れることもあるので、バス会社のリアルタイム運行情報をスクレイピングしてSlackなどと連携させて使っていたりします。
というわけで、
Google Home + IFTTT + Raspberry Pi を組み合わせた古典的なWebhook連携で、何かを聞くと、答えを発言してくれる家庭内システムを作りました。
もちろん、Raspberry Pi 側の実装次第で、発言する内容はなんでもオッケーです。
前提
- Google Home のセットアップが完了済み
- インターネットからRaspberryPiにアクセスできる
- インターネットに公開できない環境なら、ngrokを使ったり、何かしらのメッセージ・キューを使った実装をしてください。
IFTTT Applet を作る
Google Homeの発言をトリガにして、Raspberry Pi上のHTTPハンドラを叩くまでをIFTTTで行います。
トリガを設定する
Google Assistant の Say a simple phrase をトリガにします。
「おっけーグーグル、バスの時間教えて」
キーワードは3つまで設定でき、一字一句、正しく発言しないとキャッチしてくれません。
「Google Assistant」を使うと、Google Home に呼びかけたキーワードにトリガを設定できます。IFTTTにGoogleアカウントでOAuthログインしていれば、特に追加設定は不要です。
アクションを設定する
Webhooks の Make a Web Request を使います。
Raspberry PiのURLを指定します。
Raspberry Pi を準備する
Raspberry Pi で動かすプログラムを作る
google-home-notifierというnpmパッケージを使うと簡単にテキストをGoogleHomeで再生できます。
https://github.com/noelportugal/google-home-notifier
Express使ったHTTPサーバを立てます。コードを一部だけ抜粋します。
const fetchRealtimeBusInfo = /* スクレイピングを行うモジュールを別途作る */
const googlehome = require('google-home-notifier');
const speak = (message) => {
googlehome.device('リビング', 'ja'); /* デバイス名 */
googlehome.ip('192.168.0.xx'); /* IPアドレス */
googlehome.accent('ja');
googlehome.notify(message, function (res) {
console.log(res);
});
};
const handler = (req, res, next) => {
fetchRealtimeBusInfo().then(function (dia) {
if (dia.length) {
let content = '次のバスは' + dia[0].status; /* "あと5分です。"などの文字列が入ります。 */
if (dia.length >= 2) {
content += '。その次は' + dia[1].status;
}
speak(content);
} else {
speak('バスはありません');
}
});
res.status(200).send('OK');
};
router.post('/googlehome/bus', handler);
Raspberry Pi で動かす前にPCで動作確認しておくと安心でしょう。この段階で、うまくいっていれば、GoogleHomeから音が出ます。
Raspberry Pi で動かす。
私はRaspbianの上でNode.jsを動かしています。Node.jsのインストール方法は割愛します。
依存しているNPMパッケージmdns
のビルドエラーが出るかもしれませんが、libavahi-compat-libdnssd-dev
をインストールしておくことで解消します。
apt-get install libavahi-compat-libdnssd-dev
google-home-notifier について
純正では、外部からのプッシュを契機にGoogle Homeでテキストを再生する方法は提供されていないので、今回はこれを使います。
google-home-notifier
の中身はシンプルです。
どうやって GoogleHome から音を出しているのか、というと・・・、 node-castv2-client
パッケージでやっているようです。
https://www.npmjs.com/package/castv2-client
GoogleHome は ChromeCast と同じプロトコルを使っているようなので、これで音を再生できるっぽい。
node-castv2-client
自体は、ChromeCastに繋げば、写真を表示するなどの制御が出来るようです。
テキストを音声に変えるには、別のパッケージ google-tts-api
を使っています。
Google翻訳のTTS(Text To Speach) APIを叩いてmp3のURLを取得するコードで、200文字まで対応しています。
ただ、このGoogle翻訳のAPIは、非公開APIのようなので、Googleが本来意図した使い方では無い可能性もあり、いつまで使えるかはわかりませんね。
感想
現時点で、IFTTTを使った方法で会話の往復を実現するのはちょっと面倒でした。
api.ai を使う方法があるので、こっちが適しているケースもあると思います。
https://qiita.com/syarihu/items/53ea1a65f481f8121109
GoogleHomeに音声ファイルを投げるには、ローカルネットワークにサーバーを立てる必要があるのも面倒です。すでにRaspberryPiなどで家庭内サーバがお家にあれば、敷居は低いと思います。
数日使ってみましたが、「自分で設定したトリガワードを忘れる」という問題に直面して、起動できないことがしばしば・・・。
普通のGoogleHomeの感覚でいくと、多少の、曖昧な表現や語順の変化でも受け入れてもらえるのですが、IFTTTのSay a simple phrase
では一字一句の間違いも許されないので、かなり使い勝手が悪かったです。
キーワードは3つまで設定できるものの、もっと柔軟に判断してほしい・・・。会話型インターフェースの難しさを感じました。