RaspberryPi
IoT
Lチカ
GoogleHome

レッツラズパイ!〜Google HomeでLピカさせよう編〜

レッツラズパイ!・プロジェクト

  1. レッツラズパイ!〜Raspberry3にOSをインストールしよう〜
  2. レッツラズパイ!〜Lチカ&Lピカをマスターしよう編〜
  3. レッツラズパイ!〜Webカメラで監視しちゃうゾ編〜
  4. レッツラズパイ!〜温度センサーとmailgunで検知メールを送ろう編〜
  5. レッツラズパイ!〜Google HomeでLピカさせよう編〜(これ)
  6. レッツラズパイ!〜Google Homeに室温を教えてもらおう編〜
  7. レッツラズパイ!〜Lチカボタン編〜

RaspberryPiを始めて触る&IT初心者向けのドキュメントです。私の所属する会社で使う、IT初心者の方のインターンシップ向けのドキュメントとして書きはじめたので、かなり丁寧に書いていますがご了承下さい。

参考記事

この4つの記事を参考にさせていただきました。

Google HomeでLピカさせよう

用意するもの

簡単な構成図

  • Google HomeとRaspberry Pi、作業用のクライアント端末は同一ネットワーク上のWi-Fiに接続させます。
  • 今回はRaspberry PiとGoogle Homeを連携させるためにIFTTT,Beebotteを使用します。
  • Google Assistantが使用する人の発言を拾い、IFTTTをトリガー(this)させます。
  • IFTTTのwebhook(外部のウェブサーバに対してウェブリクエストを送信する機能)を利用してBeebotteに情報をPOSTして、その情報をRaspberry Piが取得しLEDランプを点灯させます。

図にすると以下の通りです。

【修正済み】Google Home×Lピカ構成図.jpg

Google Homeの準備

スマートフォンにてアプリをインストールからの設定

まずは、使用するGoogle Homeのデバイス設定を行うため、スマートフォンからGoogle Homeのアプリケーションをインストールします。

こちらは、公式手順を参照して下さい。

Beebotteセットアップ

Beebotteは、IoT向けのクラウドサービス。REST API や MQTTをサポートして、接続された機器にリアルタイムでメッセージを通知することができます。

今回の通信のイメージとしては、以下のようになります。

Google Home → IFTTT → Beebotte(ここ) ⇔ Raspberry Pi → LEDランプ

ではさっそく、Bebotteの設定を始めていきましょう!

Channel作成

  1. 「Home」より[Create New]をクリックして新規Channelを作成する。

Beebotte_1.png

2. 各項目を下記の通りに設定し、[Create Channel]をクリックします。下記以外の項目はデフォルト値のままでOKです。

設定項目 設定値
Channel Name MySmartHome
Channel Description MySmartHome
Resource Name voice
Resource Description voice

Beebotte_2.png

アクセストークンの取得

  1. 前手順で作成した「MySmartHome」をクリックします。

Beebotte_3.png

2. 赤丸で囲まれた部分に赤文字でトークンが表示されているので、それをメモしておきます。
Beebotte_4.png

Beebotteの動作確認

  1. Account SettingsメニューのAccess Managementタブをクリックして、「Seacret Key」をメモしておきます。 Beebotte_5.png
  2. Consoleメニューをクリックして、各項目を下記の通りに設定し、[Subscribe]をクリックします。下記以外の項目はデフォルト値のままでOKです。
設定項目 設定値
Seacret Key 手順1.でメモした内容を記載

以下、設定値は「Subscribe」についての設定になります。

設定項目 設定値
Channel Description MySmartHome
Resource Name voice

Beebotte_6.png

3. 「Messages」に青い文字が表示されていることが確認できたら、Macを使用している場合はターミナルから、Windowsを使用している場合は、Raspberry Piから下記コマンドを実行します。

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

「Messages」に先程作成したチャンネル名やリソース名、"Hello World"等を含む文字列が表示されればBeebotteの動作確認は完了です!

IFTTTセットアップ

IFTTTは簡単に言うとWebサービス同士を自動的に連携できるサービスです。

今回は、Google AssistantとIFTTTのwebhookを連携させ、Beebotteに情報をPOSTします。
今回の通信のイメージとしては、以下のようになります。

Google Home → IFTTT(ここ) → Beebotte ⇔ Raspberry Pi → LEDランプ

ではさっそく、IFTTTの設定を始めていきましょう!

