Google Homeで設定したショートカットやIFTTTコマンドが認識されない時のチェックポイント

Google Home + IFTTTでは好きな音声コマンドに対して様々な動作をさせるレシピを作ることができます。例えばIF側にGoogleアシスタント、出力側(THEN THAT側)にIFTTT赤外線家電コントローラーという組み合わせをすれば、「○○と言ったら家電のスイッチが入る」といったことができてしまうわけです。またGoogleアシスタント側の機能としてショートカットというものがあり、文字通りコマンドワードの短縮形や言い換えを定義することができます。例えば「Netflixでスタートレックディスカバリーを再生」と毎回つっかえずに言うのが大変なら、「スタートレックを見る」をショートカットにしておけば、Google側で自動的に言い換え(聞き換え)てくれるわけです。IFTTTのGoogleアシスタント入力では1つのレシピに3つの言い換えが割り当てられますが、ショートカットを使えばより多くのパターンを指定できます。例えば部屋の照明をつける1つでも「電気をつけて」「照明をつけて」「灯りをつけて」「明るくして」といくらでも言いようがあります。しかもまたGoogleさんの聞き分けが正確なので「電気をつけて」に対して「電気つけて」では反応せずそれぞれ登録しておかなければなりません。設定した自分だけならまだしも機械に疎い家族の言い方もカバーしようと思うと大変です。そんな時にはショートカットが便利です。

さてそんな自由な音声コマンドで様々な操作ができる素晴らしい技術ですが、使ってみるとどうにも上手くいかないことがあります。本記事ではσ(^^)の経験則からそんな時のチェックポイントをまとめてみました。基本は「Google Home(アシスタント)はまず聞き取った音声を“文字”に変換してから登録コマンドを参照する」ということです。

■Googleの聞き取り方に合わせる

例えばテレビのHDMI入力切替をApple TVに切り替えたいと「AppleTVに切り替え」ってコマンドを設定したいとします。しかし「AppleTV」も「切り替え」も文字にすると「アップルTV」「あっぷるてぃーびー」「切り替え」「切換」など様々な書き方ができます。AppleとTVの間にスペースを入れるかどうかということもあります。こういう場合、どういうルールでコマンド文を書けばいいかというと、「それをGoogleに言ってみて聞き取った通り」が答えです。Googleアシスタントアプリなら聞き取った音声を文字にして表示してくれますし、ショートカット設定画面ではわざわざ入力欄の端にマイクボタンがあり声で入力することができます。これらの方法でGoogleがどう書き取るかを調べ、そのままを音声コマンドにするのが無難でしょう。

■マイナーな固有名詞を避ける

もうひとつのポイントとしては単語や文章として一般的ではないものを避けるという点。我が家の猫は「たね」といいます。たねのベッドに敷いたペットヒーターをスマートコンセントで制御し、「たねヒーターをオン(オフ)」というコマンドで制御できるようにしようとしたのですがどうしても上手くいきません。そこでGoogleアシスタントで聞き取りを確認してみると「亀ヒーター」などとなりWeb検索結果を表示しようとします。こうしたSpeech To Text技術では、多少音声入力状態が悪くとも、一般的な会話として意味が通じる日本語文章を成立さえようと寄せてきます。つまり「たね/ヒーターかな?亀/ヒーターかな?」ってなった時に、後者の方が辞書(=ネット)によくある組み合わせだから言葉として正しいに違いない、と判断してしまうわけです。これはショートカットに登録しようとIFTTTでコマンドワードに指定しようと無意味です。それらはすべて一旦テキストに変換されてからマッチするものを探しているからです。順番として言えば、

  1. Speech-To-Text処理でテキスト化
  2. ショートカット設定からピッタリ同じテキストがないか探す
  3. IFTTTのコマンドワードからピッタリ同じテキストがないか探す
  4. Googleアシスタントのコマンドワードからピッタリ同じテキストがないか探す
  5. どれにもマッチしなければWeb検索に投げる

みたいなイメージです(2〜4の順番は実際には違うかも知れませんが)。だから2や3で固有名詞的な単語を登録しても1の段階で一般的な日本語として寄せられてしまうのでなかなか思った通りに認識されないというわけです。

Google Homeのスマートデバイスは部屋を割り当てることができます。例えば「たねヒーター」の所在地を「ベッドルーム」にすることで「ベッドルームのたねヒーターをオン」というコマンドが使えるようになります。常識的に考えれば「ベッドルームの」といってる時点で候補が狭まって認識率が向上しそうなものですが、実験してみた感じあまり違いはありませんでした。やはり一旦「ベッドルームの亀ヒーター」などとテキスト化され、結果としてWeb検索にいってしまうことが多いです(100%ダメでもなく上手くいくこともある)。

