🏠

Google Homeから音声でPCを起動する

2024/11/09に公開

「Ok Google, 春はあけぼの」と言うことでコンピュータを起動する方法について説明します。

Androidの日本語音声認識を使ってWoLによりPCを起動する方法については、IFTTTを使った方法がいくつか紹介されています。しかしこの方法はワークフローが大げさな上に、Googleの音声認識サービスの仕様変更により使い勝手が悪くなっているという問題があります。

さて、RedditにIFTTTを使わずGoogle Homeから音声認識を使って直接Android内のアプリケーションを起動する方法が紹介されていました。以下ではこの方法の紹介と応用として日本語音声認識によるWake on LANについて説明します。なお、Google Homeの操作の登録方法やTaskerの使用法については細かい説明を省きます。

作業に当たってはGoogle PlayからWake on LANアプリをインストールして、コンピュータを起動できるよう設定しておいてください。今回のワークフローはアプリ間連携を使うため、他のWoLアプリでは動作しないかもしれません。

Google Assistantの言語は日本語に設定されているものと仮定します。

処理の流れ

今回紹介する処理の流れを図に示します。

  1. ユーザーが発した音声は、Google Homeによっていったんクラウドの音声認識エンジンに送られます。そしてそこで解析され、"Ok, Google"に続く部分が登録されたコマンドであるか調べられます。
  2. 登録されたコマンドであった場合、あらかじめ登録しておいたノーティフィケーションがGoogle Homeに返されます。
  3. Google HomeはそのノーティフィケーションをAndroidデバイス内部で発行します。
  4. 発行されたノーティフィケーションはTaskerというアプリでキャッチされます。
  5. Taskerはノーティフィケーション内部に記述されたタスクがある場合、それを実行します。
  6. 実行するタスクはWake on LANアプリの呼び出しであり、それによって外部にWoLパケットが発せられます。

IFTTTを利用した方法では、1.にIFTTTを使い、2.にメッセージング・アプリを使います。その二つを「Google Home+YAML設定ファイル」に置き換えるというのが今回紹介する方法です。

Google Homeに登録するスクリプト

Google Homeのサイトを開き、 メニュー > 自動化 > 新たに追加 と進んで、以下のスクリプトを入力し、[保存]ボタンを押します。保存後、[有効にする]ボタンを押して有効化することを忘れないでください。

metadata:
  name: Taskerによる自動化スクリプト
  description: このスクリプトを自分用に編集して使う

automations:
  - starters:
      - type: assistant.event.OkGoogle
        eventData: query
        is: "春はあけぼの"
    actions:
      - type: home.command.Notification
        title: "Google Home Tasker Routine"
        body: "My Cool Task"
        members: YOUR_EMAIL_ADDRESS@gmail.com

このYAMLスクリプトは、Rdditに紹介されているスクリプトを日本人向けに変更したものです。

変更点は以下の3点です。

  1. metadataのnameを日本語に変更した。これはGoogle Homeページに表示される名前。
  2. metadataのdescriptionを日本語に変更した。これは利用者用の説明文。
  3. automationsのisを日本語に変更した。

3番目が重要です。このisはGoogle Assistantが認識すべきコマンドです。ここでは例題として『春はあけぼの』を使っています。つまり、Androidに向かって「Ok,Google. 春はあけぼの」と言うと、actionsに記述したことが実行されます。コマンドの選び方については経験的にわかっていることを後述します。

actionsのmembersには、自分のGoogleアカウントであるメールアドレスを書いておきます。Google Homeは複数人が使うことを想定しており、この部分でノーティフィケーションをどのユーザーに投げるのかを指定します。

このYAMLスクリプトについてもっと詳しく知りたい方は、Google Home Developer CenterのAutomations Script Editor を読むとよいでしょう。

Taskerプロジェクトのインポート

Androidのブラウザからプロジェクトのリンクを開いて、"Run Tasks from Google Home.xml"ファイルをダウンロードして下さい。そしてこのファイルをTaskerにインポートします。

インポートすると、Run Tasks from Google HomeプロジェクトがTaskerの画面下に現れます。この中には"Google Home Tasker Routine"プロファイルと、"My Cool Task"タスクがあります。

プロファイルの方は、先のYAMLスクリプトに従ってGoogle Homeが発するノーティフィケーションをキャッチし、タスクに振り分ける役目を持っています。このプロファイルは変更する必要はありません。

プロジェクトのインポートが終わったらテストをしましょう。Androidデバイスに向かって「春はあけぼの」と言うと、片言の英語でアナウンスが流れ、画面にメッセージダイアログが表示されます。

この時起きていることを図示します。

Google Homeから発せられた音声認識ノーティフィケーションには"Google Home Tasker Routine"という名前がついています。これはTaskerの中の"Google Home Tasker Routine"というNotificationプロファイルによってキャッチされます。そして"My Cool Task"というTaskerタスクが実行されます。

途中の経緯をインフラだとみなせば、YAMLに次のように書くことでタスクFOOを実行できると要約できます。

        body: "FOO"

タスクのカスタム化(その1)

タスクをカスタム化しましょう。

