この記事を読むのに必要な時間は約 20 分です。
最近スイッチボット買ってさらに生活が便利になったのですが、思ったのが「声で操作したいなー」ということ。
スイッチボットは通信にBluetoothを利用しているので基本は専用アプリでの操作になります。Amazon EchoやGoogle Homeに対応していると記載がありますが、それは別売りのスイッチリンクという製品を利用することで可能となります。
しかし、この製品が高いんですよね。約7,000円ほどします。。あったら便利何だろうけどそのためだけに7,000円も出すのは高い!
ということで自分で作成することにしました。既にラズパイは持っていたのでそれを利用することにしました。
構成を図解で理解する

結構めんどくさい構図になってしまっているのですが、スイッチボットがBluetoothでの操作にしか対応していないため、このようになっています。
スマートリモコンでBluetooth対応とかできたら良いんですけどね。。現状はそれが不可能なためBluetoothの信号をラズパイから飛ばすしかありません。(ラズパイ3だと標準でBluetoothの通信が可能です)
そしてラズパイを操作する手段ですが、ここは以下の2パターンが考えられます。
- 外部サービスからラズパイの処理を実行する
- ラズパイから外部サービスにアクセスして処理を実行する
シンプルに考えると「1」が単純なのですが、ラズパイを外部からアクセスできるように公開する必要があるので、セキュリティ的な観点で不安が残ります。。となると「2」が残るのですがこれを実現するために今回のように少し複雑な構造になります。
そこで必要になるのがBeebotteというブローカーサービスと呼ばれるものです。
BeebotteはWebhookに対応しているため、それをIFTTTから呼んであげるという構造です。
少しめんどくさいですが、今回利用するBeebotteなどの使い方を覚えると結構いろんなことに応用が効くようになります。Beebotte自体もIoTのためのサービスに位置付けられているようなのでこれを機に使ってみてください。
また、今回そこまで対応していませんが、ラズパイに赤外線受信機をつけることでスマートリモコンで操作可能にし、それをスマートデバイスとしてAmazon Echoに認識させて操作をする方法も考えたりしました。
この方法であれば、Nature Remoなどのスマートリモコンを通してスマホから簡単に操作できるし、Alexaを利用しても「アレクサ、廊下の照明つけて」といったシンプルなフレーズで操作できるようになります。ここは今後の課題です。ラズパイの赤外線操作も少し調べたのですがちょっとめんどくさそうだったので。
各サービスの設定や連携を説明するのですが、その前にいくつか今回利用しているワードについて説明しておきます。
スマートスピーカー(アレクサ・グーグルアシスタント)
Amazon EchoやGoogle Homeをさします。声で操作できるスピーカーで、Amazonの各種サービスを利用できたり、スマート家電やスマートリモコンと連携することで声で家電の操作が可能となります。
今回の一連の処理の流れのスタートです。スイッチボットを声で動かすために必須の製品です。
IFTTT(イフト)

「If This Then That」の頭文字を取ったサービスで、異なるWebサービス間を連携させることができる超絶便利サービスになります。
「異なるWebサービスを連携する」場合、通常であればプログラムを組んだりする必要がありますが、IFTTTはプログラミングは不要でWebサイトやアプリ上から連携の設定をポチポチするだけで使えるようになります。
今回は「スマートスピーカーに話しかけることで、Webhookを実行する」というように利用しています。
IFTTT自体については過去記事でも紹介しているので、初期設定や特徴などを知りたい方は以下の記事を参考にしてください。
Webhook(REST API)

Webhookは単純に説明すると、「POSTリクエストを実行する」ことを指します。そのため、先ほどのIFTTTの設定に合わせて説明すると、「スマートスピーカーに話しかけた場合に特定のURLにリクエストを発行する」と言えます。
この「特定のURLにリクエスト」を発行するという部分ですが、何ができるかと言うと、例えばLINE通知とかの場合だと、「https://notify-api.line.me/api/notify」というURLに対してメッセージなどをパラメータに渡して実行すると、LINEに通知を行うことができます。
URLを叩くとLINEに通知が行くのは、LINE側がそのように設計を行なっているためです。LINE側が設計してURLとして公開している仕組みを「API」と言います。APIの中でも特定の形式に従って設計されているAPIを「REST API」と言います。
※LINE通知で実際にどのように通知を行うかは以下の記事で紹介しています。

