14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-11-27

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』は利用可能です。

1. google-home-notifier
    [Raspberry PiにNode.jsとnpmの最新版をインストールする](https://qiita.com/mascii/items/77c685df65c4cbca9315)を参考に進めます。

    ```
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が動作しませんでした。完了後、バージョンを確認します。

```text:node

$ node -v
v8.9.0


    ```text:npm
$ npm -v
5.5.1
[google-home-notifier](https://github.com/noelportugal/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


	```text:node_modules/mdns/lib/browser.js(修正前)
	Browser.defaultResolverSequence = [
	  rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
	, rst.makeAddressesUnique()
	];
	```

	```text: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
```js:example.js

//var deviceName = 'Google Home';
var deviceName = '(Google Homeセットアップ時の名前)';


    ```
vi google-home-notifier.js
```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
  1. localhost上と同一LAN上から投げてみる

    RPi

$ curl -X POST -d "text=ローカルホストからのメッセージ" http://localhost:8080/google-home-notifier
Google Home will say: ローカルホストからのメッセージ


    ```bash:無線LAN上の別PC
$ curl -X POST -d "text=同一ネットワークからのメッセージ、漢字や句読点もOK" http://192.168.168.1:8080/google-home-notifier
Google Home will say: 同一ネットワークからのメッセージ、漢字や句読点もOK
  1. 外から投げてみる
    事前に、ufwで「接続元のIPアドレスから、イプシムの固定IPアドレス:ポート8080への接続」を許可してください。

sudo ufw allow from [会社のIPアドレス] to [イプシムのIPアドレス] port 8080 proto tcp


    ```bash:会社のPC(任意ポートへのPOSTが許可されている方に限ります)
$ curl -X POST -d "text=仕事が終わったので帰ります" http://イプシムの固定IPアドレス:8080/google-home-notifier
Google Home will say: 仕事が終わったので帰ります
簡単!
iPhoneの[iCurlHTTP](https://itunes.apple.com/jp/app/icurlhttp/id611943891)[^3]でもOKです。
<img width="375" alt="iCurlHTTP1.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/211762/04dc4db2-a2ae-c25e-3982-c09c2c6edeee.jpeg">

<img width="375" alt="iCurlHTTP2.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/211762/912b071c-7813-c9fd-7b71-7ad27c2dad8f.jpeg">

#今後の展開

  • ちゃんとしたWeb UI/APIを作る。
  • Web UI/API経由でgoogle-home-notifierを直接呼び出す。(フロントがあればリスナーは不要)
  • 認証を設ける。
  • ボイスメッセージを投げて、そのままGoogle Homeに再生させる。
  1. NAPTタイマ切れによる切断やグローバルIP変更時の再接続など、確実に接続できる保証もありません。そもそも外界にトンネル張りっぱなしというのも少し不安です。

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

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?