Edited at

Raspberry PiからGoogle Homeを喋らせる


はじめに

昨年末にGoogle Home Miniを買ったので何か使えないか調べていたところ、Node.jsにgoogle-home-notifierというAPIがあり、任意の言葉を喋らせることができるという記事があったのでやってみた。

macだと

$ npm install google-home-notifier

すればサンプルプログラムが実行できたが、RaspberryPiで同じことをやろうとしたら何かとつまづいたので、記事にすることにした。


使用機材


  • Google Home Mini

  • Raspberry Pi 3 Model B (Raspbian Stretch 2017-11-29 インストール済み)


2019/04/06 追記

Raspbian Stretch 2018-11-13 だと Node.js の v8.11.1 が標準でインストールされていた。

そのため下記 「Node.jsのアップデート」の作業は不要、npmが入っていなかったため、npmのインストールが必要と思って $ sudo apt-get install npm とやってもうまく入りませんでした。

やはり下記手段をやる必要がありそうです。


Node.js のアップデート

Rasbpian Stretchに標準でインストールされているNode.jsはバージョンが古い(v4.8.2)。

そのため、npmでgoogle-home-notifierをインストールしようとすると怒られるので、Node.jsをアップデートする必要があった。

せっかくなので、「nvm(Node Version Manager)」(プロジェクトごとに、Node.jsのバージョンを切り替えて使えるようにする仕組み)を入れて、今後バージョン違いで困らないようにした。

手順は下記を参考にした。

Raspberry Pi 3 Model BにnvmでNode.jsをインストールする - しらすの備忘録


古いNode.jsをアンインストール

$ sudo apt-get autoremove nodejs


nvmのインストール

nvmをインストールするためのディレクトリ作成

$ sudo mkdir ~/.nvm

$ sudo chmod 777 ~/.nvm

gitからnvmを取得

$ git clone https://github.com/creationix/nvm.git ~/.nvm

nvmを使えるようにする

$ source ~/.nvm/nvm.sh

nvmバージョンを取得して、nvmがインストールできたことを確認する。

$ nvm --version


Node.js のインストール

nvmでインストールできるNode.jsのバージョンのリストを確認

$ nvm ls-remote

この中で、「LTS(Long Team Support)」(要するに安定版)とついているバージョンをインストール

2018-01-05時点でv8.9.4

$ nvm install v8.9.4

Node.jsがインストールされたかどうかバージョンを確認

$ node --version

v8.9.4

npm(Node Package Manager)もインストールされているかどうかバージョンを確認

$ npm --version

5.6.0

やっとgoogle-home-notifierをインストールする準備ができました。


google-home-notifierのインストール

ここからは下記を参考に作業してます

Google Home開発入門 / google-home-notifier解説 - Qiita

作業用ディレクトリを作成して移動

$ mkdir googlehome

$ cd googlehome

npmの準備(package.jsonの作成)

$ npm init

満を持してgoogle-home-notifierのインストール

この1行がやりたかったために上記の準備が必要だったのだ!

$ npm install google-home-notifier

しかし、失敗。がーん。

fatal error: dns_sd.h: そのようなファイルやディレクトリはありません

エラーメッセージで検索すると、下記のサイトに出会った。

Raspberry Pi 3 にhomebridgeを導入してsiriから家電操作できるようにした際の覚書 - Qiita

ここを参考に、下記を実行してみる

$ sudo apt-get install libavahi-compat-libdnssd-dev

再度

$ npm install google-home-notifier

今度は成功。


サンプルプログラムの実行

ここに書いてあるサンプルプログラムをmain.jsファイルに保存


main.js

const googlehome = require('google-home-notifier')

const language = 'ja';

googlehome.device('Google-Home', language);

googlehome.notify('こんにちは。私はグーグルホームです。', function(res) {
console.log(res);
});


実行。

$ node main.js

失敗。

events.js:183

throw er; // Unhandled 'error' event
^

Error: getaddrinfo -3008
at errnoException (/home/pi/work/googlehome/node_modules/mdns/lib/resolver_sequence_tasks.js:199:11)
at getaddrinfo_complete (/home/pi/work/googlehome/node_modules/mdns/lib/resolver_sequence_tasks.js:112:10)
at GetAddrInfoReqWrap.oncomplete (/home/pi/work/googlehome/node_modules/mdns/lib/resolver_sequence_tasks.js:120:9)

getaddrinfoでエラー?

よくわからないが、GoogleHomeのIPアドレスを指定する方法があったので、参考にプログラムを修正。

(2018/05/19修正) 公式のREADMEに記載の方法で名前解決できるようになりました。コメントで教えてくれたhorihiroさんThanx!

node_modules/mdns/lib/browser.js コードの一部を修正。


before

Browser.defaultResolverSequence = [

rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
, rst.makeAddressesUnique()
];


after

Browser.defaultResolverSequence = [

rst.DNSServiceResolve(), 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];

要するにrst.getaddrinfo()rst.getaddrinfo({families:[4]})にする。

この修正を加えてから再度実行すると、Google Homeが喋ってくれる。

もしうまくいかなかったり、IPアドレスを直接指定したい場合は以下のコードでIPアドレスを指定できる。


main2.js

const googlehome = require('google-home-notifier');

const language = 'ja';
googlehome.device("Google-Home", language);
googlehome.ip("192.168.xxx.xxx");
googlehome.notify('こんにちは。私はグーグルホームです。', function(res) {
console.log(res);
});

いろいろなものと連携して、GoogleHomeが喋るようにできますね。

こんな記事も見つけました。

GoogleHomeスピーカーに外部からプッシュして自発的に話してもらいます


未解決問題など


  1. Node.jsを一回アンインストールした影響か、Raspberry Piに元から入っていたNode-RED(ブロックを繋げてプログラミングするやつ)が消えてしまった。使いたいときはあらためてインストールする必要がある。


  2. macではIPアドレスを直打ちしなくてもできたので、直打ちしなくてもよい方法を知りたい。 (2018/05/19解決)