はじめに
LambdaとDynamoDBを使用すればIOT用のグラフページを作成できるのではと思ったのでその備忘録。
この記事では図中上の「IOTデータ保存」部分を実施。
DynamoDBの設定
パーテーションキーとソートキーがある

上記例ではパーテーションキーがidでソートキーがtime
パーテーションキーのみ、またはパーテーションキーとソートキーの2つを指定する事が可能。
今回のIOT機器の場合、idが機器固有の番号、timeがデータを計測した際の時間としています。
理由としてとあるIOT機器(id)が同じ時間(time)に計測を実施したデータを2つ3つ送信する事は無いはずなので。
idとtimeの2つの値を合わせて主キーの様な扱いとしています。
API Gatewayを使用しない(Lambdaのみ)
関数URLというものが存在する。
これによりLambda関数用のURLを生成できる。
関数URLについては公式ブログを参考にしてください
利用料やAPIGatewayを使用する場合との違いなどが記載されています。
LambdaへDynamoDBへのアクセス権限を与える

Lambda関数で使用中のロールにAmazonDynamoDBFullAccessポリシーをアタッチ。
今回の場合DynamoDBへの書き込み権限だけで問題ないはずですが、あらかじめ用意されているポリシーではFullAccessくらいしか書き込めそうなのが無かったのでとりあえずフルの権限を与えました。
dynamodb:PutItemが書き込みのアクションだと思いますがAWSLambdaDynamoDBExecutionRoleだとDynamoDBは読み込み限定で書き込み許可されてなさそう。
Lambdaプログラム
機器からの受信データはそれぞれ
- v:電源電圧
- temp:気温
- lux:明るさ
- rx:電波受信感度
- status:バッテリー駆動またはソーラー発電による駆動のステータス
機器idは1固定で保存していますが、データと一緒に機器idも受け取るべき。
require 'json'
require 'aws-sdk-dynamodb'
def lambda_handler(event:, context:)
# 受信データ加工
datas = JSON.parse(event["body"])
v = datas["data1"]
temp = datas["data2"]
# datas["data3"]
lux = datas["data4"]
rx = datas["data5"]
status = datas["data6"]
if status > 1
status = false
else
status = true
end
# DynamoDB保存処理
region = 'ap-northeast-1'
table_name = 'iot_data'
client = Aws::DynamoDB::Client.new(region: region)
table_item = {
table_name: table_name,
item: {
id: 1,
battery: status,
rx: rx,
voltage: v,
temperature: temp,
light: lux,
time: "#{Time.now}"
}
}
client.put_item(table_item)
return { event: JSON.generate(event), context: JSON.generate(context.inspect) }
end


