ラズパイを用いてGoogle Home に「ただいま」と言うと音声ファイルが再生される

#Google Home に「ただいま」と言うと音声ファイルが再生される
Qiitaで色々な方の記事を参考にしつつ作りました
初投稿なので誤りやお気付きの点がございましたらご指摘お願い致します

#大まかな流れ
1.Google Home に「帰ってきたよ」と言う
2.Google Homeが音声認識
3.Raspberry Piが認識した音声から該当する音声ファイルを再生

#音声ファイル再生までの流れ
![スクリーンショット 2018-08-27 9.09.46.png](https://qiita-image-store.s3.amazonaws.com/0/284042/7f894c0e-d521-f16d-3d7b-32db2f233092.png)


#使用したもの
・Google Home mini
・Raspberry Pi zero 


#音声認識をしてRaspberry Piにデータを送るまで
PC側の準備とRaspberry Pi側の準備で分けました
##IFTTT・Webhook・BeeBotte・Node-Redの準備
こちらの記事を参考にしました↓   分かりやすくまとめてあります
[IFTTT から Raspberry Pi に指示を出す]
(https://qiita.com/minatomirai21/items/4c4e777b43ede1e42900)
以下に本記事においてアレンジを加えた箇所を載せて起きます



<b>・IFTTTの「this」</b>
"trigger"を"Say a phrase with a text ingredient" から "Say a simple phrase"
に変更して作成しました
参考記事では"What do you want to say?"において入力値"$"を文章の先頭に持ってこれないため

>|項目|入力値|
>|:---:|:---:|
>|What do you want to say?|ラズパイに $ と送信|
>|What do you want the Assistant to say in response?|ラズパイに $ と送信します|

と"ラズパイに"を追加していましたが、もっと短いフレーズで行いたく"Say a simple phrase"を使用しました
![スクリーンショット 2018-08-29 23.27.22.png](https://qiita-image-store.s3.amazonaws.com/0/284042/307f07ff-9c42-bd4b-4a2c-ffb96d49ada4.png)

"What do you want the Assistant to say in response?"には
「。」を入れると無言でIFTTT「that」のactionが行われます
ただ作成段階で「。」にすると反応がないため「はい」などの短いフレーズにすると楽です

「　　　」のように何も記入しないと
Google Homeが「OK アクションを実行します」と発声しフレーズが長くなるのでオススメしません



※"Say a phrase with a text ingredient"の方が応用がきく気がします




<b>・IFTTTの「that」</b>
"Say a simple phrase"変更に伴い"Body (optional)"を
{"data":[{"xxxxx"}]  （←ここのxxxxx には好きなワードを入れてください）
にします
![スクリーンショット 2018-08-29 23.35.19.png](https://qiita-image-store.s3.amazonaws.com/0/284042/2925e242-56d2-22f0-cf6f-38f9aeca8c3b.png)

上図のようにすることで
Raspberry Piに"xxxxx"がデータとして送信され
そこで条件分岐させることが可能で、後ほど説明します


##Raspberry Pi側での準備
[IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する]
(https://qiita.com/msquare33/items/9f0312585bb4707c686b)
よりライブラリインストールをします
下にこの記事から引用したscriptを載せます
>
```smarthome.py
import paho.mqtt.client as mqtt
import json
TOKEN = "[Beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "MySmartHome/voice"
CACERT = "mqtt.beebotte.com.pem"
def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
    client.subscribe(TOPIC)
def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    data = {key:value.strip() for key, value in data.items()}
    if "room" in data.keys():
        print(data)
client = mqtt.Client()
client.username_pw_set("token:%s"%TOKEN)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(CACERT)
client.connect(HOSTNAME, port=PORT, keepalive=60)
client.loop_forever()
```
>

ここで

```py
TOKEN = "[Beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "MySmartHome/voice"
CACERT = "mqtt.beebotte.com.pem"
```
はテキトーに自分が設定したものに変更していくのですが

```py

CACERT = "mqtt.beebotte.com.pem"
```
だと名前が重複している？か何かでエラーが出てきたので
ファイルの名前を変更しました
参考URLが見つからなかったので、エラーが出てきた方はググった方が良さそうです


下に作成したscriptを載せておきます

```sh2.py

import subprocess
import paho.mqtt.client as mqtt
import json

TOKEN = "token_xxxxxxxxxxxxxx"  #[ご自身のトークン]
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "raspi/action"
CACERT = "vee.pem"

def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
    client.subscribe(TOPIC)
    
def on_message(client, userdata, msg):
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    data = {key:value.strip() for key, value in data.items()}
    if "xxxxx" in data.keys():    #xxxxxには好きなワードを
        subprocess.call("aplay xxxxxxxx.wav", shell = True)
    if "yyyyy" in data.keys():    #yyyyyにも好きなワードを
        subprocess.call("aplay yyyyyyyy.wav", shell = True)
        
client = mqtt.Client()
client.username_pw_set("token:%s" % TOKEN)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(CACERT)
client.connect(HOSTNAME, port=PORT, keepalive=60)
client.loop_forever()
```

先述したIFTTTの「that」において決めた好きなワードを上のscriptの”xxxxx”に入れることで応答するようになっています
複数の音声認識で応答するようにするには、"yyyyy"のように好きなワードをまた決めて、if文を増やしていけばOKだと思います


#音声再生
音声出力の際にいくつか作成しました
下にもまとめてありますが、一応参考にした記事になります→[Raspberry Piで音楽(wav/mp3)ファイルを再生する方法 python編](https://qiita.com/Nyanpy/items/cb4ea8dc4dc01fe56918#1pygame)
###パターン①
<b>サーバにあげたmp3をgoogle-home-notifierを用いてGoogle Home miniで再生する</b>

Google Homeから音声(音楽)を再生させる方法を調べたところ"google-home-notifier"を用いる方法が数を多く出てきました
[Google HomeでMP3を再生](https://scrapbox.io/smart-home/Google_HomeでMP3を再生)を参考に進めることでmp3をサーバにあげることで、Google Homeがそのサーバに接続し再生させることができました
"google-home-notifier"の使い方はこちら→[Google Home開発入門 / google-home-notifier解説](https://qiita.com/SatoTakumi/items/c9de7ff27e5b70508066)

```yobuyo.js

const googlehome = require('google-home-notifier');

googlehome.device("Google-Home",'ja');

googlehome.ip("192.168.XX.XX");

googlehome.play('http://192.168.XX.XX:3000/xxxxxx.mp3',(res)=>{
    
    console.log(res);
                });
```

ご自身のGoogle HomeのIPアドレスとRaspberry PiのIPアドレスおよびサーバのアドレスを上のscriptに入れることで使えるようになると思います

ちなみにこのパターンではpythonのみでは実装できないため
python内でJavaScriptを実行しなければなりません
したがって以下のようにJavaScriptをsubprocessで呼びます

```py

def on_message(client, userdata, msg):
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    data = {key:value.strip() for key, value in data.items()}
    if "xxxxx" in data.keys():
        subprocess.check_call('node /home/pi/yobuyo.js', shell = True) ##ここが変わったよ

```

これでGoogle Homeから音楽(音声)出力できるよーになるのですが、、、


<b>しかーし</b>


JavaScriptを呼び、そのサーバから出力するのにとても時間がかかるため
音声認識から5秒ぐらい待たなければいけません

そこで最初考えていたこのパターンは諦めなければなりませんでした


###パターン②
<b>Google Home miniをBluetoothスピーカーとして再生する</b>
```sh2.py```は先のパターンを諦めた末に生まれたもので、Google HomeをBluetoothスピーカーとして使用することを前提に作成してあります
aplayを使うとwavしか対応がないので少し面倒くさいのが難点。

Bluetoothスピーカーとして使うために設定として
[Bluetoothスピーカーから音を出す](http://belial6.hateblo.jp/entry/2017/06/30/003546)や[Raspberry piでbluetoothスピーカーを鳴らす](http://zokibayashi.hatenablog.com/entry/2017/10/10/020902)を見ていただければ簡単に設定できると思います

ポイントとしてデスクトップ上部のパネルにおいて、Bluetoothだけで選択するのではなく、隣のスピーカーを右クリックしてGoogle Homeを選択することが大事だと思います

#動作確認

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">できた。 <a href="https://t.co/7ggO0GYhsB">pic.twitter.com/7ggO0GYhsB</a></p>&mdash; えるちき (@study2093) <a href="https://twitter.com/study2093/status/1035074561186746368?ref_src=twsrc%5Etfw">2018年8月30日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

Google Homeからの反応が欲しかったため「はい」と応答が返ってきます
最後に再生される音楽を好きなものに変えることで色々楽しめるかと・・・

音声認識されて音楽が再生されたときのもの↓
![スクリーンショット 2018-08-30 16.24.15.png](https://qiita-image-store.s3.amazonaws.com/0/284042/39a6e0b3-5a0c-e5e1-223a-29b4bbd5d8a2.png)



#最後に
「ただいま」と言うとGoogle Homeのデフォルトの返答が返ってくるのでやめました笑


#参考記事
作成中に参考にした記事をひたすら貼っておきます
[IFTTT から Raspberry Pi に指示を出す](https://qiita.com/minatomirai21/items/4c4e777b43ede1e42900)
[Raspberry Pi 3 + Google Homeでエアコンを音声操作できた]
(https://craftzdog.hateblo.jp/entry/control-an-air-conditioner-with-voice-from-google-home-via-raspberry-pi)
[Raspberry Pi での Node-RED 利用]
(https://qiita.com/minatomirai21/items/184e04bab76bee70470e)
[IFTTTの使い方]
(https://ifttt-japan.club)
[IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する]
(https://qiita.com/msquare33/items/9f0312585bb4707c686b)
[Raspberry Piで音楽(wav/mp3)ファイルを再生する方法 python編](https://qiita.com/Nyanpy/items/cb4ea8dc4dc01fe56918#1pygame)
[帰宅したらGoogleHomeから好きな音声で「おかえり」って言ってもらいます](https://qiita.com/taaaaaaak22/items/abfb9f2a672689c20505)
[Bluetoothスピーカーから音を出す](http://belial6.hateblo.jp/entry/2017/06/30/003546)
[Raspberry piでbluetoothスピーカーを鳴らす](http://zokibayashi.hatenablog.com/entry/2017/10/10/020902)