概要

 Raspberry PiがAWSから操作情報を受け取るためのプログラムの実装と、LambdaからRaspberry PiでON/OFF操作情報を送信するテストを行った。


背景と目的

 前回までで、疑似赤外線リモコンが完成した。今回は、Rapsberry PiがAWSから操作情報を受け取って疑似赤外線リモコンへ送信指示を出せるようにする。


詳細

1.方法

 AWSとRaspberry Piを連携させるには、AWS IoTを使う。操作情報を含むトピックをRaspberry Piがサブスクライブすればよさそう。

2.AWS IoTのコンソールでデバイスの作成

 デバイス作成は、AWS IoT上のコンソールのウイザードに従ってやった。コンソールのconnectから、Configuring a deviceのGet startedをクリックし、プラットフォームとSDKを選択する。プラットフォームはRaspbianなのでLinuxを選択。SDKは、いつの間にやらPythonができているのでPythonを選択。

SDK選択
図2.2 プラットフォームとSDKの画面

 次に、Thingの名前を決めてNext Stepに進むと、Download connect kitというものダウンロードボタンが現れるので、ダウンロード。

connection_kit
図2.3 connect kitのダウンロード画面

 次に、コマンドの指示がでるので、ダウンロードしたzipファイルをFTPでRaspberry Piに転送し、コマンドを実行。Start.shがうまく動けば、以下のようにコンソールに表示が出る。同時に、図2.5のようにAWSのコンソールにも表示が出る。

test
図2.4 コマンドを実行させた様子

command2
図2.5 通信がうまくいってるときのコンソール

 ここまでで、Raspberry PiとAWS IoTの接続ができた。

3.Raspberry Piで、トピックをサブスクライブする

 以下のリンク等を参考に、トピックをサブスクライブするためのコードを作成。

 最初、END_POINTというパラメータは何を指定すればいいか分からなかったが、こちらを見て、InteractのHTTPSという欄にあるRest API EndpointでOKだということが分かった。

# Import SDK packages
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient

CLIENT_ID = "Thing名"
END_POINT = "xxx.iot.リージョン名.amazonaws.com"
PATH_CA = "配置先ディレクトリ/root-CA.crt"
PATH_KEY = "配置先ディレクトリ/Thing名.private.key"
PATH_CRT = "配置先ディレクトリ/Thing名.cert.pem"

# For certificate based connection
myMQTTClient = AWSIoTMQTTClient(CLIENT_ID)

# Configurations
myMQTTClient.configureEndpoint(END_POINT, 8883)
myMQTTClient.configureCredentials(PATH_CA, PATH_KEY, PATH_CRT)

# 接続
myMQTTClient.connect()

# サブスクライブ開始
myMQTTClient.subscribe("$aws/things/Thing名/shadow/update", 0, subscribe_callback)

# 受信待ち
while True:
    time.sleep(1)

 そして、subscribeメソッドの引数に渡したコールバック関数は、トピックが到着したときの処理を書けばよい。ここでは、詳細は省略するが、到着したペイロードの中に、ON/OFF操作情報があるとして、それに応じてGPIO18にパルスを送るようにしている。

def subscribe_callback(client, userdata, message):
    # データを受け取る
    payload = json.loads(message.payload)
    # payloadの内容に応じて、GPIO18にパルスを送る
    :
    :
4.Lambdaによる確認

 最後に、LambdaでAWS IoTのThing Shadowに、トピックをパブリッシュしてみた。実装は、boto3を使った。参考になったサイトは以下。payloadという辞書に、送信したいデータを入れる。

# coding: utf-8
import boto3
import json

iot = boto3.client("iot-data", リージョン名)

def lambda_handler(event, context):

    # 送信データを作成
    payload = {
        "state": {
            "desired": {
                キー : 値,
                :
            },
            "reported": {
                キー : 値,
                :
            }
        }
    }
    
    # パブリッシュする
    iot.publish(
        topic='$aws/things/Thing名/shadow/update',
        qos=0,
        payload=json.dumps(payload)
    )

    # TODO implement
    return {}

 この結果、正しくトピックが受信され、無事エアコンがON/OFFできた!

 というわけで、AWS IoTとRaspberry Piが接続され、操作情報を載せたトピックをパブリッシュすればエアコンの電源がON/OFFできるところまできた。次回は、最終段階であるAPI Gateway⇒Lambda部分を構築し、スマホの操作を完成させる。