『this』トリガーの作成

GoogleHomeからの音声を受けてBeebotteにPOSTするためのIFTTTを作成します。
1. IFTTTにサインアップ&サインインします。

002_IFTTT.png

2. サインインが成功したら、画面上にある[My Applets]をクリックします。

003_IFTTT.png  
3. 「My Appletsページ」が表示されたら、[New Applet]をクリックします。

004_IFTTT.png  
4. これからAppletを作成していきます。

IFTTTの基本的な考え方は「If this then that」です。「もし〜ならば〜する」といった具合ですね。

【考え方】
・this → どのプラットフォームの何をトリガーにするか
・that → どのプラットフォームの何を実行するか(アクション)

それでは、「もし〜ならば」から作成していきますので、[this]をクリックします。
今回でいうと「もし"Google Assistantからあるフレーズを認識した"ならば」となりますね。

005_IFTTT.png

5. 検索フォームより[Google Assistant]を検索し、クリックします。

006_IFTTT.png

6. 今回は、キーワード付きのフレーズを認識できる機能を使いますので、[Say a phrase with a text ingredient]をクリックします。

007_IFTTT.png

7. 動作を設定します。設定項目は以下の通りです。

項目
What do you want to say? 部屋の $ をつけて
What do you want the Assistant to say in response? ちょっとまっててー
Language Japanese

008_IFTTT.png

他に入力する箇所もありますが、空欄でOKです。
入力が完了したら[Create trigger]をクリックします。

これで「もし〜ならば」の[this]の作成は完了です!

『that』アクションの作成

  1. 続いて、「ならば〜する」を作成していきますので、[that]をクリックします。

009_IFTTT.png

2. 検索フォームより[webhooks]を検索し、クリックします。

010_IFTTT.png

webhooksは、FTTT上でWEBリクエストによる『トリガー』や『アクション』が利用できるものです。

3. [Make a web request]をクリックします。

011_IFTTT.png

4. webhooks(アクション)の設定をします。設定項目は以下の通りです。

項目
URL https://api.beebotte.com/v1/data/publish/[bebotteのChannel名]/voice?token=[Beebotteのトークン]
Method POST
Content Type application/json
Body {"data":[{"room":"office","device":"{{TextField}}","action":"on"}]}

※URLの内容はBebotteで作成したChannelとトークンにしましょう!

【修正済み】012_IFTTT.png

入力が完了したら[Create action]をクリックします。

5. 確認が入るので、問題なければ[Finish]をクリックします。

013_IFTTT.png

6. この画面が表示されたら、IFTTTの完成です!!!

014_IFTTT.png

「部屋の◯◯を消して」も作ろう

やっぱり、電気はつけたら消したいですよね。
なのでさっそく「消して」ver.も作成しましょう!

手順は簡単です。

『this』と『that』の設定を少し変えるだけ!
作り方は同じです。

今回は、設定値だけ載せておきますので、手順は「つけて」の手順を参考にしましょう。

  • 『Google Assistant』の設定値
項目
What do you want to say? 部屋の $ を消して
What do you want the Assistant to say in response? ちょっとまっててー
Language Japanese
  • 『webhooks』の設定値
項目
URL https://api.beebotte.com/v1/data/publish/[bebotteのChannel名]/voice?token=[Beebotteのトークン]
Method POST
Content Type application/json
Body {"data":[{"room":"office","device":"{{TextField}}","action":"off"}]}

動作確認

BeebotteとIFTTTの設定が完了したので、実際にGoogleHomeに「部屋のライトをつけて」と言ってみましょう!

そうすると・・・・!?

015_IFTTT.png

成功すれば、メッセージに表示されます!
これで、BeebotteとIFTTTが連携されていることが確認できましたね。

Raspberry Piセットアップ

Python3を使ってRaspberry PiからBeebotteのトリガーを検知させます。
前提として、ラズパイにSSH接続をしましょう!

Beebotte連携テスト

これからRaspberry PiにPythonのコードを作成していきます。

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

  1. Beebotteを監視するためのライブラリをインストールします
$ sudo pip3 install paho-mqtt

Beebotte連携テスト

  1. 事前にサーバにアクセスするための証明書をダウンロードします。
$ wget https://beebotte.com/certs/mqtt.beebotte.com.pem -P ~/work