ちなみにこのWebhookは特定のアクションに合わせて、POSTリクエストを発行すること自体を指しており、LINE側ではAPIの提供を行なっている形になります。そのため、APIを提供しているサービスであれば、今回のようにIFTTTを経由させることで全て声で操作することが可能です。なんとも便利な時代ですね。
Beebotte(ビーボット)

IoTやリアルタイムでメッセージをやりとりするようなサービスをサポートするために作られたサービスです。
REST APIやWebsocket、MQTTを用いてあらゆるサービスを連携可能としています。サービス的にはIFTTTと近いものがありますが、IFTTTより汎用性がありますが、多少のプログラミングの知識が必要となります。
上の図のように送信者(パブリッシャー)と受信者(サブスクライバー)を接続する中継役のような役割をになっており、両者は相互通信が可能となっています。この型はよくPub/Sub型と呼ばれたりします。
今回の場合はパブリッシャーがIFTTTでサブスクライバーがラズパイになります。
IFTTTはプログラムができなくても、アプリ上などからぽちぽち設定するだけで各Webサービスの連携が可能ですが、Beebotteは簡単なプログラムを書く必要があります。
MQTT
Beebotteで対応している通信規格の一つでWebsocketなどと同様に相互通信が可能です。MQTTを用いてラズパイとBeebotteを常時接続しておくことで、Beebotteからの通信を瞬時にラズパイ側で検知することが可能になります。
特徴としてはWebsocketより通信量が小さいため、軽量データを高速に通信するのに優れています。
スイッチボットの操作に関しては通信回数自体は少ないですが、大した情報の通信も不要でサンプルソースも記載されていたMQTTを利用しています。
基本やること自体は上記で説明したPub/Subの構造でそこの通信方法としてMQTTを利用すると理解してください。
IFTTTからBeebotteをキックしたタイミングでサブスクライバーに対して通信が行われますが、そのタイミングまでにラズパイからBeebotteに接続している必要があるため「⓪」を記載しています。
各サービスの設定手順を解説
上記で解説した各種サービスを連携していくのですが、それぞれちょっとした設定が必要です。具体的には以下のような設定です。
ラズパイ部分に関してはコーディングとなりますが、サンプルソースを作成しているのでほぼコピペでいけます。
- BeebotteでIFTTTからキックするようのチャンネルを作成
- IFTTTでAlexaからWebhookをキックするアプレットを作成
- ラズパイからBeebotteに接続するソースを記載(Python)
以下に設定方法を記載していきます。
BeebotteでIFTTTからキックするようのチャンネルを作成

まず、Beebotteに登録されていない方は登録して新規チャンネルを作成してください。チャンネルと言うのはBeebotte内での名称になります。1サービス1チャンネルで作成するものだと思ってください。
アカウント登録がまだの方はメインページ右上の「Sign up」から登録を行なってください。アカウント自体はメールアドレスだけで作成可能で利用料金等は基本的に発生しません。
正確にはBeebotteには無料利用枠と有料枠があるのですが、無料利用枠が広いため基本的に料金が発生しないようになっています。

利用するのはこの「XS」枠です。無料枠にも関わらず1日に50,000メッセージまでやりとりが可能です。スイッチボットの操作は1メッセージで完結するので1日に5万回スイッチボットを操作しない限り料金は発生しません。てわけでそんな操作することもないので(1日に10回も操作しない)まぁ無料と言うことです!!
登録が完了すると以下のような画面になるので、「Create New」から新規チャンネルを作成します。

設定は以下のキャプチャのように適当に名前とか説明をつけて、リソースは一つ何か追加してください。
入力できたら、「Create channel」をクリックしてチャンネルを保存してください。

作成が完了すると、以下のようにチャンネル一覧の画面に戻ります。(最初にあったtestチャンネルは削除しました)

「Switchbot」のチャンネル名のところをクリックすると、チャンネルに接続するために必要なチャンネルトークンの確認が行えます。
これは後ほど利用するのでメモしておいてください。

