LoginSignup
13
12

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-08-30

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

Qiitaで色々な方の記事を参考にしつつ作りました
初投稿なので誤りやお気付きの点がございましたらご指摘お願い致します

大まかな流れ

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

音声ファイル再生までの流れ

スクリーンショット 2018-08-27 9.09.46.png

使用したもの

・Google Home mini
・Raspberry Pi zero

音声認識をしてRaspberry Piにデータを送るまで

PC側の準備とRaspberry Pi側の準備で分けました

IFTTT・Webhook・BeeBotte・Node-Redの準備

こちらの記事を参考にしました↓ 分かりやすくまとめてあります
IFTTT から Raspberry Pi に指示を出す
以下に本記事においてアレンジを加えた箇所を載せて起きます

・IFTTTの「this」
"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

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

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

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

・IFTTTの「that」
"Say a simple phrase"変更に伴い"Body (optional)"を
{"data":[{"xxxxx"}] (←ここのxxxxx には好きなワードを入れてください)
にします
スクリーンショット 2018-08-29 23.35.19.png

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

Raspberry Pi側での準備

IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する
よりライブラリインストールをします
下にこの記事から引用した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()

ここで

TOKEN = "[Beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "MySmartHome/voice"
CACERT = "mqtt.beebotte.com.pem"

はテキトーに自分が設定したものに変更していくのですが


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編

パターン①

サーバにあげたmp3をgoogle-home-notifierを用いてGoogle Home miniで再生する

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

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で呼びます


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から音楽(音声)出力できるよーになるのですが、、、

しかーし

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

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

パターン②

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

Bluetoothスピーカーとして使うために設定として
Bluetoothスピーカーから音を出すRaspberry piでbluetoothスピーカーを鳴らすを見ていただければ簡単に設定できると思います

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

動作確認

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

音声認識されて音楽が再生されたときのもの↓
スクリーンショット 2018-08-30 16.24.15.png

最後に

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

参考記事

作成中に参考にした記事をひたすら貼っておきます
IFTTT から Raspberry Pi に指示を出す
Raspberry Pi 3 + Google Homeでエアコンを音声操作できた
Raspberry Pi での Node-RED 利用
IFTTTの使い方
IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する
Raspberry Piで音楽(wav/mp3)ファイルを再生する方法 python編
帰宅したらGoogleHomeから好きな音声で「おかえり」って言ってもらいます
Bluetoothスピーカーから音を出す
Raspberry piでbluetoothスピーカーを鳴らす

13
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12