Help us understand the problem. What is going on with this article?

ラズパイ+3GPi+イプシムを使って外から家のGoogle Homeを喋らせる

More than 1 year has passed since last update.

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 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)の使い方で参照したサイトと接続手段

どうやって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

セットアップ

  1. ラズパイ+3GPi+イプシム
    anyPi(ラズパイ+3GPi)で固定IPアドレスSIMイプシムを使うと、ラズパイ+3GPiをufw/hostapd/dnsmasqでモバイルWi-Fiルータにして格安SIMで使うに従って設定します。

  2. Google Home
    Google HomeのMACアドレスを調べて、ラズパイのDHCPサーバでGoogle Homeに恒久的にIPアドレスを割り当てます。

    /etc/dnsmasq.conf
    dhcp-host=XX:XX:XX:XX:XX:XX, GoogleHome, 192.168.168.2, infinite
    

    スマートフォンでGoogle Home側の設定を終わらせます。この時点ですでに『OK, Google』は利用可能です。

  3. 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';
    

動作確認

  1. 起動

    node example.js
    
  2. 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
    
  3. 外から投げてみる
    事前に、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: 仕事が終わったので帰ります
    

    簡単!
    iPhoneのiCurlHTTP3でもOKです。
    iCurlHTTP1.JPG

    iCurlHTTP2.JPG

今後の展開

  • ちゃんとしたWeb UI/APIを作る。
  • Web UI/API経由でgoogle-home-notifierを直接呼び出す。(フロントがあればリスナーは不要)
  • 認証を設ける。
  • ボイスメッセージを投げて、そのままGoogle Homeに再生させる。

  1. NAPTタイマ切れによる切断やグローバルIP変更時の再接続など、確実に接続できる保証もありません。そもそも外界にトンネル張りっぱなしというのも少し不安です。 

  2. Google Homeを自宅LANに接続したくない、という別の理由もありますが…。 

  3. 設定画面で「Use HTTP2」のチェックを外してください。 

ipsim_net
固定IPアドレスMVNO【イプシム】の中の人。
https://ipsim.net/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした