RaspberryPiでgoogle-home-notifierをインストールしてお好みの言葉を話してみる
GoogleHomeMiniが年末に安売りになったので自分も購入し、天気やキッチンタイマーのようなものに使用していました。
とはいっても、3日ぐらいで飽きるので他の使い方がないのかなと思い、IFTTT
からGoogleスプレッドシートへ記録なども行っていました。
IFTTT
の連携は結構便利だなーとは思っているのですが言葉をいろいろ決めたりしないといけないので、制限がおおいなあというのが、
実際のところでした。そこで、RaspberryPiと連携し、話す言葉を変更できる連携に手をだしました。
このネタは2017年のアドベントカレンダーではさんざんやりつくされた感じはしたのですが、自分もその波に乗ってみました。 それでもつまずく自分…。今年もいろいろなトラップに引っかかる予感です。
今回紹介するgoogle-home-notifier
は非常に簡単な呼び出しを行うだけで話すことができるのでとても便利です。
ただ、RaspberryPiのように常時起動の機器がないと実現ができないのは少しハードルはあるかなと思います。
githubを参考に
Node.js
の準備
google-home-notifier
はNode.js
のモジュールなので、新しめのNode.js
の設定をします。最近のバージョンは4.x系なので昔よりはマシになりましたが
最近のLTSあたりにしておくのが無難かなと思います。
過去のエントリーを参考にして設定します。
やっててよかった備忘録。2018/01/08現在は以下のバージョンがLTSのようです。
$ node -v
v8.9.4
google-home-notifier
のインストール
ググったのサイトをみていると
# 任意のフォルダに移動し
$ npm init
$ npm install google-home-notifier
こんな感じで問題ないようなことが書いてあるのですが。
Node.js
の初心者の私にはピンときていませんでした…。
あと、モジュールのインストールを行うとエラーが発生して、インストールが完了しませんでした。
公式のドキュメントにRaspberryPiの項目があるのでそれを見ると
Raspberry Pi If you are running from Raspberry Pi make sure you have the following before nunning "npm install": Use the latest nodejs dist. curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - sudo apt-get install nodejs Also install these packages: sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev
てな記載が。別途パッケージが必要なのね。(ちゃんとドキュメントを読みましょう)
パッケージ名を確認するとavahi
とかmdns
なライブラリが必要のようです。
(前半部分はNode.js
のインストールなので既に行っていることから省略でもも問題はありません)
インストールに必要な事前準備
以下でパッケージをインストールします。
【コマンド】
$ sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev
【ログ】
$ sudo apt-get install git-core libnss-mdns libavahi-compat-libdnssd-dev パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 libnss-mdns はすでに最新バージョン (0.10-8) です。 libnss-mdns は手動でインストールしたと設定されました。 以下の追加パッケージがインストールされます: libavahi-client-dev libavahi-common-dev libavahi-compat-libdnssd1 libdbus-1-dev 以下のパッケージが新たにインストールされます: git-core libavahi-client-dev libavahi-common-dev libavahi-compat-libdnssd-dev libavahi-compat-libdnssd1 libdbus-1-dev アップグレード: 0 個、新規インストール: 6 個、削除: 0 個、保留: 3 個。 424 kB のアーカイブを取得する必要があります。 この操作後に追加で 1,285 kB のディスク容量が消費されます。 続行しますか? [Y/n] y 取得:1 http://mirrordirector.raspbian.org/raspbian stretch/main armhf git-core all 1:2.11.0-3+deb9u2 [1,410 B] 取得:2 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian stretch/main armhf libavahi-common-dev armhf 0.6.32-2 [62.6 kB] 取得:3 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian stretch/main armhf libdbus-1-dev armhf 1.10.24-0+deb9u1 [200 kB] 取得:4 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian stretch/main armhf libavahi-client-dev armhf 0.6.32-2 [56.5 kB] 取得:5 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian stretch/main armhf libavahi-compat-libdnssd1 armhf 0.6.32-2 [44.0 kB] 取得:6 http://ftp.jaist.ac.jp/pub/Linux/raspbian-archive/raspbian stretch/main armhf libavahi-compat-libdnssd-dev armhf 0.6.32-2 [58.8 kB] 424 kB を 4秒 で取得しました (102 kB/s) 以前に未選択のパッケージ git-core を選択しています。 (データベースを読み込んでいます ... 現在 124934 個のファイルとディレクトリがインストールされています。) .../0-git-core_1%3a2.11.0-3+deb9u2_all.deb を展開する準備をしています ... git-core (1:2.11.0-3+deb9u2) を展開しています... 以前に未選択のパッケージ libavahi-common-dev:armhf を選択しています。 .../1-libavahi-common-dev_0.6.32-2_armhf.deb を展開する準備をしています ... libavahi-common-dev:armhf (0.6.32-2) を展開しています... 以前に未選択のパッケージ libdbus-1-dev:armhf を選択しています。 .../2-libdbus-1-dev_1.10.24-0+deb9u1_armhf.deb を展開する準備をしています ... libdbus-1-dev:armhf (1.10.24-0+deb9u1) を展開しています... 以前に未選択のパッケージ libavahi-client-dev:armhf を選択しています。 .../3-libavahi-client-dev_0.6.32-2_armhf.deb を展開する準備をしています ... libavahi-client-dev:armhf (0.6.32-2) を展開しています... 以前に未選択のパッケージ libavahi-compat-libdnssd1:armhf を選択しています。 .../4-libavahi-compat-libdnssd1_0.6.32-2_armhf.deb を展開する準備をしています ... libavahi-compat-libdnssd1:armhf (0.6.32-2) を展開しています... 以前に未選択のパッケージ libavahi-compat-libdnssd-dev:armhf を選択しています。 .../5-libavahi-compat-libdnssd-dev_0.6.32-2_armhf.deb を展開する準備をしています ... libavahi-compat-libdnssd-dev:armhf (0.6.32-2) を展開しています... libdbus-1-dev:armhf (1.10.24-0+deb9u1) を設定しています ... libavahi-common-dev:armhf (0.6.32-2) を設定しています ... libavahi-client-dev:armhf (0.6.32-2) を設定しています ... libavahi-compat-libdnssd1:armhf (0.6.32-2) を設定しています ... libc-bin (2.24-11+deb9u1) のトリガを処理しています ... git-core (1:2.11.0-3+deb9u2) を設定しています ... libavahi-compat-libdnssd-dev:armhf (0.6.32-2) を設定しています ...
google-home-notifier
のインストール
google-home-notifier
のインストールはnpm
で行います。
今回作業するディレクトリはgooglehomeSample
としました。適宜読み替えて作業をしてください。
任意のディレクトリとなっていますが、google-home-notifier
というモジュール名と同じディレクトリ名にすると
エラーになりますので気を付けてください。(自分はハマった)
【コマンド】
$ mkdir googlehomeSample $ cd googlehomeSample/ $ npm init $ npm install google-home-notifier
公式ページではインストール前のnpm init
については言及がされていませんでしたが、事前にしておくと警告行が減ったので含めています。
npm init
ではパッケージバージョンの情報やライセンス情報の入力などを求められますが、そのままリターンしました。
【ログ】
$ mkdir googlehomeSample $ cd googlehomeSample/ $ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (googlehomesample) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to /home/pi/googlehomeSample/package.json: { "name": "googlehomesample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this ok? (yes) $ npm install google-home-notifier > mdns@2.3.4 install /home/pi/googlehomeSample/node_modules/mdns > node-gyp rebuild make: ディレクトリ '/home/pi/googlehomeSample/node_modules/mdns/build' に入ります CXX(target) Release/obj.target/dns_sd_bindings/src/dns_sd.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_browse.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_enumerate_domains.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_get_addr_info.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_process_result.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref_deallocate.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_ref_sock_fd.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_register.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_resolve.o CXX(target) Release/obj.target/dns_sd_bindings/src/dns_service_update_record.o CXX(target) Release/obj.target/dns_sd_bindings/src/mdns_utils.o CXX(target) Release/obj.target/dns_sd_bindings/src/network_interface.o CXX(target) Release/obj.target/dns_sd_bindings/src/socket_watcher.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_ref.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_create.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_deallocate.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_set_value.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_get_length.o CXX(target) Release/obj.target/dns_sd_bindings/src/txt_record_buffer_to_object.o SOLINK_MODULE(target) Release/obj.target/dns_sd_bindings.node COPY Release/dns_sd_bindings.node make: ディレクトリ '/home/pi/googlehomeSample/node_modules/mdns/build' から出ま す > ngrok@2.2.24 postinstall /home/pi/googlehomeSample/node_modules/ngrok > node ./postinstall.js ngrok - downloading binary https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip ngrok - downloading progress: 5084312/5084312 ngrok - binary downloaded to /home/pi/.ngrok/aHR0cHM6Ly9iaW4uZXF1aW5veC5pby9jLzRWbUR6QTdpYUhiL25ncm9rLXN0YWJsZS1saW51eC1hcm0uemlw.zip ngrok - unpacking binary ngrok - binary unpacked to /home/pi/googlehomeSample/node_modules/ngrok/bin/ngrok npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN googlehomesample@1.0.0 No description npm WARN googlehomesample@1.0.0 No repository field. + google-home-notifier@1.2.0 added 138 packages in 170.896s
これでインストールができました。途中でngrok
などもビルドしているようなので少し時間はかかっています。
サンプルを動かす
サンプルは以下のようになっていますが、コアの要素だけを抽出し簡単にしてみました。
【オリジナルのサンプル】 github.com
【機能を絞ったサンプル】
var googlehome = require('google-home-notifier'); var language = 'ja'; googlehome.device('テスト', language); googlehome.ip('192.168.0.2');// IPアドレスは自分の環境のGoogleHomeの設定に合わせてください var text = 'こんにちは'; try { googlehome.notify(text, function(notifyRes) { console.log(notifyRes); }); } catch(err) { console.log(err); }
基本的にはgooglehomeの設定(言語設定、IP設定など)を行い、notifyメソッドを実行すると、 いったん音がなり、テキストの読み上げが行われます。
deviceメソッドの第一引数は適当でいいようなのですが、たぶん事前設定した名前にすればIP設定しなくてもいいのかなとなんとなく思いました。(未確認)
警告が表示されますが、特に問題はないようです。 (内容はavahi関連の警告で、今回のコードではIP直接のアクセスだから問題ないのかなと思います。)
【実行のようす】
$ node test.js *** WARNING *** The program 'node' uses the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node> *** WARNING *** The program 'node' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi. *** WARNING *** Please fix your application to use the native API of Avahi! *** WARNING *** For more information see <http://0pointer.de/avahi-compat?s=libdns_sd&e=node&f=DNSServiceRegister> Device notified
これで無事音声が出力されました。読み上げた音声はたどたどしい抑揚です。
では固定の文字列ではなくコマンドライン引数にしていした文字列を読み上げるコードに変更してみます。
var googlehome = require('google-home-notifier'); var language = 'ja'; googlehome.device('テスト', language); googlehome.ip('192.168.0.2');// IPアドレスは自分の環境のGoogleHomeの設定に合わせてください var text = 'こんにちは'; if(process.argv.length == 3){ text = process.argv[2]; } try { googlehome.notify(text, function(notifyRes) { console.log(notifyRes); }); } catch(err) { console.log(err); }
省略した場合は「こんにちは」と出力し、引数に指定した場合には「引数に指定した言葉」を話します。
おわりに
話す言葉の制限がかなりあったGoogleHome
ではありますが、これでかなり自由度が高くなりました。
RaspberryPi+OpenJTalk
+Bluetoothスピーカーなどの組み合わせを、RaspberryPi+google-home-notifier
+GoogleHomeに変更することも可能かなと思います。
数字の読み上げなどがどうなるのかはまだテストしていませんが、それなりに動いてくれるのでは?と思ってはいます。
cronやアラームシステムとの組合わせ、WebAPIとの連携なども簡単にできそうなのでなかなか魅力的な感じです。
それにしても、いつになったらAmazon Echoの招待が来るのだろうか…