Edited at

IFTTTとBeebotteを使ってGoogleHomeからRaspberryPiを操作する

More than 1 year has passed since last update.


目的

GoogleHome、超スゲー便利!!

声でいろいろとできると、こんなにも生活が変わるのか!!って感じ。お店では恥ずかしがってた子供たちも、今では友達のように話してる。TVのon/offや音楽、ビデオの再生、タイマー、天気と色々とやってくれるんだけど、電気を消してくれない。消してくれないというか、GoogleHomeに対応したライト(フィリップスのHueなど)でないので、そもそも無理。

しかし、幸いウチのシーリングライトはリモコン式!! だったらGoogleHomeと連携しないと!!ということで、GoogleHomeから家の電気をon/offする方法を調べてみた。


手段

対応手段としては、もちろん金に糸目をつけない方法をとりたいところ。ボーナスも入ったし。

例えばこんなのを使うとか。

特にラトックシステムのコントローラは結構魅力的。でも、製品ページを見ていくと、Google Assistantはまだ対応してないって書いてある。んー、先日ラズパイも買ったことだし、ラズパイを経由して消してみたいなーということで、ラズパイを使って電気を消すことにチャレンジ!!


IFTTT + Beebotte

まずはラズパイとどう連動させようかと色々と調べてみると、IoT PlatformのBeeBotteがよさそう。

GoogleHome -(音声)→ IFTTT -(REST)→ Beebotte ←(監視)- RaspberryPi こんな感じ。


Beebotteセットアップ

まずは音声データの受け口となるChannelをBeeBotteに作成する。


Channel作成

Homeから、[Create New]ボタンでChannelを作成する。


Channel名、リソース名登録

Channel名:MySmartHome

Resource名:voice


トークン取得

Channelを作成すると、Homeに作成したChannel名がリストアップされるので、Channel名をクリック

そうすると、そのChannelのアクセストークンを取得することができる。


動作確認

Account Settingsメニューを選択し、Credentialsタブを選択すると、Secret Keyが表示される。

表示されたSecret Keyを、ConsoleメニューのSecret Key入力エリアに入力し、SubscribeのChannelとResourceに、先ほど登録した"MySmartHome"と"voice"を入力し、Subscribeボタンを押下すると、画面右上部のMessagesエリアに青い文字が表示される。この状態で準備完了。下記のcurlコマンドを実行すると、Messagesエリアにcurlで指定したペイロードが表示されることを確認する。

curl -i -H "Content-Type: application/json" -X POST -d '{"data":"Hello World"}' http://api.beebotte.com/v1/data/publish/MySmartHome/voice?token=[Channelのトークン]


IFTTTセットアップ

次に、GoogleHomeからの音声を受けてBeeBotteにRESTするためのIFTTTを作成する。


Applet作成

IFTTTのMyAppletsページからNew Appletボタンを押下する。


IF作成

thisをクリック

googleで検索し、Google Assistantを選択

Say a phrase with a text ingredientを選択


動作を以下のように設定

項目

What do you want to say?
リビングの $ をつけて

What do you want the Assistant to say in response?
リビングの $ をつけます

Language
Japanese


Action作成

thatをクリック

webで検索し、Webhooksを選択

Make a web requestを選択


動作を以下のように設定し Create action ボタンを押下する

項目

URL
https://api.beebotte.com/v1/data/publish/MySmartHome/voice?token=[Beebotteのトークン]

Method
POST

Content Type
application/json

Body
{"data":[{"room":"living","device":"{{TextField}}","action":"on"}]}

Finishボタンを押下する

IFTTT完成!!


動作確認

BeeBotteとIFTTTの設定が完了したので、実際にGoogleHomeに「リビングの電気をつけて」と言ってみた。



おぉ。ちゃんとデータが送られてきた!!すごい!!


Raspberry Pi セットアップ

Python3を使ってRaspberry PiからBeeBotteのトリガーを検知させる。


MQTTライブラリインストール

BeeBotteを監視するためのライブラリをインストール

sudo pip3 install paho-mqtt


Beebotte連携テスト

以下のコードでBeeBotteと連携できるか確認してみる

※事前にサーバにアクセスするための証明書をダウンロードしておく。

https://beebotte.com/certs/mqtt.beebotte.com.pem


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()


コードを保存したら、

python3 smarthome.py

で実行する。

「Ok Google リビングの電気をつけて」と言うと、

「Ok Google リビングのエアコンをつけて」と言うと、

おぉ!!ちゃんと連携できてる!!


Raspberry Pi からリモコン操作

したかったんだけど...ここで力尽きた...&ウチにIR Receiverはあるんだけど、Transmitterが無かった...。とりあえず、LEDライトを電気に見立てて、「Ok Google ***をつけて」と言うと、LEDを点けるようにしてみた。

sudo apt-get install python-rpi.gpio

でRaspberry Pi のGPIOを利用できるようにしておく。

先ほどのsmarthome.pyを以下のように修正。

※何が来ても反応します。


smarthome.py

import paho.mqtt.client as mqtt

import json
import RPi.GPIO as GPIO

TOKEN = "[Beebotteのトークン]"
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "MySmartHome/voice"
OUTPUT_PIN = 16
CACERT = "mqtt.beebotte.com.pem"
GPIO.setmode(GPIO.BOARD)
GPIO.setup(OUTPUT_PIN, GPIO.OUT)

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():
GPIO.output(OUTPUT_PIN, True)
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()


とりあえずGoogleHomeでLEDをつけることができましたw



Raspberry Piもピンヘッダつけてないし、お恥ずかしい...。

最後のPython以外、ほぼほぼ参考にしたページのパクリになってるし。当初の目的だった「電気を消す」がなぜか「電気を点ける」になってるしw

これからいろいろと改造していこうかと思います。

また、せっかくのFUJITSUAdventCalendarなので、できればBeebotteではなく、K5のIoT Platformを使ってやってみたかったところ。もうちょっとK5も簡単に使えるようになるといいのに。


参考


修正履歴


  • 2018/1/11

    Guwashiさんより、設定内容がセキュアでないとの指摘を受けて、内容を修正。※画像までは変えていません。

    https://qiita.com/Guwashi/items/e1ea9c61af4715198edc

    また、"mqtt.beebotte.com:8883"でなく、"api.beebotte.com:443"でpythonのデフォルトのCA Certsを指定したりと試してみましたが、ダメでした。