結局解決策としては「ペットヒーターをオン(オフ)」というように「たねヒーター」ではなく一般語としてありがちな「ペットヒーター」に寄せることでステップ1での認識率を上げるしかありませんでした。好きな固有名をつけられないのは悔しいですが、ステップ1に対してユーザ辞書的なものをもたせる仕組みがないので現状は仕方なさそうです。子供の名前やペット名など固有名をつけてる場合は試しに換えてみてください(強いていえばCMでやってるように「ドレンを呼び出してくれ」で電話帳のドレンさんを指定できるわけなので、電話帳にある名前はステップ1でユーザ辞書的に働く可能性はあります。iOSでもSiriで「おやゆびでお」というマイナーアプリ名がどうしても認識されなかった時、電話帳に登録することでいけたことがあります)。

■スマートホームデバイスは部屋名にも注意

上述のようにスマートデバイスに部屋を割り当てることができます。別の部屋に「照明」のような同じ名前のデバイスを設置した時に「ベッドルームの照明をオン」「リビングルームの照明をオン」などと言い分けるためのもののようです。スマートデバイスの設定手順の中でどの部屋にあるものか指定する画面がでます。ここも適当に流してるといつのまにかトラブルの元になりやすいので注意しましょう。我が家の場合、気付いたら「リビングルーム」が3つくらいあったり、「リビング」があったりしてました。ここもしっかり整理し意図せぬ部屋にデバイスが割り付けられてたり、同名の部屋が複数できてないか確認してみてください。ちなみに部屋名を削除するには割り付けられたデバイスをすべて他の部屋に割り付け直して空にする必要があります。またバグなのかAという部屋のaというデバイスをBという部屋に移動させたい場合、A部屋の一覧から他へ押しつけるような操作だとなぜか適用されません。B部屋の一覧に入って他から横取りするような手順で試してみると良いかも知れません。そしてここでもカスタム名は避けた方が無難なようです。例えば我が家に猫専用の部屋を割り当てられる余裕があったら「たね部屋」とかつけたくなるかも知れませんが、おそらく「たねヒーター」と同じ問題が起きることが想像に難くありません。

 

コマンド、デバイス名、部屋名に使い慣れたあだ名を割り当てたいのは人情ですが、現状の音声認識の仕組み上、一般的な日本語会話に登場しない言葉はなかなか難しいということ、日本語テキストにすることと、そこからコマンドとマッチさせることはかなり独立のプロセスであることを意識しておくと、認識率の高いコマンド設計ができるんじゃないかと思います。

余談ですが、「平沢進(ひらさわすすむ)」というσ(^^)の好きなアーティストをSiriやGoogleアシスタントで検索させた場合、きちんと見つけてくれる一方で、「はい、ひらさわしんを再生します」的なトークバックが返ってきます。こっちが「すすむ」と言ってちゃんとそれを認識してるのに、なぜ「しん」と読むんだ?とツッコミたくなりますよね。これこそがSpeech-To-Textとその後の検索処理、読み上げ処理がまったく独立でなされている証拠といえるのではないでしょうか。認識の辞書と読み上げの辞書が別々なんだろうということです。

さらに余談ですが、こうしたコンピュータが「言葉を理解する」ということについて専門家でなくてもわかる物語仕立ての解説をしている良書を紹介しておきます。σ(^^)もまだ読みかけですが大変オススメです。

Google Home + IFTTTでAndroid BRAVIAを操作するWebhookの準備

Google HomeとIFTTTで家電を操作する場合、HTTPでどこかのURLを叩く受け口(Webhook)を用意するのが早道、というか必要です。前回、PioneerのAVアンプはネットワーク操作可能なもののtelnetの受け口しかなかったのでPHPスクリプトを使って橋渡しをしました。BRAVIAの場合はHTTPでXML形式のファイルを送りつけてやるといけるという記事が散見されるのですが、その記事で紹介されているcurl(テキストWebクライアント)を使った方法では成功しませんでした。

結局上手く言ったのは、こちらの記事を参考に、GitHubにあるalanreid氏のNode.jsプロジェクトを使った方法でした。

Node.jsは不慣れなのでいつものmacOS Server機ではなくCentOS仮想サーバーを使用。ちょっと昔すぎて手順は憶えてないですがNode.jsなどはyum installでサクっと入ると思います。

