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

## 目的
GoogleHome、超スゲー便利！！
声でいろいろとできると、こんなにも生活が変わるのか！！って感じ。お店では恥ずかしがってた子供たちも、今では友達のように話してる。TVのon/offや音楽、ビデオの再生、タイマー、天気と色々とやってくれるんだけど、電気を消してくれない。消してくれないというか、GoogleHomeに対応したライト（フィリップスの[Hue](http://www2.meethue.com/ja-jp)など）でないので、そもそも無理。
しかし、幸いウチのシーリングライトはリモコン式！！　だったらGoogleHomeと連携しないと！！ということで、GoogleHomeから家の電気をon/offする方法を調べてみた。

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

* Nature Remo<br>http://nature.global/
* ラトックシステム スマート家電コントローラ<br>http://www.ratocsystems.com/products/subpage/wfirex3.html

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

## IFTTT + Beebotte
まずはラズパイとどう連動させようかと色々と調べてみると、IoT PlatformのBeeBotteがよさそう。
GoogleHome -(音声)→ IFTTT -(REST)→ Beebotte ←(監視)- RaspberryPi こんな感じ。

### Beebotteセットアップ
まずは音声データの受け口となるChannelをBeeBotteに作成する。
#### Channel作成
Homeから、[Create New]ボタンでChannelを作成する。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/ceda6383-f4c2-fc48-7bb1-560c55d57f20.png">

#### Channel名、リソース名登録
Channel名：MySmartHome
Resource名：voice
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/16754dfa-25ec-781c-2fe7-3fbd00a4cb52.png">

#### トークン取得
Channelを作成すると、Homeに作成したChannel名がリストアップされるので、Channel名をクリック
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/0f82b70c-3953-0d5e-caa8-015e544c3943.png">

そうすると、そのChannelのアクセストークンを取得することができる。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/b9265d4d-aeb1-0d35-ea68-4eda89cd3280.png">

#### 動作確認
Account Settingsメニューを選択し、Credentialsタブを選択すると、Secret Keyが表示される。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/9e977389-0534-2851-e353-9d184ef2d8bc.png">

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

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

<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/ed31ac36-8002-df96-1db8-14009832bb19.png">

### IFTTTセットアップ
次に、GoogleHomeからの音声を受けてBeeBotteにRESTするためのIFTTTを作成する。

#### Applet作成
IFTTTのMyAppletsページからNew Appletボタンを押下する。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/09a3237f-d9d9-cf75-a0ab-1af49704fb2d.png">

#### IF作成
thisをクリック
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/34a57490-6c89-85c4-4303-c7c0475ddde3.png">

googleで検索し、Google Assistantを選択
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/7d31394a-bd36-2696-0c5d-00a53d43cfd9.png">

Say a phrase with a text ingredientを選択
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/9370162b-31c6-97ac-6c14-97c4cc2cd188.png">

<br>動作を以下のように設定

| 項目| 値 |
|:-----------------|:------------------|
| What do you want to say? | リビングの $ をつけて |
| What do you want the Assistant to say in response? | リビングの $ をつけます |
| Language | Japanese |

<img height="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/b20d2e5f-388b-f2a1-50a3-e9bc3545966d.png">

#### Action作成
thatをクリック
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/812d1859-ac7e-db32-e4fd-af036d750781.png">

webで検索し、Webhooksを選択
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/e2a7a085-89cd-7756-6809-a172bd4ba055.png">

Make a web requestを選択
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/bd3fbd70-cf68-8963-bfdf-de357bb47cfb.png">

<br>動作を以下のように設定し 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"}]} |

<img height="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/03847fd2-833f-67c6-6d0b-a393bb86cb37.png">

Finishボタンを押下する
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/72a1268b-13a0-990d-4be1-7ab7b0ef150c.png">

IFTTT完成！！
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/f0a1b8b8-9029-06a0-182a-d9509fab5e13.png">

### 動作確認
BeeBotteとIFTTTの設定が完了したので、実際にGoogleHomeに「リビングの電気をつけて」と言ってみた。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/001b4d71-a24b-3459-9be1-764b9b2bed8e.png">
おぉ。ちゃんとデータが送られてきた！！すごい！！

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

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

```bash
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()
```
コードを保存したら、

```bash
python3 smarthome.py
```
で実行する。
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/ec4c8b63-ff51-472d-66ad-9fedaa497758.png">

「Ok Google リビングの電気をつけて」と言うと、
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/4f87e4a5-4eba-4e38-c5cd-ad79d32a0337.png">

「Ok Google リビングのエアコンをつけて」と言うと、
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/c60dd0a5-4db8-7bf6-e477-9e276325d5a7.png">

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

### 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をつけることができましたｗ
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/82651/04ca00a3-f0a3-84bb-c394-f8950240726b.jpeg">
Raspberry Piもピンヘッダつけてないし、お恥ずかしい...。
最後のPython以外、ほぼほぼ参考にしたページのパクリになってるし。当初の目的だった「電気を消す」がなぜか「電気を点ける」になってるしｗ
これからいろいろと改造していこうかと思います。

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

## 参考
* Google AssistantとRaspberry Piで自宅の家電を操作する<br>https://qiita.com/104ki/items/9dcfe03246099d03d4dd

### 修正履歴
* 2018/1/11<br>
Guwashiさんより、設定内容がセキュアでないとの指摘を受けて、内容を修正。※画像までは変えていません。<br>
https://qiita.com/Guwashi/items/e1ea9c61af4715198edc<br>
また、"mqtt.beebotte.com:8883"でなく、"api.beebotte.com:443"でpythonのデフォルトのCA Certsを指定したりと試してみましたが、ダメでした。