RaspberryPiサーバーとOKgoogleを連携する方法【IoT/Python】

  • 2021.02.20
  • IoT
RaspberryPiサーバーとOKgoogleを連携する方法【IoT/Python】
えびかずき
えびかずき

こんにちは、

マイブームは自宅のスマートホーム化、えびかずきです!

今回はラズパイをサーバーにしてOKgoogleと連携する方法について説明していきたいと思います。

こんな人におすすめ:
・Pythonを使ったIoT技術について学びたい
・ラズパイを買ったはいいが、引き出しの中で眠っている

結果として、以下のIoTシステムが完成しました。

開発環境

スマートスピーカー:
Google Nest mini
DialogFlow/Actions on google

サーバー:
RaspberryPi 3B
 OS:Raspbian
 Python:3.7.3
 ライブラリ:Flask-Assistant

温度センサ:
MESH温度センサ/sony
 Webhook:IFTTT

エアコン操作:
eRemote RJ-3

やりたいこと

OKgoogleで温度をたずねると現在の温度を報告してくれるシステムを作りたい。

このシステムの概要は以下の通りです。

①RaspberryPiにFlaskでサーバーを立てる
②MESH温度センサからRaspberryPiへデータを送信する
③Actions on googleで応答システムを作る

今回のソースコードはGithubリポジトリに公開しています。
真似してみたい方はご自由に使ってください。

それでは順を追って説明していきましょう。

連携手順

①RaspberryPiにFlaskでサーバーを立てる

1.まずラズパイにFlaskをインストールします。

今回はFlaskの拡張パッケージである、『Flask-Assistant』をpipでインストールします。

$ pip3 install flask-assistant

2.Flaskで温度データを返すサーバーを立てます。

以下のディレクトリ構成で「.py」ファイルを準備して、「smart_home.py」

を実行します。

smart_home
  smart_home0.py
  temp_get.py
  temp.json

$ python3 smart_home0.py

すると、ローカルサーバーが5000番ポートで立ち上がります。

「smart_home0.py」のソースコードは以下の通り。

# smart_home0.py

import json
import requests
from flask import Flask, render_template, request
from flask_assistant import Assistant, ask, tell
from temp_get import temp_result

app = Flask(__name__)
assist = Assistant(app, '/')

# MESHからのデータ受取り
@app.route("/temp", methods=['POST'])
def temp():
    result = request.data.decode()
    data = {"temp":float(result)}
    file = open("temp.json", "w")
    json.dump(data, file)
    return result

# 起動時の応答
@assist.action('Default Welcome Intent')
def greet_and_start():
    result = blight_result()
    text = "命令をどうぞ。"
    return ask(text)

# 温度の受答え
@assist.action('CheckTemp')
def CheckTemp():
    result = temp_result()
    text = str(result)
    return tell("現在、" + text + "どです。")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000)

「temp_get.py」のソースコードは以下の通り。

# temp_get.py

import json

def temp_result():
    file = open("temp.json", "r")
    json_dict = json.load(file)
    result = json_dict["temp"]
    return result

if __name__ == '__main__':
    temp_result()

「temp.json」は以下の通り。
最初はとりあえず0.0を入れておいて、後で自動で温度が書き換えられていきます。

{"temp": 0.0}

その他のコードはGithubでご確認ください。

3.ngrokでローカルサーバーを外部と通信できるようにする

まずhttps://ngrok.com/へ行き、サインアップでユーザー登録してください。

下のコマンドで、ngrokをダウンロードします。

$ mkdir ngrok
$ cd ngrok
$ wget -O ngrok-stable-linux-arm.zip 'https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip'
$ unzip ngrok-stable-linux-arm.zip

ここはhttps://ngrok.com/downloadから手動でダウンロードしてもOK。

「Learn ngrok」>「The basics」>「Connect your account」に表示されているAuthトークンを使って、Auth認証します。

./ngrok authtoken Authトークンを入力

続いて下記コマンドで、プロセス実行中のポートを公開。

$ ./ngrok http 5000

実行後、アウトプットに表示されるURLで外部からサーバーへアクセスできるようになりました。

これでひとまず、ラズパイのサーバー準備は完了です。

②MESH温度センサからRaspberryPiへデータを送信する

続いて、温度センサのIoT準備を進めていきます。

1.まず下準備として、https://ifttt.com/でIFTTTのユーザー登録をします。

2.MESHアプリで下のようにプロジェクトを作成します。

ある一定時間ごとに温度センサの情報をIFTTTへ送信するというプロジェクトです。

それぞれのブロックの設定は以下の通り。

3.IFTTTアップレットの作成

IFTTTの『WebHooks』というサービスを使って、以下のアップレットを作成してください。

MESHセンサからデータを受け取ったら、特定のURLへWebリクエストを送るというアップレットです。

設定は以下の通り。

URLの欄には、①のngrokのところで表示されたURLを入力してください。

これで、MESH温度センサの準備は終了です!

③Actions on googleで応答システムを作る

最後の仕上げとして、Actions on googleで応答システムを作っていきましょう。

1.Actions on googleへログインする

2.Actions ConsoleでNewProjectを作成する

赤枠にプロジェクト名を入力してください。

Customを選択。

Click hereをクリック。

3.Actionの設定

まず「Modify Languages in Settiongs」から、言語を日本語へ変更します。

Developタブを開いて、応答システムの名前を入力し、音声を選択します。

音声は自分の好きな声を選べばOKです。

