はじめに
LambdaとDynamoDBを使用すればIOT用のグラフページを作成できるのではと思ったのでその備忘録。
この記事では図中の「グラフページ表示」部分を実施。
前回:https://qiita.com/aikawa_YO/items/79e8ef768b03e3f73315
HTMLの中身
imgタグのsrcには前回のグラフ画像を返してくれるLambda関数URLを指定してください。
import json
def lambda_handler(event, context):
return {
'statusCode': 200,
'isBase64Encoded': False,
"headers": {"Content-Type": "text/html"},
'body': '<h1>graph:temperature</h1><img src="https://xxxxxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/">'
}
別に画像を別で作らなくてもいい話
imgタグで画像を表示させるにはURLを指定しないといけないという固定観念にとらわれていた。
バイトデータをそのままHTMLへ直書きすれば出力できるのでこっちのほうがはやい。
import base64
import boto3
import matplotlib.pyplot as plt
from io import BytesIO
from datetime import datetime as dt
from boto3.dynamodb.conditions import Key
def lambda_handler(event, context):
dynamodb = boto3.resource("dynamodb", region_name='ap-northeast-1')
table = dynamodb.Table("iot_data")
response = table.query(
KeyConditionExpression=Key("id").eq(1),
ScanIndexForward=False
)
items = response["Items"]
temps = []
times = []
for item in items:
temps.append(float(item['temperature']))
times.append(dt.strptime(item['time'], '%Y-%m-%d %H:%M:%S %z'))
fig = plt.figure()
plt.plot(times, temps)
ofs = BytesIO()
fig.savefig(ofs, format="png")
png_data = ofs.getvalue()
plt.close()
html_txt = '<h1>graph:temperature</h1><img src="data:image/png;base64,'
html_txt += base64.b64encode(png_data).decode('utf-8')
html_txt += '">'
return {
'statusCode': 200,
'isBase64Encoded': False,
"headers": {"Content-Type": "text/html"},
'body': html_txt
}