GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいますを参考に、ラズパイ+3GPiとイプシムだけで、外出先から自宅のGoogle Homeを喋らせてみます。IFTTT、Firebase、Twitter、Slackなどの外部サービスやngrokなどのトンネルサービスは使いません。
何ができるの?
- どこでも『OK, Google』(固定回線不要・無線LAN不要)
- 外から家のGoogle Homeを喋らせる!
準備するもの
- Raspberry Pi 3 Model B(またはRPi2とUSB無線LANドングルの組み合わせ+追加設定)
- 3GPi+同梱Raspbian(3gpi2-jessie-20170904)(またはUSBモデム+追加設定)
- 固定IPアドレスMVNO「イプシム」標準SIM
- Google Home または Google Home Mini
- 自由にHTTP POSTできる環境
ネットワーク構成
Internet --(3G回線)-- <ppp0>[3GPi+イプシム]+[RPi]<wlan0> --(無線LAN)-- [Google Home]
はじめに:Google Homeの利用方法3パターン
Input | 中間処理 | Output | 例 | |||
---|---|---|---|---|---|---|
(1)OK, Google | Google Home | → | → | Google Home | 「今日の天気は?」⇒『晴れです』 | |
(2)内から外 | Google Home | → | IFTTT | → | Twitter, Slack等 | 「~と呟いて」⇒"~"をtweet |
(3)外から内 | 何かのトリガと手段 | → | google-home-notifier | → | Google Home | "帰ります"をPOST⇒『カエリマス』 |
(1)は普通の使い方ですね。
(2)はIFTTTを使う例が多いようです。
(3)が今回やりたいことですが、google-home-notifierをラズパイなどで動作させることで、簡単に実現できるようです。なんと「Google Homeに喋らせたいメッセージ」を、google-home-notifierにPOSTで投げるだけで、Google Homeが喋ります。残る問題は、LAN以外からどうやってgoogle-home-notifierに投げるか、だけです。
(3)の使い方で参照したサイトと接続手段
- GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます (LAN)
- Google Homeで時報を知らせる (LAN)
- 帰宅したらGoogleHomeから好きな音声で「おかえり」って言ってもらいます (LAN)
- Twitterの通知をGoogle Homeに教えてもらう (ngrok)
- Google Home、IFTTT、Googleスプレッドシートを使って独自音声コマンドでログをとる(ついでにNode.jsやngrokやらも使ってLINEやGoogle Homeに通知する) (ngrok)
- 新着メールを知らせてくれるGoogle Home (Firebase)
どうやってgoogle-home-notifierに投げるか?
LANから投げるのであれば、
http://ラズパイのIPアドレス:8080/google-home-notifier
にPOSTすれば良いだけです。悩むことはありません。
また親切なことに(?)、google-home-notifierはデフォルトでngrokが使えるようになっていて、WAN(Internet側)から投げる場合も、起動時に表示されるURL
https://********.nrgok.io/google-home-notifier
にPOSTすれば、後はngrokのトンネル経由で到達できるようになっています。しかし、ngrokはgoogle-home-notifierを起動する度にURLが変わってしまいます。このためIFTTTのwebhookなどに設定するのには向きません。1
そうすると、FirebaseのリアルタイムDB更新とFirebase Listenerを組み合わせが、NAT+クラウド時代のまっとうな解決方法かもしれません。
…が、固定IPアドレスがあれば、そこに投げれば良いのでは? ということで
http://イプシムの固定IPアドレス:8080/google-home-notifier
に投げる、という安易な解が導き出されました。2
セットアップ
ラズパイ+3GPi+イプシム
anyPi(ラズパイ+3GPi)で固定IPアドレスSIMイプシムを使うと、ラズパイ+3GPiをufw/hostapd/dnsmasqでモバイルWi-Fiルータにして格安SIMで使うに従って設定します。-
Google Home
Google HomeのMACアドレスを調べて、ラズパイのDHCPサーバでGoogle Homeに恒久的にIPアドレスを割り当てます。/etc/dnsmasq.confdhcp-host=XX:XX:XX:XX:XX:XX, GoogleHome, 192.168.168.2, infinite
スマートフォンでGoogle Home側の設定を終わらせます。この時点ですでに『OK, Google』は利用可能です。
-
google-home-notifier
Raspberry PiにNode.jsとnpmの最新版をインストールするを参考に進めます。sudo apt-get install nodejs npm sudo npm cache clean sudo npm install npm n -g sudo n lts
最後を
sudo n stable
とすると、v9.0.0がインストールされてしまい、google-home-notifierが動作しませんでした。完了後、バージョンを確認します。node$ node -v v8.9.0
npm$ npm -v 5.5.1
google-home-notifierのREADMEにある、Raspberry Piの記載を先に実行します。
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - sudo apt-get install nodejs sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev
あとはgoogle-home-notifier本体です。
git clone https://github.com/noelportugal/google-home-notifier cd google-home-notifier npm install
npm install後、READMEに従ってファイルを修正します。
vi node_modules/mdns/lib/browser.js
node_modules/mdns/lib/browser.js(修正前)Browser.defaultResolverSequence = [ rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo() , rst.makeAddressesUnique() ];
node_modules/mdns/lib/browser.js(修正後)Browser.defaultResolverSequence = [ rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]}) , rst.makeAddressesUnique() ];
設定ファイルを編集します。
vi example.js
example.js//var deviceName = 'Google Home'; var deviceName = '(Google Homeセットアップ時の名前)';
vi google-home-notifier.js
google-home-notifier.js//var deviceAddress; var deviceAddress='192.168.168.2'; //var device = function(name, lang = 'en') { var device = function(name, lang = 'ja') { //var googlettsaccent = 'us'; var googlettsaccent = 'ja';
動作確認
-
起動
node example.js
-
localhost上と同一LAN上から投げてみる
RPi$ curl -X POST -d "text=ローカルホストからのメッセージ" http://localhost:8080/google-home-notifier Google Home will say: ローカルホストからのメッセージ
無線LAN上の別PC$ curl -X POST -d "text=同一ネットワークからのメッセージ、漢字や句読点もOK" http://192.168.168.1:8080/google-home-notifier Google Home will say: 同一ネットワークからのメッセージ、漢字や句読点もOK
-
外から投げてみる
事前に、ufwで「接続元のIPアドレスから、イプシムの固定IPアドレス:ポート8080への接続」を許可してください。sudo ufw allow from [会社のIPアドレス] to [イプシムのIPアドレス] port 8080 proto tcp
会社のPC(任意ポートへのPOSTが許可されている方に限ります)$ curl -X POST -d "text=仕事が終わったので帰ります" http://イプシムの固定IPアドレス:8080/google-home-notifier Google Home will say: 仕事が終わったので帰ります
今後の展開
- ちゃんとしたWeb UI/APIを作る。
- Web UI/API経由でgoogle-home-notifierを直接呼び出す。(フロントがあればリスナーは不要)
- 認証を設ける。
- ボイスメッセージを投げて、そのままGoogle Homeに再生させる。