Alexa, Google HomeをRasberryPiと連携する

じょるブログ

電子工作やプログラミング関連の情報を発信している技術系ブログ

電子工作 ラズベリーパイ

Alexa, Google HomeをRasberryPiと連携する

投稿日:2018年11月22日 更新日:

この記事ではスマートリモコンを作ってみで作成した、スマートリモコンをAlexaやGoogle Assistantと連携するために利用した外部サービスについて記載します。

   

   

今回利用したサービスは以下の2つです。 

  1. beebotte
  2. IFTTT

 

beebotteとは
無料で一日50000件のメッセージを利用することができる、IoTやリアルタイム接続アプリケーションに特化したクラウドプラットフォームです。今回はこのサービスを利用してIFTTTからwebhookによってbeebotteにデータを送り(publish)、送ったデータをRaspberryPiで読み取り(subscribe)、その読み取ったデータに応じた処理(エアコンをつけるなど)を行います。


IFTTTとは
外部サービス同士を連携させることができるサービスで、これを使うことでAlexa や Google Assistant と beebotte を連携させることができます。対応している外部サービスが豊富でLineとも連携することができます、こちらも無料のサービスです。

  

beebotte

まず、ユーザーネーム、メールアドレス、パスワードを入力してbeebotteにアカウントを作成します。

ログインしたら、”create new” をクリックします。

すると以下のような画面が表示されるので、Channel名とResource名、それからそれらの説明の合計4つを入力したら、”create channel” をクリックします。
(Channel名、Resource名は何でも構いません。ここでは仮にChannel名をRaspberryPi, Resource名をSmartRemoconとしています。)
※Resource名にはユニークな名前を付ける必要があり、ありきたりな名前だとエラーが出て登録できません。

以上でChannelの作成は完了です。作成したChannelにアクセスするためにはChannel Tokenが必要なので、以下のように作成したChannel名をクリックして、Channel Tokenをメモしておきます。

 以上でbeebotteの設定は完了です。

 

IFTTT

続いてIFTTTの設定を行います。メールアドレスとパスワードを入力するか、GoogleやFacebookアカウントを使用してアカウントを作成します。

アカウントを作成しログインしたら、右上の自分のアカウント名をクリックし、”New Applet”をクリックします。


以下のような画面が表示されるので、”+This” というところをクリックします。


“search service” のところに “Google” と入力してGoogle Assistant を探し、Google Assistantのアイコンをクリックします。
(Alexaの設定を行う場合はAlexaを選択します。)

Google Assistant を連携させるのが初めての場合は、連携について確認画面が表示されるので、”Connect”をクリックします。

以下の画面が表示されたら “Say a simple phrase” をクリックします。

以下のように、Google Assistant に話しかける(または入力する)フレーズとそのレスポンスを入力し、言語をJapaneseに設定したら “create trigger” をクリックします。

次に、Google Assistant と beebotteを連携させるための仲介役となるwebhooksとの連携をしていきます。
以下のような画面が表示されるので、”+That” をクリックします。

“search service” のところに “Webhooks” と入力してWebhooksを探し、Webhooksのアイコンをクリックします。

Webhooks を連携させるのが初めての場合は、連携について確認画面が表示されるので、”Connect”をクリックします。

以下の画面が表示されたら”Make a web request” をクリックします。

以下の画像のように、

・URL
” https://api.beebotte.com/v1/data/publish/チャンネル名/トピック名?token=[先ほどメモしたBeebotteのトークン] “と入力
・Method
” POST “を選択
・Content Type
” application/json “を選択
・Body
” {“data”:[{“device”:”デバイス名”,”action”:”アクション名”}]} “と入力

と入力したら、”Create action” をクリックします。

※スマホでダブルクォーテーションを入力するとうまくいかないという報告をいただきました。なので、上記の操作はパソコンで行ってください。

URL中のチャンネル名/トピック名にはbeebotteで設定したチャンネル名とトピック名を入力してください。
Bodyのデバイス名とアクション名は、赤外線学習をした際に設定したものを入力してください。
例: $ python3 irrp.py -r -g18 -f codes air_con:on --post 130
   というコマンドで学習したものを使用する場合は、
   デバイス名は” air_con “,アクション名は” on “と入力してください。

  

“Create action” をクリックすると、このような画面に切り替わるので、”Finish” をクリックすればIFTTTでの設定は完了です。

  

