Google home miniと金魚の自動えさやり機を連携してみた

こんにちは、koheiです。
ずっと購入したかった「Google home mini」が、某量販店で半額セールだったのでついに購入しました。
アラームやタイマー、ショッピングリストなど便利に活用できてますが、せっかくなのでIotデバイスと連携したいと思い、以前自作した金魚の自動餌やり機(ラズパイ+Arduino)と連携してみました。
用意したもの
今回準備したものは、以下です。基本的に、Google home miniと以前作成した金魚の餌やり機です。
・Raspberry Pi 3B+
・金魚餌やり機(Arduino+サーボ等)
■金魚の餌やり機の構成、回路等は以前のブログ記事を参考にしてください。
はじめての電子工作 Arduinoで金魚の自動餌やり機を自作してみた
システム構成
全体の流れとしては、IFTTTを使って、Googleアシスタントでうけた情報をWebhooksからBeebotteブローカーへ通知し、ブローカーからラズパイへメッセージが通知される仕組みです。

今回以下のWebサービスを活用して実現します。
・IFTTT(イフト)・・・様々なWebサービスを連携することができる
・Beebotte・・・IoT向けのクラウドサービス(今回はMQTTブローカーを使う)
1.Beebotteでチャンネルを作る
ラズパイへの無線通信は、MQTTプロトコルを使うため、Webサービス「Beebotte」のMQTTブローカーを利用します。(※無料の利用枠があるようなので、無料版で使います)

Beebotteのサイトから「Get Started for Free」をクリックしてアカウントを作成します。
beebotte

アカウント作成後、「Create New」を押して、新規チャンネルを作成します。

チャンネルの詳細情報を設定します。
今回は以下のように設定しました。
| Channnel Name | MySmartHome |
| Channel Description | MySmartHome |
| Resource name | voice |
| Resource Description | voice |
設定後、「Create channel」押します。

追加したチャンネル「MySmartHome」をクリックします。

channel Tokenの値をメモしておきます。(後の設定で使います)

Account Settingsメニューから、Access Management画面を開きます。
Secret Keyをメモしておきます。(後の設定で使います)

以上で、Beebotteの設定は終わりです。
次は、IFTTTの設定を行います。
2.IFTTT設定
IFTTTとは、「IF This Then That」(もし、これをしたら、あれをする)の略で、Webサービス同士を連携することができるサービスです。

IFTTTのサイトからアカウントを作成して、My Appletsページから「New Applet」をクリックし、新規Appletを作成します。

まずは、「if this then that」の「this」から設定します。
+thisをクリックします。

googleを検索し、「Google Assistant」を選択します。

今回、Choose triggerでは、「Say a simple phrase」を選択します。

Waht do you want to say?には、Google homeに呼びかける文言を設定します。
What do you want the Assistant to say in response?には、Google home からの応答の言葉を設定します。設定したら、Create triggerをクリックします。
| Waht do you want to say? | 金魚の餌やり |
| What do you want the Assistant to say in response? | はい、金魚の餌やりですね。 |

次に、「if this then that」の「that」を設定します。
+thatをクリックします。

webhooksを検索して、選択します。

Make a web requestを選択します。

webhooksからのリクエスト内容を設定します。ここでは、前手順で設定したBeebotteへPOSTメソッドで情報を通知します。設定内容は以下です。
| URL | https://api.beebotte.com/v1/data/publish/[bebotteのChannel名]/voice?token=[Beebotteのトークン] |
| Method | POST |
| Content Type | application/json |
| Body | {“data”:[{“room”:”living”,”device”:”kingyo”,”action”:”on”}]} |

設定後、Finishを押してIFTTTの設定は完了です。

同様に金魚の餌やりをストップさせるAppletを追加します。(やり方は同じなので設定だけ記載します)
[Google Assistant設定]
| Waht do you want to say? | 金魚の餌やりストップ |
| What do you want the Assistant to say in response? | 金魚の餌やりをストップします。 |
[Webhooks設定]
| URL | https://api.beebotte.com/v1/data/publish/[bebotteのChannel名]/voice?token=[Beebotteのトークン] |
| Method | POST |
| Content Type | application/json |
| Body | {“data”:[{“room”:”living”,”device”:”kingyo”,”action”:”off”}]} |
3.ラズパイからMQTTトピックをsubscribeする
次に、ラズパイでMQTTトピックを受信できるように実装します。

※今回使ったラズパイ,Pythonのバージョンは、以下です。
・ラズパイ3B+
・OS:Raspbian GNU/Linux 9.4 (stretch)
・Python 2.7.13
まずは、ラズパイにpaho-mqttをインストールします。
メッセージ受信処理とArduinoへのシリアル通信を以下のように実装します。(Pythonで実装)
# -*- coding: utf-8 -*-
import serial
import threading
import paho.mqtt.client as mqtt
import json
TOKEN = "BeebotteのChannel Token"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "BeebotteのChannel /voice"
CACERT = "mqtt.beebotte.com.pem"
ser = serial.Serial('/dev/ttyACM0', 9600 , timeout=1)
def main():
while True:
val=ser.readline()
print(val)
flag = raw_input()
print("input="+flag)
ser.write(flag+'\0')
if(flag == 'q'): # qが入力されたら通信終了
break;
ser.close()
def mqtt_func():
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()
if __name__ == '__main__':
thread_1 = threading.Thread(target=main)
thread_2 = threading.Thread(target=mqtt_func)
thread_1.start()
thread_2.start()
def on_connect(client, userdata, flags, respons_code):
print('status {0}'.format(respons_code))
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
global ser
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)
if data['device'] == 'kingyo':
if data['action'] == 'on':
print("serial motor on")
ser.write('on'+'\0')
elif data['action'] == 'off':
print("serial motor off")
ser.write('off'+'\0')
・7行目のTOKENには、BeebotteのChannel Tokenを設定します。
・10行目のTOPIICには、BeebotteのChannnel/voiceと設定します。
・26行目のmqtt_funcでmqttクライアント設定処理、44行目のon_connectでサブスクライブしています。
・Beebotteからメッセージが届いたら、48行目のon_messageでArduinoへサーボモーターon/offを通知しています。
Arduino側のシリアル受信の処理は、前回のブログ記事から変えていません。
以下記事の1-1.Arduino側プログラムを参照してください。
Arduino+ラズパイ3で金魚の自動餌やり機をリモート操作できるようにした
早速、動かしてみます。
ラズパイとArduinoをUSBケーブルで接続します。
ラズパイ側で、作成したPythonコードを実行します。
Google home miniに「OK Google! 金魚の餌やり」と話しかけて、サーボモーターがちゃんと動きました!
止めるときは、「OK Google! 金魚の餌やりストップ」で止まりました!
動作の様子は、以下動作でも紹介しています。よろしければどうぞ。
最後に
今回、Google home miniと自作した金魚餌やり機を連携させてました。
やっぱりGoogle homeは、いろんなデバイスと連携させると面白いです。今後もいろんなデバイスと連携させてスマートホーム化を実現していきたいと思います。
それでは!!

