Atom's tech blog

Raspberry Pi でAWS IoT Core Lambda関数を未使用でPythonスクリプトを実行してみた!

f:id:iAtom:20201202142541j:plain


本記事では、コアデバイスRaspberry Pi)にデプロイしたLambda関数ではないPythonスクリプトを実行してAWS IoT Coreでメッセージ受信ができるかトライしてきます。

Raspberry Piのインストールや証明書、ルートCA、キー情報は、「 Raspberry PiAWS IoT Greengrassを動かしてみた!(Part1)〜(Part5」をご確認ください。

AWS構成図

f:id:iAtom:20201203140450j:plain

Raspberry PiSSH接続

MACターミナルからRaspberry PiSSH接続をします。 自分の環境に合わせてIPアドレスを変更してください。

    # ssh pi@192.168.10.10

環境構築

コアデバイスRaspberry Pi)にMQTT通信ライブラリをインストールします。Lambda関数を使用した時は、SDKAWSからデプロイしていましたが、今回はLambdaは使用しないため、MQTT通信するライブラリをインストールしておきます。

    $ pip3 install paho-mqtt

Pythonスクリプトファイル編集と実行

次のソースは下記サイトからコピーして証明書、ルートCA、endpointを変更しています。

aws.amazon.com

endpointはAWS IoTコンソールから確認ができます。


f:id:iAtom:20201130170539j:plain

それではPythonソースコード(mqtt_test.py)です。

証明書、ルートCA、キー情報は前回の設定をそのまま使用するので 絶対パスで 「/greengrass/certs/.....」としています。 ここは個々の環境で変更してください。

from __future__ import print_function
import sys
import ssl
import time
import datetime
import logging, traceback
import paho.mqtt.client as mqtt

IoT_protocol_name = "x-amzn-mqtt-ca"
aws_iot_endpoint = "xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com"  # 自分のAWS IoTのエンドポイントを設定。
url = "https://{}".format(aws_iot_endpoint)

ca = "/greengrass/certs/root.ca.pem"                          # -->  自分の環境に合わせたルートを設定。
cert = "/greengrass/certs/yyyyyyyyyy.cert.pem"          # -->  自分の環境に合わせた証明書を設定。
private = "/greengrass/certs/yyyyyyyyyy.private.key"  # -->  自分の環境に合わせたキー情報を設定。

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(log_format)
logger.addHandler(handler)

def ssl_alpn():
    try:
        #debug print opnessl version
        logger.info("open ssl version:{}".format(ssl.OPENSSL_VERSION))
        ssl_context = ssl.create_default_context()
        ssl_context.set_alpn_protocols([IoT_protocol_name])
        ssl_context.load_verify_locations(cafile=ca)
        ssl_context.load_cert_chain(certfile=cert, keyfile=private)

        return  ssl_context
    except Exception as e:
        print("exception ssl_alpn()")
        raise e

if __name__ == '__main__':
    topic = "test/date"
    try:
        mqttc = mqtt.Client()
        ssl_context= ssl_alpn()
        mqttc.tls_set_context(context=ssl_context)
        logger.info("start connect")
        mqttc.connect(aws_iot_endpoint, port=443)
        logger.info("connect success")
        mqttc.loop_start()

        while True:
            now = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
            logger.info("try to publish:{}".format(now))
            mqttc.publish(topic, now)
            time.sleep(1)

    except Exception as e:
        logger.error("exception main()")
        logger.error("e obj:{}".format(vars(e)))
        logger.error("message:{}".format(e.message))
        traceback.print_exc(file=sys.stdout)

pythonファイルの実行

Pythonファイルを実行すると日時情報を送信します。 トピックスは「test/date 」です。

    $ sudo python3 mqtt_test.py

AWS IoT テスト実行

記事のGreengrass(Part5)までで作成した情報をそのまま使用します。ただ「テスト」しか使わないので、もし前回のままデプロイした状態の場合は、テプロイをリセット(停止)しておきます。

AWS IoTコンソールで「テスト」を選択します。 トピックのサブスクリプションは、なんでも受け付けて表示したいため「#」を使用します。 この「#」はどのようなトピック情報でも受信表示するようです。


f:id:iAtom:20201130164704j:plain

「トピックのサブスクライブ」をクリックするとRaspberry Piから送信された日時情報が表示され、受信できたことが確認できました。 当然ながらLambda関数使用/未使用どちらでも動作できました.....ね


f:id:iAtom:20201130172829j:plain

最後に

テスト終了後は、AWS IoT Coreの「テスト」、Raspberry PiPythonスクリプトの停止を忘れずに。