続いて、「Account Settings」以下からSecret Keyもメモしておいてください。

一旦はこれでBeebotteの設定は完了です。
IFTTTでAlexaからWebhookをキックするアプレットを作成
IFTTTはWeb版でもスマホからアプリで作成しても良いのですが、次のようなアプレットを作成してください。
今回連携させるのは「Amazon Alexa」と「Webhook」です。
IFTTTの登録とか基本的な使い方がわからない方は以下の記事を参考にしてください。


選択して、トリガーは「Say a specific phrase」を選んでください。

フレーズは好きな文言にしてください。ここでは例として「電気消して」としています。


「that」にはWebhookを指定します。「Web」と打ったら一つに絞り込まれるので選択してください。

Webhookのトリガーは一つだけなのでそれを指定してください。

リクエストの指定ですが、画像の設定のように指定してください。
URLだけちょっと解説しておくと、「[特定のURL]/[Beebotteで作成したチャンネル]/[リソース]/?token=[チャンネルトークン]」で指定します。
- 特定のURL:https://api.beebotte.com/v1/data/publish/
- Beebotteで作成したチャンネル:Switchbot
- リソース:data
- チャンネルトークン:token_で始まる文字列
他の項目は画像通りで問題ありません。複数のスイッチボットやスイッチのオンオフを行う場合は「Body」の部分で判定を行うことになるのでそれぞれ判定できるように値を入れてください。
※このアクションは一つの設定で一つの操作しか行えないため、スイッチのONとOFFを行うにはアプレットを2つ作成する必要があります。

以上でIFTTTの設定は完了です。
これでアレクサに「アレクサ、電気消して、トリガー」と話しかけると、
アレクサ → IFTTT → Beebotte というように通信が連携していきます。
ちゃんと通信が行えているかはBeebotteのコンソールから確認が可能です。
Beebotteの設定時に確認した、シークレットキーとチャンネル、リソースを入力して「Subscribe」をクリックしてください。
その状態で先ほどのIFTTTで設定したワードをアレクサに話しかけると右側のMessagesに通信データが表示されます。

これがうまく行かない場合はおそらくIFTTTのWebhookで指定しているURLが誤っているので確認してください。
ラズパイ(Raspberry Pi)からBeebotteに接続するソースを記載(Python)
ソースはGithubに挙げているので自由に使っていただいて構いません。
参考 Beebotte接続用ソースGithub必要なライブラリのインストールはGithubのREADMEを読んでください。
最初の変数だけ、自分で設定したBeebotteのトークンやチャンネル、リソースに置き換えてください。
スイッチボットのMACアドレスの調べ方は以下の記事で記載しているので参考にしてください。

ソース自体も一応ここにも記載しておきます。
import paho.mqtt.client as mqtt
import json
import binascii
from bluepy.btle import Peripheral
TOKEN = "Beebotteのトークン"
HOST = "mqtt.beebotte.com"
TOPIC = "作成したチャンネル/リソース"
CACERT = "mqtt.beebotte.com.pem"
SWITCHBOT = "SwitchbotのMACアドレス"
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe(TOPIC)
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
p = Peripheral(SWITCHBOT, "random")
hand_service = p.getServiceByUUID("cba20d00-224d-11e6-9fb8-0002a5d5c51b")
hand = hand_service.getCharacteristics("cba20002-224d-11e6-9fb8-0002a5d5c51b")[0]
hand.write(binascii.a2b_hex("570100"))
p.disconnect()
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(HOST, port=8883, keepalive=60)
client.loop_forever()
こんな感じです。IFTTTで設定したdataで処理を分ける場合は「on_message」 で分岐するように処理を記載する必要があります。
まとめ
いかがでしたでしょうか。連携させるサービスが増えるとやり始めるのが少し億劫になりますがやってみると結構楽しいです。
今回のBeebotte、ラズパイの連携が行えるとIoTの活用の幅が広がります。外からの通信でラズパイの操作が色々とできるようになるのであとはアイディア次第でなんでもできるのでは?と思っています。
以上、スマートホーム化を楽しみましょう!