Help us understand the problem. What is going on with this article?

データをAWS IoT経由でDynamoDBへ保存する

はじめに

仕事上、まるっと引き継いであんまり理解できていない技術である、AWS Iotを自分で一から作成してみる。
やりたいことはタイトルの通り。まずはローカルマシン(PC)から簡単なデータをAWS Iotを使ってDynamoDBへデータを投げる部分を実装してみる。

準備

・AWSアカウント
・ローカルマシン(mac)
・python 3.X ※pipコマンドが使えるようにしておくこと。
・DynamoDBのテーブルは以下の通り作成しておく
 ーテーブル名:iot_test
 ーハッシュキー:time (文字列)

システム構成図

img_0.jpg

AWS IoT側の設定

AWSにログイン後、「IOT Core」をクリックし、AWS IOTの画面を表示し、
左のメニューの「管理」をクリックし、「モノ」をクリック。

img_1.jpg

モノを作成する。「単一のモノを作成する」をクリック。

img_2.jpg

「名前」に任意の名前を入力し、「次へ」をクリック。

img_3.jpg

「モノに証明書を追加」画面で「1-Click 証明書作成 (推奨)」の「証明書作成」ボタンをクリック。
img_4.jpg

証明書が作成されるので、以下をすべてダウンロード。  ※1
・このモノの証明書
・パブリックキー
・プライベートキー
・AWS IoTのルートCA
※このファイルは以降ダウンロード出来なくなるので注意

ダウンロードが完了したら、「ポリシーをアタッチ」をクリック。

img_5.jpg

ポリシーの作成を行います。
「アクション」は「iot:*」
「リソースは「*」
※今回なんでも通す設定にしていますが、設計に応じて必要な制限をかけます。

img_6.jpg

「モノの登録」をクリックして。モノの登録が完了します。

登録されたモノをクリックすると、
HTTPS、MQTTのエンドポイントを確認することができます。
※管理→モノ→セキュリティ→アクションで作成したポリシーを設定しておきます。

データ送信時は「操作」からRest API エンドポイントを確認して入力します。 ★1

img_7.jpg

次に、AWS IOTのホームから「ACT」をクリックし、ルールの作成を行います。

img_8_1.jpg

「名前」は任意の名前を入力し、「ルールクエリステートメント」には
「SELECT * FROM 'testRule/time' 」を入力します。
※ここで指定したクエリにより、送信データをフィルタリングすることもできる。

続いてアクションを設定します。
img_9.jpg

今回はDynamoDBに直接送信データを追加ます。

「アクションの追加」を選択し、「DYNAMODBV2」を選択後、
画面下部にある「アクションの設定」ボタンをクリック。

img_10.jpg

作成済みのDynamoDBを選択します。「リソースの選択」にてテーブルを選択すれば自動で入力されます。
ロールは「ロールの作成」をクリックし、新規作成し、「アクションの追加」をクリック。
以下は作成後の画面。

img_12_1.jpg

ローカルマシン側の設定

任意のディレクトリを作成し、※1のファイルをすべて配置する。

ディレクトリには以下の様になる。
・XXX.crt
・XXX-private.pem.key
・XXX-public.pem.key
・AmazonRootCA1.pem
・test.py ← 実行ファイル

pipコマンドを実行
pip install AWSIoTPythonSDK

test.pyのソース

test.py
'''
Send Time Sample
'''

from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import time
import json
import datetime
import logging

# select Debug mode
_DEBUG_ = 'PC'
#_DEBUG_ = 'Raspberry'

# Setup Param
host = "XXXXXX-ats.iot.us-west-2.amazonaws.com" ★1を入力

if _DEBUG_ == 'PC':
    #for PC
    rootCAPath = "XXXXX/AmazonRootCA1.pem"  ※ダウンロードしたKeyを入力
    certificatePath = "XXXXXX/XXXX-certificate.pem.crt"  ※任意のディレクトリに保管する。
    privateKeyPath = "XXXX/XXXX-private.pem.key"
else:
    #for Raspberry Pi
    rootCAPath = "/cert/AmazonRootCA1.pem"
    certificatePath = "/cert/xxxxxxxxx-certificate.pem.crt"
    privateKeyPath = "/cert/xxxxxxxxx-private.pem.key"

useWebsocket = False
clientId = "testRule"
topic = "testRule/time"
deviceNo = "10001"

# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

# Init AWSIoTMQTTClient
myAWSIoTMQTTClient = None
if useWebsocket:
    myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId, useWebsocket=True)
    myAWSIoTMQTTClient.configureEndpoint(host, 443)
    myAWSIoTMQTTClient.configureCredentials(rootCAPath)
else:
    myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
    myAWSIoTMQTTClient.configureEndpoint(host, 8883)
    myAWSIoTMQTTClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath)

# AWSIoTMQTTClient connection configuration
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)      # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2)            # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)    # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)         # 5 sec

# Connect and subscribe to AWS IoT
myAWSIoTMQTTClient.connect()
time.sleep(2)
# Initial

try:
    while True:
        nowtime = datetime.datetime.now()
        nowsettime = int(time.mktime(nowtime.timetuple()))  # UNIX Time
        #send Command
        message = {}
        message['time'] = nowtime.strftime('%Y/%m/%d %H:%M:%S')
        message['deviceNo'] = deviceNo
        message['ttl']  = nowsettime + 2592000
        messageJson = json.dumps(message)
        print (messageJson)
        myAWSIoTMQTTClient.publish(topic, messageJson, 1)
        time.sleep(10)
except:
    import traceback
    traceback.print_exc()

print ("Terminated")

動きとしては、数秒おきにサンプルで作成したデータをDynamoDBへ送信し続けます。

実行ログ
img_13_1.jpg

DynamoDB(テーブル名はiot_test)
img_14.jpg

まとめ

ひとまず、データをデバイス → AWS IoT → DBへ保存 という流れを一通り再現することができたのと、データを送信するまでのAWS IoTの必要な設定項目、必要なファイルも確認できたので、理解が深まった。

次はデバイスをPCではなく、raspberry piなどで実際の生データを送る部分や、
送ったデータを可視化(クラフ表示)できるようなところを触ってみたいと思います。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away