AWS IoT にデータを送る場合、画像ファイルのような大きなデータはAWS STSで一時的なTokenを取得し、S3に直接書き込むといったやり方があると思います。
今回はそれを使わず、MQTTで画像を送ってみる という事を試してみました。
エッジデバイスはJetsonを使っています。
クラスメソッドさんの
[AWS IoT] RaspberryPiからMQTTで画像をS3にアップロードしてみました を参考にさせていただきました。
#前提
- 送信元デバイスは NVIDIA Jetson Nano 開発者キット B01 を利用
- AWS IoT Core のコンパネで「モノ」を作成して、「モノ」用の証明書も作成してデバイスに保存
- デバイスにはAWS IoT Device SDK をインストール
- 送信用のpythonのコードと、lambdaプログラムコードは [AWS IoT] RaspberryPiからMQTTで画像をS3にアップロードしてみました を参考にさせていただきました。
- 送信した画像はこれ(物体検出 を試していた時のもの)
構成
##1. S3バケット作成
jetson-nano-tsumida-image
というバケットを作成
##2. LambdaからS3へのアクセスロール作成
試して消すので、一旦S3のフルアクセスを付けます。
ロール名はjetson-nano-tsumida-image-lambda
という名前で作成
##3.IoT Core rule action の設定
- ルール名
jetson-nano-tsumida-image
とした - クエリ
SELECT * FROM 'data/jetson-nano-tsumida-image'
##4. lambda
- 一から作成
- 関数名は
jetson-nano-tsumida-image
とした
- アクセス権限はデフォルトの実行ロールの変更 で「既存のロールを使用する」で、2. LambdaからS3へのアクセスロール作成 で作ったものを選択
できた。
- lambda_function.py に以下コードを入れてDeployを押す。
import json
import os
import boto3
from datetime import datetime
from io import BytesIO
from base64 import b64decode
def lambda_handler(event, context):
print("event",event)
img = event["img"]
bucket = event["bucket"]
key = event["key"]
# デコード base64 => binary
img_binary = b64decode(img)
s3 = boto3.resource('s3')
obj = s3.Object(bucket, key)
obj.put(Body=BytesIO(img_binary),ContentType="image/jpg")
return 0
- アクションで「バージョンの発行」を押す
- IoT Core ルールの画面に戻り作ったLambdaを選択して、アクション追加、ルール作成する。
##5. Client
- デバイスの証明書は
./certs/
に保存してある前提 - 画像は
./image/send_picture.jpg
として保存した。
####クライアントプログラム
送信用のpythonのコードは [AWS IoT] RaspberryPiからMQTTで画像をS3にアップロードしてみました を使わせていただきました。
- 画像ファイルは
./image/send_picture.jpg
に書き換えてます。
実行
$ python3 index.py
結果
$ python3 index.py
[30/Jun/2021 22:42:37] INFO - MqttCore initialized
[30/Jun/2021 22:42:37] INFO - Client id: jetson-nano-tsumida
[30/Jun/2021 22:42:37] INFO - Protocol version: MQTTv3.1.1
[30/Jun/2021 22:42:37] INFO - Authentication type: TLSv1.2 certificate based Mutual Auth.
[30/Jun/2021 22:42:37] INFO - Configuring endpoint...
[30/Jun/2021 22:42:37] INFO - Configuring certificates...
[30/Jun/2021 22:42:37] INFO - Configuring reconnect back off timing...
[30/Jun/2021 22:42:37] INFO - Base quiet time: 1.000000 sec
[30/Jun/2021 22:42:37] INFO - Max quiet time: 32.000000 sec
[30/Jun/2021 22:42:37] INFO - Stable connection time: 20.000000 sec
[30/Jun/2021 22:42:37] INFO - Configuring offline requests queueing: max queue size: -1
[30/Jun/2021 22:42:37] INFO - Configuring offline requests queue draining interval: 0.500000 sec
[30/Jun/2021 22:42:37] INFO - Configuring connect/disconnect time out: 10.000000 sec
[30/Jun/2021 22:42:37] INFO - Configuring MQTT operation time out: 5.000000 sec
[30/Jun/2021 22:42:37] INFO - Performing sync connect...
[30/Jun/2021 22:42:37] INFO - Performing async connect...
[30/Jun/2021 22:42:37] INFO - Keep-alive: 600.000000 sec
[30/Jun/2021 22:42:38] INFO - Performing sync publish...
publish: 224238.jpg
[30/Jun/2021 22:42:43] INFO - Performing sync publish...
publish: 224243.jpg
[30/Jun/2021 22:42:52] INFO - Performing sync publish...
publish: 224252.jpg
##6. S3の確認
無事保存されていました。
ちゃんと行けました。
補足
画像のサイズが大きすぎるとtimeoutエラーを起こすため、25Kくらいのサイズにしてから送りました。
AWSIoTPythonSDK.exception.AWSIoTExceptions.publishTimeoutException