echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【node.js】Google Home Notifierを使ってGoogle Homeにしゃべらせる

実は昨年末に、Google Homeを衝動買いしました。

始めは「なんか色々使えないかなあ...」と思っていましたが、購入してしばらくは、そんなに使用していませんでした。

が、先日Twitterで、マイクロソフトエバンジェリスト、千代田まどか(ちょまど)さんがこんなツイートをしているのを見まして。

「やっぱりこういうことができるんだ!面白そう!」って思い、さっそく(二番煎じもいいとこ)実行してみました。(僕は女の子が大好きなので、男の声にはしないですが…)

※これ以降の作業は、Windowsにインストールする前提で記載しています。

1.インストール

■node.jsのインストール
Google Homeにしゃべらせるには、Google Home Notifierというjavascriptのプログラムが必要です。
そしてGoogle Home Notifierを動かすには、node.jsが必要です。
というわけで、node.jsのインストールから始めます。

といっても、node.jsの公式サイト(https://nodejs.org/ja/)からインストーラーをダウンロードして、実行するだけですので、難しいことはないです。
※「推奨版」と「最新版」がありますが、「推奨版」が無難。

インストール後、下記コマンドをコマンドプロンプトで入力して、バージョンが表示されればOK。(ここを含めた全手順で、コマンドプロンプトは「管理者で実行」してください。)

> node --version

■node-gypのインストール
node-gypは「C++を用いた拡張機能を作るためのビルドツール的なもの」らしく、Google Home Notifierインストールに必要になります。
ここをちゃんとやらないと、Google Home Notifierのインストールでエラーが出まくるので、要注意です。(てか、僕はそれで1週間近くハマった…)

※ここはnode-gypのgithubのドキュメント(https://github.com/nodejs/node-gyp)に沿って説明をします。

まずインストールは、コマンドプロンプトで下記コマンドを入力すればOK。(ここは問題ないと思います)

> npm install -g node-gyp

そして公式サイトの「Option 1」に、
Install all the required tools and configurations using Microsoft's windows-build-tools using npm install --global --production windows-build-tools from an elevated PowerShell or CMD.exe (run as Administrator).
(訳:「PowerShellコマンドプロンプトで'npm install --global --production windows-build-tools'というコマンドを使用して、Microsoft's windows-build-toolsを介して必要なツールや設定情報をインストールしてください。(管理者権限で実行してね))

とある通りに、コマンドプロンプトから

> npm install --global --production windows-build-tools

と入力して、この作業を完了させます。

※なお「Option 2」の手順は「必要なツールや設定情報」を自分でインストールする方法です。「Option 1」の手順はそれをすべて上記コマンド一発で行えるので、「Option 1」の手順のほうが楽です。(実施するのはいずれか一方でよい)

最後に、
If node-gyp is called by way of npm and you have multiple versions of Python installed, then you can set npm's 'python' config key to the appropriate value:
(訳:node-gypをnpm経由で実行する場合で、pythonの複数バージョンがインストールされている場合、(下記コマンドのように)npmの'python'コンフィグの値を適切な値にしてください。)

> npm config set python /path/to/executable/python2.7

とあるので、この通りに設定します。(なお、node-gypはpython3.xでは動作しませんが、Option1の手順を実施すれば、別途2.xをインストールしてくれますので、問題ないはずです。)

※なお、公式ドキュメントに
If you have multiple Python versions installed, you can identify which Python version node-gyp uses by setting the '--python' variable:
(訳:もし複数バージョンのpythonがインストールされている場合、node-gypに下記コマンドでnode-gypで使用するバージョンを設定してください)

> node-gyp --python /path/to/python2.7

とありますが、僕が実施した際は、「--pythonオプションなんてないよ」と言われ、これは実行できませんでした。


次に使用方法ですが、
To compile your native addon, first go to its root directory:
(訳:あなたの環境のアドオンをコンパイルするために、まず初めに(プロジェクトの)ルートフォルダに移動してください。)

> cd my_node_addon

とあるので、まずはコマンドプロンプトの'cd'コマンドで、*.jsファイルを作成するフォルダに移動します。

次に、
The next step is to generate the appropriate project build files for the current platform. Use configure for that:
(訳:次に、プラットフォーム毎に適切なプロジェクトのビルドファイルを作成します。次の'configure'コマンドを使用します。)
> node-gyp configure

Auto-detection fails for Visual C++ Build Tools 2015, so --msvs_version=2015 needs to be added (not needed when run by npm as configured above):
(訳:VC++ビルドツールを自動検出ができなかった場合、'--msvs_version=2015'というオプションを付けてください。(上のコマンドでうまくいけば不要です))

> node-gyp configure --msvs_version=2015

とある通り、'node-gyp configure'コマンドを実行します。それで「VC++ビルドツールがない」という旨のエラーが表示されたら、下の'node-gyp configure --msvs_version=2015'コマンドを実施すればOKです。

なお、
Note: The configure step looks for the binding.gyp file in the current directory to process. See below for instructions on creating the binding.gyp file.
Now you will have either a Makefile (on Unix platforms) or a vcxproj file (on Windows) in the build/ directory. Next invoke the build command:
(訳:'configure'コマンドは'binding.gyp'というファイルをカレントフォルダ内から検索します。'binding.gyp'ファイルを作成するには、「build」フォルダ内に'vcxproj'ファイルがあると思うので(Unixでは'Makefile'ファイル)、下記の’node-gyp build’コマンドを実行してください。)

> node-gyp build

という記載もあるので、もし「binding.gypがない」とかいう旨のエラーが表示されたら、'node-gyp build'コマンドを一度実行してから、再度'configure'コマンドを実行すればよいと思います。

Google-Home-Notifierのインストール
で、ようやくメインのGoogle-Home-Notifierのインストールです。
といってもこれ自体は単純で、下記コマンドを実行するだけです。

> npm install google-home-notifier

※ここで「dns_sd.h」ファイルがない、というエラーが表示された場合、先に下記「Bonjour SDK for Windowsのインストール」を実行してから、再度上記コマンドを実行します。(エラーが出る場合、大量に出るはずです)

Bonjour SDK for Windowsのインストール
dns_sd.h」ファイルがないというエラーは、「Bonjour SDK for Windows」をインストールすることで解決できるので、これをインストールします。
これはApple Developerにあるので、ここからダウンロードしてインストーラを実行すればOKです。

【参考サイト】
http://kghr.blog.fc2.com/blog-entry-118.html
http://blog.livedoor.jp/sce_info3-craft/archives/9706909.html


2.プログラミング(ようやく)
で、実際のプログラムですが、公式サイト(https://github.com/noelportugal/google-home-notifier)のソースをそのままコピペで大丈夫かと思います。
でも英語なので、試しに上記【参考サイト】内のサンプルソースを「sample.js」とかいう名前でファイルに保存して、下記コマンドで実施させてみます。

※コード自体は非常に短いですが、特に問題なく動作すると思います。(同じネットワークにGoogle Homeがある事が前提。なお文字コードを「UTF-8」にする必要があるので、それだけは注意。)

> node sample.js

var googlehome = require('google-home-notifier');
var language = 'ja'; // ここに日本語を表す ja を設定

// ネットワーク内からGoogle Homeを見つけてくれる
googlehome.device('Google Home', language); 
// もし Google Home のIPアドレスを指定するなら、以下のスクリプトに置き換える
// googlehome.ip('xxx.xxx.xxx.xxx', language);

googlehome.notify('こんにちは', function(res) {
  console.log(res);
});

OK、問題ないです。

■続けてしゃべらせる
最後に「続けてしゃべらせる」ですが、たぶん最初に下記のようなプログラムを思いつくかと思います。

// ネットワーク内からGoogle Homeを見つけてくれる
googlehome.device('Google Home', language); 
// もし Google Home のIPアドレスを指定するなら、以下のスクリプトに置き換える
// googlehome.ip('xxx.xxx.xxx.xxx', language);

googlehome.notify('こんにちは', function(res) {
  console.log(res);
});

googlehome.notify('こんばんは', function(res) {
  console.log(res);
});
makeSpeak('こんにちは');
makeSpeak('こんばんは');

function makeSpeak(sentence) {

    // ネットワーク内からGoogle Homeを見つけてくれる
    googlehome.device('Google Home', language); 
    // もし Google Home のIPアドレスを指定するなら、以下のスクリプトに置き換える
    // googlehome.ip('xxx.xxx.xxx.xxx', language);

    googlehome.notify(sentence, function(res) {
        console.log(res);
    });
}

が、残念ながら、これはどちらもエラーになります。(下記のようなエラーが出ると思います。)
Error: mdns service already started
at Browser.start (c:\dev\js\google_home\node_modules\mdns\lib\mdns_service.js:30:11)
at Object.notify (c:\dev\js\google_home\node_modules\google-home-notifier\google-home-notifier.js:28:13)
at Timeout.makeSpeak [as _onTimeout] (c:\dev\js\google_home\google_home.js:37:16)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5)

といっても1行目に思いっきり「mdns service already started」とある通り、要は最初の命令がすでに実施中なので、次の命令を実行できない、というだけです。

なので、例えば下記のように、前の命令が終了してから次の命令を実行するようにすれば問題ないです。(タスクキューに追加するとか、もっといい方法はあると思いますが、ここではそれは置いときます)

// 前のmakeSpeak()の終了を待つためにsetInterval()をする。
var count = 0;
var val = setInterval(makeSpeak, 7500);

function makeSpeak() {

    // Google Home Notifierの設定
    var googlehome = require('google-home-notifier');
    var language = 'ja'; // ここに日本語を表す ja を設定

    var sentence = '';

    switch(count)
    {
        // しゃべらせる内容
        case 0:
            sentence = 'あくしろよ';
            break;
        case 1:
            sentence = 'おう考えてやるよ';
            break;
        case 2:
            sentence = 'すいません許してください。何でもしますから';
            break;
        default:
    }

    count++;

    // ネットワーク内からGoogle Homeを見つけてくれる
    googlehome.device('Google Home', language);

    // もし Google Home のIPアドレスを指定するなら、以下のスクリプトに置き換え
    // googlehome.ip('xxx.xxx.xxx.xxx', language);

    // 実際にしゃべらせる
    googlehome.notify(sentence, function(res) {
        console.log(res);
    });

    // 全部しゃべったら終了。
    if(count > 2) {
        clearInterval(val);
    }
}

※なお、上記プログラムを実際に実行した動画が、下記になります(手ブレはご勘弁を。)

いやー、苦労しましたね。
でもこれで、Google Homeの使用幅が広がりました。
これからは、Google Homeどんどん使いたいと思います。

…てか、我ながら長い文章だなあ。