Raspberry Pi にGoogle Assistant SDKを搭載して「OK Google」してみる。

つい先日、[Google Assistant SDK](https://developers.google.com/assistant/sdk/) がサードパーティーに公開され、RaspberryPiでも利用できる様になったので、早速試してみました。

[![RaspberryPi GoogleAssistant](http://img.youtube.com/vi/s_Y_BjKHEjw/0.jpg)](https://www.youtube.com/watch?v=s_Y_BjKHEjw)

[RaspberryPi GoogleAssistant  - YouTube](https://www.youtube.com/watch?v=s_Y_BjKHEjw)

おなじみ「OK Google」から音声コマンドを使って、天気情報やGoogle音声検索などが行えます。

今回公開されたSDKはIFTTTとの連携が簡単に行えます。試しに音声で照明の点灯・消灯などを試してみました。残念ながら今のところ日本語対応はしていないのですが、相変わらずGoogleの音声認識精度はとても高いと感じました。

SDKは`pip`でインストール出来、手軽に使う事が出来ます。簡単にまとめてみます。

## 環境

![2017-04-29 22_56_04.gif](https://qiita-image-store.s3.amazonaws.com/0/47128/fc9b6760-5b18-53fd-23f6-5b7739087a81.gif)

- Raspberry Pi3 (RASPBIAN JESSIE WITH PIXEL 4.4　/ Python 3.4.2)
- LOGICOOL ウェブカム HD画質 120万画素 C270
- ミニロボットPC等用スピーカー小型かわいい白
- 7インチ(1024*600) IPS液晶パネル　ディスプレイ
- irMagician-T（大宮技研）

音声入力用のマイクはウェブカムのマイクを使用しました。

## Google Cloud PlatformでAPIの認証情報を取得する

![Google Assistant SDK  |  Google Assistant SDK  |  Google Developers 2017-04-29 22-59-47.png](https://qiita-image-store.s3.amazonaws.com/0/47128/88e8fb74-035e-4a24-c578-96428681c6f8.png)

[Google Assistant SDK](https://developers.google.com/assistant/sdk/)

公式ページのドキュメントに沿って設定をすれば比較的簡単に設定する事が出来ます。SDKはGoogleCloudPlatformを利用しますのでアカウントの設定はあらかじめしておきます。

![Configure a Developer Project and Account Settings  |  Google Assistant SDK  |  Google Developers 2017-04-29 23-07-20.png](https://qiita-image-store.s3.amazonaws.com/0/47128/4b26728b-0144-a363-f7ed-81ff84fdaf29.png)

ドキュメントにある「GO TO THE PROJECTS PAGE」ボタン押下でプロジェクトが自動的に作成出来ます。このプロジェクトのAPIキー経由で、Googleのサーバーを利用し音声認識を行う事が出来ます。

![認証情報 - My Project 2017-04-29 23-12-30.png](https://qiita-image-store.s3.amazonaws.com/0/47128/6c3e2eb0-e4c6-c03d-5ad9-43f9ab3bfe2f.png)

「API Manager」→「認証情報を作成」により、「APIキー」と「クライアントID」を作成します。

![クライアント ID の作成 - My Project 2017-04-29 23-15-57.png](https://qiita-image-store.s3.amazonaws.com/0/47128/904e81f6-8cb7-b81e-2445-ea300a84c539.png)

「クライアントID」で一つ注意が必要です。今回はRaspberryPiを利用しますので「その他」を選択して下さい。

![OAuth クライアント - My Project 2017-04-29 23-19-49.png](https://qiita-image-store.s3.amazonaws.com/0/47128/5d935e6a-46db-a6b3-02be-f83396582135.png)

「クライアントID」が取得出来たら「クライアントシークレット」のJSONファイルをダウンロードします。ドキュメントに従って

```bash:ssh
$ scp ~/Downloads/client_secret_XXXX.json pi@<raspberry-pi-ip-address>:/home/pi/
password: <password-for-raspberry-pi>
```
RaspberryPiのIPアドレスとパスワードを設定します。

## Google Assistant Python Sample

![googlesamples:assistant-sdk-python: Samples and bindings for the Google Assistant API 2017-04-29 23-28-01.png](https://qiita-image-store.s3.amazonaws.com/0/47128/74063162-ca7d-76e9-bee0-cf43a31069f4.png)

[googlesamples/assistant-sdk-python - GitHub](https://github.com/googlesamples/assistant-sdk-python)

公式のレポジトリにSDKのインストール方法が詳しく書かれているのでRaspberryPiに`pip`でインストールします。

```bash:ssh
$ sudo apt-get install portaudio19-dev libffi-dev libssl-dev
$ sudo python3 -m pip install --upgrade google-assistant-sdk[samples]
```
IPアドレスとパスワードを事前に登録しているので、環境変数の設定などをせず利用出来ます。ユーザーフレンドリーなSDKですね。

```bash:ssh
$ python3 -m googlesamples.assistant
INFO:urllib3.connectionpool:Starting new HTTPS connection (1): accounts.google.com
INFO:root:Connecting to embeddedassistant.googleapis.com
Press Enter to send a new request...
```
これでGoogleAssistantと会話ができる様になります。時間や天気、単語検索などはサンプルコードからも利用出来ます。

## IFTTTに登録する

![Do more with Google Assistant - IFTTT 2017-04-29 23-46-55.png](https://qiita-image-store.s3.amazonaws.com/0/47128/6575e6e7-a2c5-5ad9-dbd7-6c10864db7cd.png)

[IFTTT](https://ifttt.com/google_assistant)

GoogleAssistantはIFTTTのレシピになっているので、連携が簡単に行えます。試しに「『Tweet』と発話したらツイートする」レシピを作ってみます。

![If You say  tweet   then post a tweet to  pon_dad   IFTTT.png](https://qiita-image-store.s3.amazonaws.com/0/47128/0d7f3f33-6228-dbb9-5b3f-c12e7cc203a9.png)

レシピを保存、実行したら、RaspberryPiにGoogleAssistantを立ち上げて「Tweet」と言ってみます。

![ポンダッドさんのツイート: "**これはテストツイートです** Googleアシスタントさんからツイートしています。" 2017-04-29 23-53-38.png](https://qiita-image-store.s3.amazonaws.com/0/47128/7155d22d-e92b-19bb-7f15-f031bb2f5842.png)

こんな感じでツイート出来ました。

さて、ここからが本番です。ドキュメントにはIFTTTの「Maker Webhooks」を使うと簡単に出来るよ。と書いてあります。RaspberryPiのローカルサーバーにWebhookを送信するには「ngrok」を使うと良いと書いてあります。

## ngrok

![ngrok - secure introspectable tunnels to localhost 2017-04-29 23-59-44.png](https://qiita-image-store.s3.amazonaws.com/0/47128/5440bf59-05e8-acec-4086-42bdcde6b95a.png)

[ngrok](https://ngrok.com/)

今まで知らなかったのですが、これを利用するとローカルサーバーのアドレスを公開アドレスとして利用する事が出来ます。このアドレスを利用してIFTTTからGET（POST）リクエストを送信しRaspberryPiを動かすという仕組みです。

![ngrok - download 2017-04-30 00-03-34.png](https://qiita-image-store.s3.amazonaws.com/0/47128/8598b0f7-3136-bd2f-e78d-9f72ce374d20.png)

RaspberryPiのChromiumから公式ページを開き、「LINUX ARM」版をダウンロード、解凍するとアプリを利用出来る様になります。

![ngrok - secure introspectable tunnels to localhost 2017-04-30 00-05-53.png](https://qiita-image-store.s3.amazonaws.com/0/47128/7ca85284-849b-fce7-1c54-44ff7d6cd7c7.png)

無料アカウントを登録するとリクエストトークンが発行されるのでRaspberryPiに登録します。登録が終わったら以下の様なコマンドを実行します。

```bash:ssh
$ ./ngrok http --region ap 8080
```
これでアジアリージョンのアドレスとlocalhostの8080番ポートを紐づける事が出来ます。

```bash:ssh
ngrok by @inconshreveable                                       (Ctrl+C to quit)
                                                                                
Session Status                online                                            
Account                       xxxxxx (Plan: Free)                               
Version                       2.2.4                                             
Region                        Asia Pacific (ap)                                 
Web Interface                 http://127.0.0.1:4040                             
Forwarding                    http://xxxxxxxx.ap.ngrok.io -> localhost:8080     
Forwarding                    https://xxxxxxxx.ap.ngrok.io -> localhost:8080    
                                                                                
Connections                   ttl     opn     rt1     rt5     p50     p90       
                              0       0       0.00    0.00    0.00    0.00 
```
無料プランでは実行の度にアドレスはランダムに変わってしまいます。固定アドレスを使用するには有料プランに課金しないといけないみたいですね。

さて、もう少しです。RaspberryPiにローカルサーバーを立て、IFTTTからのリクエストを受け取れる様にします。

## ローカルサーバーを立てる

`node.js`でローカルサーバーを立てる際はフレームワーク`express`を利用していたのですが、Pythonでは初めてだったので、一番シンプルそうな`bottle`フレームワークを利用しました。

irmagicianのPythonライブラリは [netbuffalo/irmcli　- GitHub](https://github.com/netbuffalo/irmcli) こちらで公開されているので、これをPython3で動作する様に一部書き換え、bottleでローカルサーバーを立てました。

[PonDad/app.py - Gist](https://gist.github.com/PonDad/fcea6e5cfbb1b2b52c249d9d9dea1d32)

irmagicianの赤外線読み取りは[iOS10「ホーム」アプリと「Raspberry Pi + irMagician」でお手軽家電操作。 - Qiita](http://qiita.com/PonDad/items/a17d8b7d0be59f4c7f18) この記事と同じです。

さて、これで`python3 app.py`でローカルサーバー`http://localhost:8080`が立てられ、パス`http://localhost:8080/light_on`に接続されると照明がつき、`http://localhost:8080/light_off`に接続されると照明を消せる様になりました。

ngrokを作動させておけば、外部アドレスとして`http://xxxxxxxx.ap.ngrok.io/light_on`と`http://xxxxxxxx.ap.ngrok.io/light_off`でRaspberryPiを動作させる事が出来ます。

## IFTTTと連携する

さて、ようやく準備が整いましたのでIFTTTと連携させてみます。

![If You say  light on   then make a web request   IFTTT (1).png](https://qiita-image-store.s3.amazonaws.com/0/47128/8f32021c-04d2-0235-69ab-b752108dff81.png)

これは照明をつけるレシピです。消灯のレシピと合わせて登録すれば完成です。

## まとめ

RaspberryPiに特化したSDKなのでインストールが楽に行え（重要）、高性能な音声認識を利用する事が出来ました。

WebサービスやRaspberryPiの様なIoT機器との連携が手軽に出来るので日本語対応が楽しみですね。では。

## 追記（2017/5/21）

SDKが0.1.0から0.3.0にバージョンアップしていたので追記します。

![Download the Library and Run the Sample     Google Assistant SDK     Google Developers.png](https://qiita-image-store.s3.amazonaws.com/0/47128/fc3ab010-3e06-722b-a598-82e315cc0cc7.png)

[Download the Library and Run the Sample - Google Assistant SDK
](https://developers.google.com/assistant/sdk/prototype/getting-started-pi-python/run-sample)

oauthの認証をライブラリを使って行うように変更になっています。

上記サンプルでは仮想環境を作らずそのままSDKをインストールしていたのですが、新しいバージョンだと動作しませんでした。

リンクを貼っておきますので詳しくはそちらをご参照下さい。では。