##モチベーション
Raspberry Pi カメラ画像をS3へアッロードでは、ラズパイからAWSのアクセスはAWS SDK for Python (Boto3) を使用している。
AWS IoTを使うのと何が違うんだろ?ということでAWS IoT Coreを試す。
ラズパイ→boto3→AWS S3→xxx
ラズパイ→AWSIoTPythonSDK→AWSIoTMQTTClient→AWS IoT Core→xxx
##AWS IoTにRaspberryPiを登録
###モノの作成
https://console.aws.amazon.com/iot/home?region=us-east-1#/home
- 開始方法→管理→モノ→作成→単一のモノを登録する
- 名前:RasPi3B
- 次へ
- 証明書の作成
このモノの証明書 xxxxxcert.pem→ダウンロード
パブリックキー xxxxx.public.key→ダウンロード
プライベートキー xxxxx.private.key→ダウンロード
AWS IoT のルート CA→ダウンロードをリンク先へ、この5種のルート証明書がダウンロードできるのだが、どれが最適なのか、正直不明。
デバイスつまりラズパイRSAベースなのか、ECCベースなのかで選べばよいみたい。
一旦全部ダウンロードしてみる。
どうも、Aug 29, 2018まではVeriSignの証明書へのリンクが張られていたのが、変更になった模様。VeriSignの証明書が使えなくなるためAWSが独自の証明書である Amazon Trust Sevices (ATS)を提供開始したため。(理由は下記ページからの私の推測です
https://aws.amazon.com/jp/about-aws/whats-new/2018/08/aws-iot-core-adds-new-endpoints-serving-amazon-trust-services-signed-certificates-to-help-customers-avoid-symantec-distrust-issue)
###ポリシを作成して証明書にアタッチ
安全性→ポリシー→作成
###AWSIoTPythonSDKのインストール(AWSIoTPythonSDK-1.4.4)
pi@raspberrypi:~ $ pip install AWSIoTPythonSDK
Collecting AWSIoTPythonSDK
Downloading https://files.pythonhosted.org/packages/95/1d/40c13828f8cec38b4ca4213b9815d19f4776de17bb82f9680b9297925ca9/AWSIoTPythonSDK-1.4.4.tar.gz (79kB)
100% |████████████████████████████████| 81kB 989kB/s
Building wheels for collected packages: AWSIoTPythonSDK
Running setup.py bdist_wheel for AWSIoTPythonSDK ... done
Stored in directory: /home/pi/.cache/pip/wheels/f6/f9/4c/8959a65e4a45bdf0dd5f0e062a93b30b5221a4fffea7f85a2a
Successfully built AWSIoTPythonSDK
Installing collected packages: AWSIoTPythonSDK
Successfully installed AWSIoTPythonSDK-1.4.4
###RESTエンドポイントの確認
AWS IoT→ソフトウェア→設定 からエンドポイントを確認
###Subscribeするpythonコード
# coding: utf-8
import time
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
CLIENT_ID = "test_client_id"
ENDPOINT = "xxx-ats.iot.us-east-1.amazonaws.com"
# MQTTでは、標準で1883/TCPポート
# SSL(TLS)による暗号化を行う場合には8883/TCPポートを使用。
PORT = 8883
ROOT_CA = "./cert/AmazonRootCA1.pem"
PRIVATE_KEY = "./cert/xxx-private.pem.key"
CERTIFICATE = "./cert/xxx-certificate.pem.crt"
TOPIC = "RasPi3B/sample"
def main():
# https://s3.amazonaws.com/aws-iot-device-sdk-python-docs/sphinx/html/index.html
# setting for MQTT
client = AWSIoTMQTTClient(CLIENT_ID)
client.configureEndpoint(ENDPOINT, PORT)
client.configureCredentials(ROOT_CA, PRIVATE_KEY, CERTIFICATE)
# AWSIoTMQTTClient connection configuration
client.configureAutoReconnectBackoffTime(1, 32, 20)
# -1:infinite
client.configureOfflinePublishQueueing(-1)
# Draining: 2 Hz
client.configureDrainingFrequency(2)
# 10 sec
client.configureConnectDisconnectTimeout(10)
# 5 sec
client.configureMQTTOperationTimeout(5)
# Connect to AWS IoT with default keepalive set to 600 seconds
# keepAliveIntervalSecond : Time in seconds for interval of sending MQTT ping request. Default set to 600 seconds.
client.connect()
# TOPICが起動したら呼ばれる関数を登録するQoS(Quality of Service)=1
# QoS=0:投げっぱなし,QoS=1:少なくとも1回は確実にBrokerにメッセージが届く
client.subscribe(TOPIC, 1, mycallback)
# time.sleep(5)
#無限ループ
while True:
time.sleep(5)
def mycallback(client, userdata, message):
print("Received a new message: ")
print(message.payload)
print("from topic: ")
print(message.topic)
print("--------------\n\n")
if __name__ == "__main__":
main()
コード実行
pi@raspberrypi:~ $ python mqttclient.py
##テスト機能を使ってトピックを発行(publish)
AWS IoT→テスト
RasPi3B/sampleを入力して、「トピックを発行」
メッセージが受信され、登録してあった処理が呼ばれることが分かる。
無限ループにしているので、最後にCtrl-Zでループを抜ける。
pi@raspberrypi:~ $ python mqttclient.py
Received a new message:
{
"message": "Hello from AWS IoT atsmaru"
}
from topic:
RasPi3B/sample
--------------
^Z
[3]+ 停止 python mqttclient.py
##最後に
できたことを図示するとこんな感じ。
モノRasPi3B
├ 証明書
│ └ ポリシー
├ エンドポイント
├ トピック:RasPi3B/sample ← Publish ← test
← subscribe ← ラズパイのpython
##次回
ラズパイからトピックを発行したかったのに、逆のことをしてしまいました。
次回当初したかったことをトライします。