インポートしたばかりのTaskerプロジェクトには"My Cool Task"という名前のタスクが定義されています。これは次のような内容です。

  • タスク名は"My Cool Task"
  • 英語によるアナウンスを行うアクションを実行する。
  • メッセージ・ダイアログを表示するアクションを実行する。

これを次のように変更します。

  1. 名前を"Start my computer"に変更する。
  2. アナウンスを日本語に変更する。
  3. メッセージ・ダイアログの表示をやめる。

タスクの名前を変えたので、YAMLの方もactionsのbodyをタスク名に揃えます。

metadata:
  name: Taskerによる自動化スクリプト
  description: このスクリプトを自分用に編集して使う

automations:
  - starters:
      - type: assistant.event.OkGoogle
        eventData: query
        is: "春はあけぼの"
    actions:
      - type: home.command.Notification
        title: "Google Home Tasker Routine"
        body: "Start my computer"
        members: YOUR_EMAIL_ADDRESS@gmail.com

これで、Androidに対して「Ok Google, 春はあけぼの」と言うと、「コンピュータを起動します」というアナウンスが帰ってくるようになりました。

タスクのカスタム化(その2)

音声認識でタスクを起動する準備が整いました。仕上げとしてタスクにWake on LANを接続しましょう。

Taskerの"Start my Computer"タスクを開き、"+"ボタンをクリックして新しいアクションを追加します。するとアクションのリストが現れますので"Plug in"を選んでください。プラグインのリストの中にWake on LANアプリがりますのでそれを選択します。

すると、Wake on LANをプラグインとして実行するアクションが選ばれ、編集画面となります。そこで、Configurationの欄を編集してください。あらかじめ行っていたWake on LANの設定一覧が現れますので起動したいコンピュータを選びます。

これで終わりです。設定が正しければ、Androidに「Ok Google, 春はあけぼの」と話すだけでアナウンスが流れコンピュータが起動します。

複数コマンドでタスクを実行する

YAMLの構文を知っていれば、automations startersの中身がリストであることにピンとくると思います。type以下をコピペして並べれば、複数コマンドで一つのタスクを実行できます。

変更例を以下に抜粋します。

metadata:
  name: Taskerによる自動化スクリプト
  description: このスクリプトを自分用に編集して使う

automations:
  - starters:
      - type: assistant.event.OkGoogle
        eventData: query
        is: "春はあけぼの"
      - type: assistant.event.OkGoogle
        eventData: query
        is: "夏は夜"
    actions:
      - type: home.command.Notification
        title: "Google Home Tasker Routine"
        body: "Start my computer"
        members: YOUR_EMAIL_ADDRESS@gmail.com

この例では

  • 「Ok Google, 春はあけぼの」
  • 「Ok Google, 夏は夜」

のいずれかを言う事で、コンピュータを起動します。

コマンドでタスクを使い分ける

さらに複数コマンドのそれぞれに対して別のタスクを割り当てることもできます。

metadata:
  name: Taskerによる自動化スクリプト
  description: このスクリプトを自分用に編集して使う

automations:
  - starters:
      - type: assistant.event.OkGoogle
        eventData: query
        is: "春はあけぼの"
    actions:
      - type: home.command.Notification
        title: "Google Home Tasker Routine"
        body: "Haru"
        members: YOUR_EMAIL_ADDRESS@gmail.com
  - starters:
      - type: assistant.event.OkGoogle
        eventData: query
        is: "夏は夜"
    actions:
      - type: home.command.Notification
        title: "Google Home Tasker Routine"
        body: "Natsu"
        members: YOUR_EMAIL_ADDRESS@gmail.com

この例では

  • 「Ok Google, 春はあけぼの」によって"Haru"タスクが実行される。
  • 「Ok Google, 夏は夜」によって"Natsu"タスクが実行される。

ようになっています。

コマンドの選び方

「春はあけぼの」「夏は夜」を例題に音声認識を行いました。いくつか実験したところではGoogle Assistantには使いにくい癖がありますので書いておきます。

まず、これは予想できることですがコマンドはGoogleの音声認識が出力する文字列にしなければなりません。「はるはあけぼの」と発話すると「春はあけぼの」が出力されます。したがって「春は曙」をコマンドにすることはできません。YAMLに書いた文字列は音声認識の結果と比較されるのであって、「この文字列に一致する言葉を聞き取れ」というチャンレンジを与えているわけではありません。

ですので、コマンドを決める際には実際に認識させてどのような文字列が出力されるか調べておきましょう。

  • 「まじんごー」→「マジンゴー」
  • 「たて、じゃいあんとろぼ」→「縦、ジャイアントロボ」

おかしな文字列が返ってくるようならば使わない方がよいでしょう。将来変化する可能性があります。

また、妙な挙動がありました。

  • 「けいさんきをきどう」→「計算機を起動」が認識されタスクが実行される。
  • 「こんぴゅーたをきどう」→「コンピュータ」が検索される。

なんでやねん。

こういう、妙な挙動が多々ありますので命令文は避けた方がよいのかもしれません。Google Homeのあらかじめ用意されたルーチンも「おはよう」「仕事に行ってきます」といった命令形を避けた言葉になっています。

コマンドとして使う言葉を選ぶときには以上のような点に注意してください。

Discussion