まずAndroid BRAVIA側でIP操作を受け付ける許可とPSK(暗証番号)の設定をします。

  • ホーム -> 通信設定 -> ホームネットワーク-> モバイル機器/レンダラー機能を「入」に
  • ホーム -> 通信設定 -> ホームネットワーク-> IP コントロール -> 認証 を「Normal and Pre-Shared Key」に
  • ホーム -> 通信設定 -> ホームネットワーク-> IP コントロール -> Pre-Shared Keyで4桁の暗証番号を設定
  • ホーム -> 通信設定 -> ホームネットワーク-> IP コントロール -> 簡易IPコントロール を「入」に

またルーターもしくはBRAVIA自体の設定を変更し、固定IPアドレスになるようにしておくと良いでしょう。

次に適当なフォルダにalanreid氏のプロジェクトをクローンします。

そのフォルダに、demo.jsやhttp-bravia-echo.jsなどがあると思います。

demo.jsで動作チェック

???をBARVIAのIPアドレスに変更。xxxxをBRAVIA上で設定した暗証番号に変更します。

これでコマンドラインから、

とすると、画面には利用できるコマンド一覧が表示され(condole.log(list);の結果)、続いてテレビの電源が入ってNetflix画面になる(cluent.exex(‘Netflix’);の結果)はずです。demo.jsはこの2つのコマンドを連続で実行する、まさしくデモ用のファイルです。コマンドライン用の実行ファイルを作るのであれば、これをコピーし、前半のList available commandsのセクションを削除し、Netflixコマンドを他のものに書き換えるだけで良いでしょう。

ブラウザからの操作を受け付ける

本来Node.jsは.jsスクリプトをサーバーとして待ち受けさせて、ブラウザからアクセスがあった時に所定の動作を行わせるためのものです。その為の基本動作を組み込んだのがhttp-bravia-echo.jsです。こちらも自分の環境にあわせてちょっとだけ修正します。

portはブラウザからアクセスする時に必要になります。Webサーバーといえば80番が標準的ですが、セキュリティの問題とか色々あるので避けた方が無難です。特に他とぶつかったりしてなければ標準の5006で良いでしょう。いくつにしたかだけ憶えておきます。???とxxxxは先ほどと同じ、BRAVIAのIPアドレスと暗証番号です。

します。最後に「&」をつけておくことで、ユーザがコンソールからログアウトしても裏で動き続けるようになります。動作テストの間はつけない方が良いかも知れません。またOSを再起動すると止まってしまいまた同じ様に起動する必要があります。OS起動時に自動起動する方法は別途ググってください。

さて、エラーもなく正常に起動したら、ブラウザから呼んでみます。

のようにします。ここでは暗証番号は使わないので注意してください。WakeUpがコマンドになります。電源オンはPowerOnではなくWakeUpでいけるようです。成功するとWebページとしては「OK」とだけ出ます。注意したいのはその操作(ボタン)を受け付ける状態になっていないとOKが返った場合でもなにも起きないということです。例えば「Num1」はテンキーの1ボタンですが、ホーム画面やNetflixアプリを起動している状態ではなにも置きます。先に「Tv」にしておいてから「Num1」にするとチャンネルが切り替わる、という具合です。「OK Google、NHKを映して」みたいなことをしたい場合、IFTTT側ではマクロ操作できないので、スクリプト側でWakeUp->Tv->Num1のように連続的にコマンドを送る必要がありそうです。音量についても1回に1目盛り上げ下げしても仕方ないので、数回繰り返すような処理が必要でしょう。JavaScriptが得意な人はこのhttp-bravia-echo.jpを直接改造すると良いと思います。σ(^^)はPHPの方が得意なので、別にApacheサーバーでホストしたスクリプトから連続で呼び出すようにしようかと思案中です。

IFTTT(インターネットから)呼び出す

IFTTTのサーバーは当然ながら自宅のイントラネット(LAN)の外にあります。なので、IFTTTアプリのWebhookアドレスとして上記の「192.168.x.x」といったアドレスを入力しても到達できません。ルーターのポート開放設定が必要だったり、利便性として固定IPアドレスやダイナミックDNSアドレスなども欲しくなるでしょう。

Google Home miniも追加購入。無印との違いは?

Google Home便利すぎて、仕事部屋にも欲しくなったminiを予約。本日届きました。チャコールです。

電源ポートがmicroUSBなので良いです。付属のACアダプタではなくデスクのAnkerの10ポートハブから電源がとれてスッキリ。出張や帰省などで一時的に持って出る時も電源の心配をせずに本体だけさっと持っていけるのがいいですね。

ちなみに付属の充電器はこんな丸くてかわいらしいものですが出力は5V/1.8Aとなかなかのものでした。スマホ付属の充電器(iPhoneだと1.0A)やコンビニや百均の乾電池式充電器(0.5Aくらいのもある)だと電力不足で動かないかも知れないですね。付属以外で選ぶ時は2.0A級のものにしておいた方がいいかも知れません。