ダウンロード先は、LチカLピカ編で作成したディレクトリです。これから作成するPythonファイルの同じディレクトリで作成します。ディレクトリがない場合は、新規で作成してください。
  

  1. 先ほどダウンロードした証明書のディレクトリに移動します。
$ cd ~/work

  
3. 連携テスト用のプログラムを作成します。

$ vim smarthome.py

  
4. 下記プログラムをコピペして作成して下さい。

smarthome.py
import paho.mqtt.client as mqtt
import json

TOKEN = "[Beebotteのトークン]" # 変更箇所
HOSTNAME = "mqtt.beebotte.com"
PORT = 8883
TOPIC = "[BeebotteのChannel名]/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()

  
一部、BeebotteのトークンとChannel名に変更する箇所があるので注意してください。
編集後は、[ESC]キーを押下して[:wq]で保存しましょう。
  
5. それではさっそくプログラムを実行してみましょう。

$ python3 smarthome.py

↓ 実行後・・・

status 0

上記のように表示されたことを確認します。

6. 「OK Google!部屋のライトをつけて!」と言ってみましょう。

MySmartHome/voice b'{"data":[{"room":"office","device":"\xe9\x9b\xbb\xe6\xb0\x97","action":"on"}],"ispublic":true,"ts":1529208677835}'
{'device': 'ライト', 'room': 'office', 'action': 'on'}

連携が成功していると、上記のように認識します!
以上で、Beebotteとの連携テストは終了です。

Raspberry Pi配線作業

基本的にはレッツラズパイ!〜Lチカ&Lピカをマスターしよう編〜の配線を参考にしてください。

ただし今回は、16番ピンから制御するため、LEDのプラス側のジャンパーワイヤーを16番ピンに差し替えてください。

配線図は以下の通りです。

016_配線図.jpeg

Google Homeから操作してLEDピカさせる

  1. ラズパイのGPIOを利用できるようにするためプログラムを編集します。また、さきほど作ったプログラムは「部屋の〇〇をつけて!」の「◯◯」は何が来ても反応してしまいます。よって、プログラムに「電気」と「ライト」だけ反応するように編集します。。
smarthome.py
import paho.mqtt.client as mqtt
import json
import time
import RPi.GPIO as GPIO

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

# 名詞の変換表
noun_conv = {
            "電気": "light",
            "ライト": "light",
            }

# 接続中の処理を記載→subscribeする
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]
    # Google Assistantの側でTextFiledの前後に半角スペースが入ることがあるのでstripして削除
    data = {key:value.strip() for key, value in data.items()}
    # 「〜を」と言ってしまった際に「を」が入ってTextFieldに入ってくることがあるので削除
    if data["device"].endswith("を"):
        data["device"] = data["device"][:-1]
    print(data)

    # 日本語の表記ゆれに併せて、IFTTTのTextFieldをlightに修正
    if not data["device"] in set(noun_conv.values()):
        try:
            data["device"] = noun_conv[data["device"]]
            print(data)
        except:
            print(data)
            print("unkown device")
            return

    # 部屋の電気(ライト)をつけて
    if data['action'] == 'on':
        GPIO.output(OUTPUT_PIN, True)

    # 部屋の電気(ライト)を消して
    if data['action'] == 'off':
        GPIO.output(OUTPUT_PIN, False)

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

一部、BeebotteのトークンとChannel名に変更する箇所があるので注意してください。
編集後は、[ESC]キーを押下して[:wq]で保存しましょう。

2. それではもう一度プログラムを実行して「OK Google!部屋のライトをつけて!」と言ってみましょう!

$ python3 smarthome.py

↓ 実行後・・・

MySmartHome/voice b'{"data":[{"room":"office","device":"\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\x88","action":"on"}],"ispublic":true,"ts":1529991711851}'
{'room': 'office', 'device': 'ライト', 'action': 'on'}
{'room': 'office', 'device': 'light', 'action': 'on'}

正常に動作をしたら、続けて「OK Google!部屋のライトを消して!」と言ってみましょう!

$ python3 smarthome.py

↓ 実行後・・・

MySmartHome/voice b'{"data":[{"room":"office","device":"\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\x88","action":"off"}],"ispublic":true,"ts":1529991798747}'
{'room': 'office', 'device': 'ライト', 'action': 'off'}
{'room': 'office', 'device': 'light', 'action': 'off'}

どうですか?LEDライトは消えましたか?

Google HomeでLピカさせよう編は以上です。お疲れ様でした♪