4.Dialogflowで応答システムを作成する

Overviewタブから「Add Action(s)」を選択。

Custom intentを選択。

Default LanguageをJapanese、Default Time ZoneをAsia/Tokyoに設定。

CREATE INTENTをクリック。

このINTENTというのが、応答システムの部品になります。

「CheckTemp」という名前でINTENTを作成。

以下のようなTraining phraseを指定する。

FullfillmentのEnable Webhook call for this intentにチェックを入れる。

左上のナビゲーションバーから、Fulfillmentの設定画面へいき、

URL欄に公開中のサーバーURLを入力する。

これで応答システムが完成です。

5.仕上げの設定

Actions on googleへ戻って、Deployタブへ行きます。

赤枠内の必要事項を入力すれば、準備完了です。

これで全ての工程が終了しました。

OKgoogleに「スマートホームにつないで」と話しかけると、上記の応答システムが起動します。

続いて、「温度を教えて」とお願いしてみましょう。

期待通りの応答をしてくれたでしょうか?

発展編:エアコン操作を追加する

温度を教えてくれるだけでは正直つまらないので、

ここからはエアコンを付けてくれる機能を追加したいと思います。

追加機能概要:

①Actions on googleの応答システム「エアコンをつけますか?」を追加
②室内にeRemoteを設置
③RaspberryPiサーバーにeRemote操作のプログラムを追加

①Actions on googleの応答システム「エアコンをつけますか?」を追加

下のように「AirconOn」という名前のintentを新規に作成します。

Fulfillmentで、Webhookの設定にチェックを入れる。

②室内にeRemoteを設置

続いてリンクジャパンのeRemote RJ-3を使って、リモコンのIoT化をしていきます。

1.エアコンに赤外線が届きやすい場所に、eRemoteを設置します。
※ラズパイと同じWifiネットワーク内に設置する必要があります。

③RaspberryPiサーバーにeRemote操作のプログラムを追加

さて最後の仕上げとして、ラズパイサーバーにプログラムを追加していきましょう。

1.eRemoteをラズパイで操作するためのAPIを入手します。

$ git clone https://github.com/TheGU/rm3_mini_controller.git
$ cd rm3_mini_controller
$ pip3 install -r requirements.txt

2.下のコマンドで同じネットワーク上のeRemote本体を検索します。

$ python3 test_run.py

3.2で得られたIPアドレス、ポート番号、MACアドレスを設定ファイルに書き込む

[General]
IPAddress = XXX.XXX.X.X
Port = XX
MACAddress = XX.XX.XX.XX.XX
Timeout = 30

4.リモコンの赤外線情報をインプットする

下のコマンドを実行した後、

eRemote本体に向かって、エアコンのリモコンを近づけて電源ONボタンを押します。

$ python3 BlackBeanControl.py -c power_on

これで、赤外線情報の登録が完了です。

うまくいけば、「BlackBeanControl.ini」の設定ファイルに[Commands]という情報が追加されています。

もう一度同じコマンドを実行すると、エアコンの電源が入るようになっているはずなので確認してみましょう。

$ python3 BlackBeanControl.py -c power_on

5.Flaskのプログラムを編集する

最後にFlaskのプログラムを編集していきます。

ディレクトリ構成は以下の通り。

smart_home
  smart_home.py
  temp_get.py
  temp.json
        rm3_mini_controller
  eremote.py

#smart_home.py

import json
import requests
from flask import Flask, render_template, request
from flask_assistant import Assistant, ask, tell
from temp_get import temp_result
from eremote import temp_on

app = Flask(__name__)
assist = Assistant(app, '/')

# MESHからのデータ受取り
@app.route("/temp", methods=['POST'])
def temp():
    result = request.data.decode()
    data = {"temp":float(result)}
    file = open("temp.json", "w")
    json.dump(data, file)
    return result

# 起動時の応答
@assist.action('Default Welcome Intent')
def greet_and_start():
    result = blight_result()
    text = "命令をどうぞ。"
    return ask(text)

# 温度の受答え
@assist.action('CheckTemp')
def CheckTemp():
    result = temp_result()
    text = str(result)
    return ask("現在、" + text + "どです。エアコンをいれますか?")

# エアコンの起動 
@assist.action('AirconOn')
def On():
   temp_on()
   return tell("エアコンをいれました。")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000)
# eremote.py

import subprocess

path = "python3 rm3_mini_controller/BlackBeanControl.py -c "

def temp_on():
    subprocess.call(path + "power_on",shell=True)

if __name__ == '__main__':
    temp_on()

その他のコードはGithubでご確認ください。

これで無事システムが完成しました!

OKグーグルに話しかけてみて、期待通りの応答をしてくれるか確認してみましょう。

まとめ

今回はRaspberryPiサーバーとOKgoogleを連携する方法について説明しました。

サクッと書けるかなと思いましたが、割と長い記事になってしまいました。

やっていることは単純ですが、

IoTの基礎的な技術がぎゅっと詰まった記事になっているので、興味のある方はぜひ試してみてください。

さらに応用として、温度が高くなれば自動でエアコンが入るとかやってみても面白そうですね。

今回結構楽しかったので、IoT関連の記事も今後増やしていこうかなと思っています。

ではまた次回!

参考書籍

この書籍が参考になりました。

Python×ラズパイ×Google Homeの他、Amazon Echoを使ったIoTシステムの紹介もあります。

自宅のスマートホーム化に熱中できておすすめ。

IoTカテゴリの最新記事