ifttt
RaspberryPi
beebotte
GoogleHome

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

目的

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を指定したりと試してみましたが、ダメでした。