最後に・・

プログラム編で紹介したhomeauto.pyというプログラムの、TOKENというところに先ほどメモしたBeebotteのトークンを、TOPICというところにチャンネル名とトピック名を入力してください。 (以下のプログラムでは仮にChannel名をRaspberryPi, Resource名をSmartRemoconと設定したと想定しています。これを自分で設定した名前に変更してください。)

#!/usr/bin/python3
# -*- coding: utf-8 -*-

#smartremocon.py

import paho.mqtt.client as mqtt
import subprocess
import json
from time import sleep

HOST = 'mqtt.beebotte.com'
PORT = 8883
CA_CERTS = 'mqtt.beebotte.com.pem'
TOKEN = 'token_xxxxxxxxxxxxxxxxxx'    #Beebotteで作成したチャンネルのトークンを入力
TOPIC = 'RaspberryPi/SmartRemocon'    #Beebotteで作成したトピック名を入力

def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))

def on_disconnect(client, userdata, flags, respons_code):
    print("Unexpected disconnection.")
    client.loop_stop()


def on_message(client, userdata, msg):
    print(msg.topic + ' ' + str(msg.payload))
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    print(msg.payload.decode("utf-8"))
    print(data)

    def default_command(data):
        subprocess.call(["python3", "irrp.py", "-p", "-g17", "-f", "codes", data["device"]+":"+data["action"]])
        print("excuted command: " + data["device"]+":"+data["action"])

    # control
    # control
    # control air_con
    list_summer=[5,6,7,8,9,10]
    list_winter=[11,12,1,2,3,4]

    if (data["device"] == 'air_con'):
        if   (data["action"] == 'on'):
            date = datetime.datetime.now()
            if date.month in list_summer:
                print(date.month,"月 ","冷房をつけます")
                subprocess.call(["python3", "irrp.py", "-p", "-g17", "-f", "codes", data["device"]+":"+"on"])

            elif date.month in list_winter:
                print(date.month,"月 ","暖房をつけます")
                subprocess.call(["python3", "irrp.py", "-p", "-g17", "-f", "codes", data["device"]+":"+"on-winter"])

        else:
            default_command(data)

    # control TV
    elif (data["device"] == 'TV'):
        if   (data["action"] == 'input_switch1'):
            input_switch(data)
            sleep(0.1)
            input_switch(data)
        elif (data["action"] == 'input_switch2'):
            input_switch(data)
            sleep(0.1)
            input_switch(data)
            input_switch(data)
        elif (data["action"] == 'input_switch3'):
            input_switch(data)
            sleep(0.1)
            input_switch(data)
            input_switch(data)
            input_switch(data)
        else:
            default_command(data)

    # control ps4
    elif (data["device"] == 'ps4'):
        if (data["action"] == 'on'):
            subprocess.call(["sudo", "ps4-waker"])
        if (data["action"] == 'standby'):
            subprocess.call(["sudo", "ps4-waker", "standby"])
        if (data["action"] == 'enter'):
            subprocess.call(["sudo", "ps4-waker", "remote", "enter"])
        if (data["action"] == 'back'):
            subprocess.call(["sudo", "ps4-waker", "remote", "back"])
        if (data["action"] == 'torne'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA00442"])
        if (data["action"] == 'primevideo'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA03099"])
        if (data["action"] == 'youtube'):
            subprocess.call(["sudo", "ps4-waker", "start", "CUSA01065"])

    # control temperature
    elif (data["device"] == 'temp'):
        subprocess.call(["cd", "DHT11_Python"])
        subprocess.call(["python3", "dht11_example.py"])
        subprocess.call(["cd", "DHT11_Python"])

    # control other
    else:
        default_command(data)

if __name__ == '__main__':
    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_disconnect = on_disconnect
    client.on_message = on_message
    client.username_pw_set('token:%s' % TOKEN)
    client.tls_set(CA_CERTS)
    client.connect(HOST, PORT)
    client.subscribe(TOPIC)
    client.loop_forever()

TOKENとTOPICを入力したらsmartremocon.pyという名前でRasberryPiのcodeディレクトリの中にこのプログラムを保存し、以下のコマンドでsmartremocon.pyを実行してみてください。

pi@raspberrypi:~ $ cd code
pi@raspberrypi:~/code $ sudo chmod 755 smartremocon.py
pi@raspberrypi:~/code $ python3 smartremocon.py

実行して数秒待つと、mqttによる接続が開始され ” status 0 ” と表示されるので、お手持ちのスマホやGoogle HomeからGoogle Assistantを呼び出し、先ほどIFTTTで設定した言葉(エアコンつけてなど)を話してみてください(入力でも可)。先ほどIFTTTで設定した言葉(エアコンをつけますなど)が返ってきて、ターミナルにBeebotteに送られた(publishされた)データ等が表示されたら外部サービスとの連携は成功です。さらに数秒待つと赤外線送信が実行されます。
Alexaから操作する場合は1つ注意する点があり、” アレクサ、エアコンつけて “と話しかけても動作しません。Alexaから IFTTTを使用するには” アレクサ、トリガー、エアコンつけて “といったり、” アレクサ、エアコンつけてをトリガー ” といったように話しかけなければいけません。成功すると ” IFTTTに送信します ” という言葉が返ってきます。

これでスマートリモコンは完成です。
次の記事では、 google home や Alexa をもっていなくてもRaspberryPiひとつでスマートリモコンを操作できるように、RaspbberyPiにGoogle Assistantをいれていきます。

google ads




google ads




-電子工作, ラズベリーパイ

執筆者:


  1. トクメイ より:

    質問失礼いたします。
    この通りに進めてきたのですがIFFFTで
    ・Body
    ” {“data”:[{“device”:”デバイス名”,”action”:”アクション名”}]} “と入力
    この通りに書くとうまく送信されません。
    []を””に変更するとうまく送信できますがプログラム側でエラーが起きてしまいます。
    うまく動作しないためお返事いただけると幸いです。

    • joruji より:

      コメントありがとうございます。
      上手く送信されないというのは、どういった状態なのでしょうか?
      また、[]を””に変更した場合はどういったエラーになるのでしょうか?
      原因は分からないのですが、もしかしたら全角と半角が混ぜっていたりスペースが入っていたりしているのかもしれません。
      ですので、一度コピペせず全て手入力で入力してみてください。
      的確なアドバイスができず申し訳ございません。

      • トクメイ より:

        “”の場合はプログラム側で
        TypeError: string indices must be integer
        このようなエラーが発生し、[]で実行した場合にはIFTTT側で
        Your server returned a 400. Unable to make web request to~
        といったエラーが発生してしまいます。
        半角全角スペースは確認いたしましたが特に間違っている箇所はありませんでした

        • joruji より:

          “”の場合はラズパイ側にデータは届いているようなので、ラズパイ側のプログラムに問題があるのかもしれません。
          記事で紹介したサンプルプログラムをご自身で編集などされましたでしょうか?

          もしくは、jsonデータの中に含まれる、ご自身で設定したbeebotteのChannel名などの変数に問題があるのかもしれません。

comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


関連記事

壊れたイヤホンを半田ごてを使って直してみた – 修理方法解説

   長年使用していたイヤホンが壊れてしまったので、半田ごてを使用して直してみました。この記事ではイヤホンの直し方について解説します。 (イヤホンの構造によって多少直し方は異なる場合があります。) 今 …

RaspberryPiのセットアップ ① – 2種類のOSインストール方法と基本設定

 この記事では、私がラズパイにOSをインストールするたびに行っているRaspberryPiのセットアップについて記載します。ここでは、NOOBSとイメージファイルによる2種類のOSのインストール方法と …

AmazonDushボタンを改造してできること- ラズパイやIoT製品との連携方法

AmazonDushボタンはひと手間加えるだけで、IoT製品等の遠隔ボタンとして使用することができます。これにより、スマートロックと連携させダッシュボタンで鍵を開閉したり、スマートリモコンのボタンとし …

初めての大学生の電子工作 スマートリモコンを作ってみた

 タイトル通り、初めて電子工作をやってみました。電子工作をやったことがないという方にもこの記事を読めば作れるように、つまづいたとこなども丁寧に説明していきます。もしわからないことなどがございましたら気 …

ラズベリーパイをディスプレイに接続せずSSH設定する方法

    一般的にラズベリーパイをパソコンからSSHで操作しようとした場合は、ラズパイにマウス、キーボード、ディスプレイを接続して、一度ラズパイ上でwi-fiの設定を行う必要があります。 しかし、実家に …




関連記事