SORACOM LTE-M Button Powerd by AWSを使ってSwitchBotを動かしてみた
AmazonのブラックフライデーセールでSwitchBotを買いました。
このSwitchBotは、BLE APIがオープンになっているのでプログラムで制御することができます。
なのでRaspberry Piを使ってSwitchBotを触ることができます。
で、これを試したときにせっかくRaspberry Piを使ってるならMQTTブローカーを立てて遠隔でSwitchBotを操作できそうだと思いました。
そして、遠隔操作でパッと思いついたのが以前使ってたSORACOM LTE-M Button powered by AWSです(ちなみに商品ページのリンクにある活用レシピの中の打刻の話は僕の執筆したやつです)。
というわけで今回は、このSORACOM LTE-M Buttonを使ってSwitchBotを動かしてみました。
システム構成
ボタンを押されたら、Lambda関数を呼び出してSORACOM BeamにPublishします。
Publishしたデータは、SORACOM BeamのMQTTアドレスでRaspberry Piに転送されることでSwitchBotを操作できるようにしていきます。
用意するもの
- SwitchBot
- Raspberry Pi(今回はRaspberry Pi3 model B+を使っています)
- SORACOM LTE-M Button powered by AWS
- USBドングル(SORACOM Airを使用する場合、SORACOM Arcを使っている場合は不要です)
AWS IoT Coreの設定
まずは、AWS IoT CoreでSORACOM Beamに接続するための設定を行います。
モノの作成
-
モノを作成
からAWS IoTで使用するデバイスを登録します。
-
1つのモノを作成
を選択して次へ
をクリックします。
-
モノの名前を任意のものに設定して
次へ
をクリックします。 -
今回はポリシーを新規で作成するので、スキップして、
モノの作成
をクリックします。
-
新しい証明書を自動生成
を選択して次へ
をクリックします。
-
デバイス証明書とプライベートキーファイルは必要なのでここで忘れないようにダウンロードします。(パブリックキーファイルは必要ではありませんがダウンロードしないと終わらないので一緒にダウンロードします。)
また、ルートCA1ファイルも必要になるので合わせてダウンロードします。
ポリシーの作成
-
左のメニューから
ポリシー
を選択して作成
をクリックします。
-
設定内容を記入して、
作成
をクリックします。
- 名前 :
PubSubToAnyTopic
- アクション :
iot:*
- リソース ARN :
*
- 効果 : 許可をチェック
-
左のメニューから
証明書
をクリックして作成した証明書を選択してポリシーのアタッチ
をクリックします。
-
作成したポリシーを選択して
アタッチ
をクリックします。
-
左のメニューから
設定
をクリックしてデバイスデータエンドポイントメモします。
SORACOM Beamとの連携
-
設定するSIMに紐付いたSIMグループを選択して
SORACOM Beam設定
を開く -
MQTTエントリポイント
を選択
-
転送先を設定します。
- プロトコル:MQTTS
- ホスト名:AWS IoT Coreの設定からコピーしたエンドポイント
- ポート番号:8883
- 証明書を有効にして証明書を設定できるようにする
証明書の認証情報入力
- 認証情報:任意のものでOK
- 秘密鍵のテキストボックス:{ランダム文字列}-private.pem.key の内容
- 証明書のテキストボックス:{ランダム文字列}-certificate.pem.crt の内容
- CA 証明局のテキストボックス:Amazon ルート CA の内容
入力したら 保存
をクリックしてBeamの設定が完了します。
IMSIの確認
MQTTのトピックで必要になるので、SORACOMのユーザーコンソールで今回使用するSIMの詳細を開いてIMSIを確認し、メモしておきます。
Raspberry Piの設定
SIMの設定
Raspberry PiからSORACOMのプラットフォームに接続するための設定を行います。
ドングルを使ってセルラー通信をやるならsetup_air.sh
をSORACOMのユーザーサイトからダウンロードして実行します。
Wifiのみで通信をやるなら、SORACOM Arcのセットアップを行います。セットアップはこちらのブログを参考にしてもらうとすぐに試せると思います(僕の書いた記事ですがw)。
環境構築
Raspberry Piに必要なソフトウェアをインストールします。
$ sudo apt-get update
$ sudo apt-get install python3-pip
$ sudo apt-get install python3-dev
$ sudo apt-get install python3-setuptools
$ sudo apt-get install libboost-python-dev
$ sudo apt-get install libboost-thread-dev
次にPythonのライブラリをインストールします。
AWS IoTでSubscribeするには専用のSDKを使いますが、今回はSORACOM BeamのMQTTでSubscribeするのでSDKを使わず、paho-mqttをインストールします。
そして、SwitchBotは公式のレポジトリではpybluezを使った方法が紹介されていますが、調べてみたらサードパーティーで公開されている専用のライブラリがあったのでそっちを使います。
$ sudo pip3 install paho-mqtt
$ sudo pip3 install switchbotpy
コードの用意
環境構築したところで、Subscriberのコードを用意します。
ファイル名はsubscriber.py
とします。
<DEVICE_MAC_ADDR>
はお使いのSwitchBotのMACアドレスに書き換えます。
{{imsi}}
はプレースホルダーになっているので、接続しているSIMのものに書き換えなくても大丈夫です。
#!/usr/bin/env python3
import json
import subprocess
import paho.mqtt.client as mqtt
from switchbotpy import Bot
from switchbotpy.switchbot_util import SwitchbotError
device_addr = '<DEVICE_MAC_ADDR>'
bot = Bot(bot_id=0, mac=device_addr, name='bot0')
def on_connect(clinet, user_data, flag, rc):
print("Connect with result code {}".format(rc))
clinet.subscribe("switchbot/{{imsi}}")
def on_disconnect(client, userdata, flag, rc):
if rc != 0:
print("Unexpected disconnection.")
def on_message(client, userdata, msg):
data = json.loads(msg.payload.decode('utf-8'))
print("Reseaved: {}".format(data))
cmd = data['command']
switch_cmd = None
if cmd == 'on':
switch_cmd = True
elif cmd == 'off':
switch_cmd = False
elif cmd == 'reboot':
subprocess.run(['sudo', 'reboot'])
if switch_cmd is not None:
print('Send Command')
try:
bot.switch(switch_cmd)
except SwitchbotError:
print('Command Falied')
client = mqtt.Client()
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
if __name__ == "__main__":
try:
client.connect("beam.soracom.io", 1883, 60)
client.loop_forever()
except KeyboardInterrupt:
pass
上記のコードを保存して以下のコマンドを実行します。
$ python3 subscriber.py
コンソールに以下のように表示されていればSORACOM Beamに接続できています。
もし接続エラーが出た場合は、SIMの設定ができていない可能性があるので、ping pong.soracom.io
を実行してSORACOMのプラットフォームに接続できているか確認してください。
Connect with result code 0
このあとLambdaからのPublishできるか確認するため、接続状態にしておきます。
Lambda関数の用意
今度はボタンを押したときに実行するLambda関数を用意します。
IAMロールを作成
関数を作成する前にAWSでLambdaのアクセス権限を設定するIAMロールを作成します。
AWSのIAMコンソールを開いて、IAMロールを作成します。
ユースケースから Lambda
を選択して、次へすすむ。
アクセス権は AWSIoTWirelessFullPublishAccess
と AWSLambdaBasicExecutionRole
を設定します。
タグはスキップでOKです。
ロール名は lambdaIoTPublish
にして後は設定内容に問題なければ ロールの作成
をクリックします。
Lambda関数を作成
作成したIAMロールを使ってLambda関数を作成します。以下の内容で設定します。
- 関数名:
buttonTrigger
- ランタイム:Python3.9
- アクセス権限:既存のロールから
lambdaIoTPublish
を選択
import os
import json
import boto3
iot = boto3.client('iot-data', region_name='ap-northeast-1')
def lambda_handler(event, context):
# 押されたときのアクションを取得
click_type = event['deviceEvent']['buttonClicked'].get('clickType')
print("clickType: {}".format(click_type))
# プレイスメントの値を取得
cmd = event['placementInfo']['attributes'].get(click_type)
imsi = event['placementInfo']['attributes'].get('DEVICE_IMSI')
try:
# 受け取ったメッセージをデバイスへPublish
pub_msg = {
'command': cmd
}
iot.publish(
topic = "switchbot/{}".format(imsi),
qos = 0,
payload = json.dumps(pub_msg)
)
except Exception as e:
print(e)
raise e
return {
'statusCode': 200,
'body': 'Success Call'
}
関数のテスト
それでは、メッセージがPublishされるかテストをしてみます。
テストのイベントデータとして、以下のJSONを使います。
DEVICE_IMSI
はSORACOMでお使いのSIMのIMSI番号に書き換えます。
{
"deviceEvent": {
"buttonClicked": {
"clickType": "SINGLE",
"reportedTime": "2018-05-04T23:26:33.747Z"
}
},
"deviceInfo": {
"attributes": {},
"type": "button",
"deviceId": " G030PMXXXXXXXXXX ",
"remainingLife": 5
},
"placementInfo": {
"projectName": "TestProject",
"placementName": "button1",
"attributes": {
"DEVICE_IMSI": "123456789012345",
"SINGLE": "on",
"DOUBLE": "off",
"LONG": "reboot"
},
"devices": {
"myButton": " G030PMXXXXXXXXXX "
}
}
}
テストイベントを用意したらLambdaのテストを実行します。
実行後、Raspberry PiのコンソールにPublishされたメッセージが表示されたら正常に通信できています。そして受け取ったメッセージで手元のSwitchBotも動作していれば問題ありません(たまにSwitchBotとの接続を失敗することがありますが、何度も失敗するときは一度Raspberry Piを再起動して試してもらうといいと思います)。
Reseaved: {'command': 'on'}
AWS IoT 1-Clickの設定
デバイスの追加
今回使用するボタンをAWS IoT 1-Clickに追加します。
AWS IoT 1-Clickのコンソールを開いたら、デバイスの追加
をクリックします。
もしくは、スマホにAWS IoT 1-Clickのアプリをインストールして、そこからデバイスを追加することもできます。
追加するときは、LambdaやAWS IoT Coreを設定したリージョンと同じものを選択していることに注意が必要です。
デバイスプレイスメントの設定
左のメニューから 管理→プロジェクト
をクリックしてプロジェクトを新規で作成します。
作成後、デバイステンプレートを作成します。
デバイステンプレートではボタンが押されたときにLambda関数を呼び出すように設定します。
関数名は先ほど作成したLambda関数名 buttonTrigger
と同じです。
プレイスメントの属性では以下の値を設定します。
IMSIはLambda側で環境変数を設定しなくてもプレイスメントの属性で設定した値を使うことで、値の設定箇所がひとまとめになるので設定が整理しやすくなります。
属性 | 値 |
---|---|
DEVICE_IMSI | SORACOMに接続しているIMSI |
SINGLE | on |
DOUBLE | off |
LONG | reboot |
動作確認
それでは動作確認です。
動画のようにボタンを押してSwitchBotが動いたら、成功です。
ちなみにsystemctlで動かしたときにRaspberry Piを再起動できるようにボタンを長押しするとRaspberry Piが再起動できるようにしています。
まとめ
今回はSORACOM LTE-MボタンでAWSのサービスを駆使してSwitchBotを動かしてみました。
SORACOM Beamを使えばデバイス側にAWSの接続情報を入れなくてもSORACOMのプラットフォームでクラウド側に接続情報を設定することで、デバイス側のコードがシンプルでセキュアな通信を実現できます。
しかも、AWSをよく使う人なのでAWS IoT 1-Clickで簡単にLambdaを動かせるのは便利です。
SORACOM × AWSの相性バツグンですね!
Discussion