音楽はデフォルトスピーカーを指定できるので、既設のSRS-HG1を指定。「OK Google, ○○を再生」とするだけで出力先は指定せずともそちらから鳴ってくれます。ただしSRS-HG1がスリープだと鳴り始めるまでにちょっと待たされるのと、再生中に「OK Google」した時にミュートがかからないのが惜しい。ただミュートかからないで音楽鳴ってる状態でも認識率はさほど定価しない気もします。

あと無印Google Homeは天面がタッチスイッチになっていて、音声を止めたりクルクルジェスチャーでボリューム調整できたりするんですが、miniではそういうことが一切できないので、音量調節から音声でする必要があります。

仕事机に設置して椅子に座った状態でしか使ってないのでマイク精度の違いは比較できませんが、少なくとも口から1mもない距離では全く問題ないと言えます。

できることと比して考えるとコスパは非常に高いんじゃないでしょうか。特に音楽は別のスピーカーで聴くからいいやって人はこちらのminiがオススメです。たくさん買って存在感なく家中に偏在させたい感じです。音楽も無印Homeは低音が出すぎという評価もありますし、別途Chromecast内蔵スピーカーやChromecast Audioをお使いの方は割りきってこちらにするのもアリですね。

Google Home + IFTTTでPioneerのAVアンプを操作する(赤外線不使用)

Google Home、快適です。Android BRAVIAを制御できないので悔しくて、対応も待ちきれず結局Chromecast Ultraも買っちゃいました。で、BRAVIAのHDMI入力が足りなくなり、AVアンプと配線を見直し。ウチのAVアンプPioneerのVSA-1124はHDMI1,2とBDが4K/60pの4:4:4に対応、あとは4:2:2対応です。

というかHDRに対応したHDMI2.0aではないので、AVアンプを経由するとせっかくのChromecast Ultraのメリットが一部活かされません。ということでUltraをBRAVIAに直結し、4K関係ないNintendo SwitchをAVアンプ経由に。

しかしこの組み合わせで問題なのは、HDMI-CECによる自動入力切替がイマイチちゃんと働かないという点。Switchを起動しても自動で映ってくれません。仕方ないのでこれもGoogle Home + IFTT + Nature Remoで制御しようと思い、(普段iPhoneアプリから操作してるので)使ってなかった赤外線リモコンを発掘してみると、なんとHDMI選択が順送りボタンのみで、ダイレクトに特定のHDMI番号を指定できませんでした…
これででは例えばHDMI1のSwitchに切り換えたいとしても今が何番かによってボタン押下回数が違ってくるので、Nature Remoからの単純な赤外線信号では一発変更できないことになります。というか事実上無理。

なんか手はないかなぁと思って、iPhoneアプリから操作できるんだからなにかしらのTCP/IPプロトコルによる制御、あわよくばWebhookで叩けるんじゃね?ってことで検索。もともと80番ポートは空いてて、ブラウザから設定画面を呼び出せるんですが、残念ながら操作関係は不可能。なんとtelnetで制御しているということがわかりました

以下のような感じで、telnetし、認証もプロンプトもありませんが、「?P」と打つと今の電源状態(ONならPWR0など)が返ってきます。「?V」なら音量がわかるし、HDMI1に切り替えたい時は「19FN」という感じです。なんと親切なことに米Pioneerが仕様書PDFまで公開してくれてます

残念ながらIFTTTでtelnet制御ができるレシピはありませんし、(IFTTTから到達可能なように)外向けにtelnetポートを空けたくもありません。自宅内WebサーバーにPHPスクリプトを置き、そこからAVアンプにtelnetしてHDMIポート変更コマンドを送りつけてみることにしました。

PHP用のtelnetライブラリですが、ざっと探して最初に見つけたのは使えず、こちらで成功しました。Installの項目にあるようにcomposerでインストールを済ませた後、こんなコードで切換に成功しました。

自分に必要な機能しか実装してません。$commandsの中でPOSTでcmd変数にセットされるコマンドと実際の制御コードの対応付けを定義しています。これで「OK Google, アンプの電源を入れる」といったGoogle Assistantサービスの「Say a simple phrase」を使った固定コマンドなら、そこからWebhookでこんな感じにすれば動きます。Body欄の=の右辺が指定したいコマンドです。

少し応用的な使い方として音声コマンド中の文字列をコマンドとして渡す「Say a phrase with a text ingredient」も試してみました。HDMIの入力毎にアプレットを作るのが面倒なので、1つで済まそうという狙いです。「アンプを(入力名)に切り換え」みたいにすると、PHPスクリプトに入力名の部分が渡されるので、それを使ってswitch文のところでコマンドに置き換えています。「What do you want to say?」欄で「avアンプを $ に切換」のようにします。$の両側には半角スペースを空けます。avを小文字にしたのは、スマホのGoogle Homeアプリで実際にしゃべってみた時に出る認識文がそうなっているので合わせました。

THEN側はこんな感じにBody欄に入れます。<<<>>>で囲った部分がURLエンコードされます。TextFieldというプレースホルダは「Add ingredient」ボタンを使って挿入できます。PHPスクリプトのswitch文の中の対応付けも、Google Homeアプリでしゃべってみてどうテキストになるかを参考にします。基本的には英単語は半角小文字になるようです。「スイッチ」のようなカタカナ語はそのまんま。「ぴーえすふぉー」だと「ps 4」のように半角スペースが入りますが、入ったり入らなかったりで揺れると面倒なので、スクリプト側で半角スペースを除去しています。結果として「apple tv」は「appletv」になります。時にカタカナで「アップル tv」と認識されることもあったので両方ともhdmi4に対応付けています。このあたりはスマホのGoogle Homeアプリで色々しゃべってみて結果を反映させましょう。

これで一応設定は完了なんですが、Google Homeで認識させると全く同じ「avアンプをスイッチに切り替え」となるのに、IFTTTコマンドとして認識される時と、Web検索になってしまう(ハードのGoole Homeだと「すみません(ry」)ことがあり、成功率が低いです。コマンドを長くしてみてもあまりかわりません。IFTTTで設定してから反映されるまでに若干タイムラグがあるような感じもします。

結局どうやっても必ずIFTTTコマンドとして認識されるようにはできなかったので、Google Homeのショートカットで「スイッチに切り替え」や「スイッチを表示」を「avアンプをスイッチに切り替え」に置き換わるようにしてみたところ、成功率が上がりました。ショートカットに色々書くなら最初から「Say a phrase with a text ingredient」で入力別にアプレットを作っても一緒じゃないか、って気もしますが、IFTTTのGoogle Assistantは言い換えが3種類までなのに対し、ショートカットならもっとバリエーションを持たせられるとか、修正フローが若干楽とかで、メンテナンス性は良い気がするので良しとします。

繰り返しになりますが、上手くいかない時は、

  • スマホアプリ版Google Homeでどうテキスト化されるか調べる
  • テキストとしては通ってるのに音声コマンドとして認識されない時はショートカットで定義する

などを試して見るといいでしょう。またPHPスクリプトが上手く動かない時は、一旦MethodをGETにして(URL欄に「スクリプト名?cmd=<<<TextField>>>」とし、スクリプトもfilter_inputの部分をPOSTからGETにする)、ブラウザから叩いてみるといいかも知れません。GETのままでもいいんですが、日本語コマンド名が長いと255文字(だっけ)超えるかもなと思ってPOSTにしています。

予想外に苦労しましたがなんとかなりました。Google HomeとPioneerアンプというレアな(?)組み合わせの話であまり参考にできる人はいないかもですが覚え書き(telnetでなにかしたい時にはいいかも?)。

Google Homeから家庭内「iPhoneを探す」

自宅内でiPhoneが見当たらない時、「iPhoneを探す」は重宝しますよね。ただしPC起動してブラウザから呼び出すか、他のiOS端末が必要でちょいめんどくさいです。アメリカだと標準で電話を鳴らす機能があるっぽいんですが、電話が基本都度課金される日本ではなかなか難しいのかも知れません。IFTTTでも電話発信はUS Onlyとなっています。通知を鳴らしたりメールを送信することはできますが、1度鳴るだけだと部屋中探索には向きません。

しかしちゃんと使えるアプレットがありました。「VoIP Calls」です。名前からすると外部サービスのアカウント(050番号?)登録が必要なのか?と一瞬思ってしまいますが、実際にはIFTTアプリのビルトイン機能らしく、iPhone上のIFTTTアプリが入っていればすぐ着信が受けられます。iOS10辺りで導入された標準電話着信画面のAPIを使ってるみたいです(LINE無料通話とかMessenger通話で出るアレ)。本当にVoIPで着信してるのか、アプリで疑似的に着信画面だけ出して出た後はアプリがテキストを音声合成してるのか不明ですが、ともあれ見かけ上は電話がかかってきて、指定したテキストを読み上げてくれます。

これを「iPhoneを探す」的に使うんだったら、こんな感じのレシピを作ればよさそうです。

以下は実際の着信の様子。