こんにちは。技術3課の森です。 東京での生活をしている最中、乗り換える必要のない電車に乗ってたはずなのに、人がいっぱい降りるから一緒に降りてしまい、 目的地をあっさりと通過してしまった経験を本日しました。
AWS IoTとCloudWatchで可視化
以前、nakamuraが書いたブログに似たことをやってみました。 ただやるだけではなく、できるだけManagementConsoleを使わずにやってみたかったので、いくつかプログラミングを交えてやってみました。
実行環境の準備
まずは環境の準備から始めます。以下の3つをインストールしてください。
- AWS CLI
- AWS SDK for Python
- mosquitto (MQTT Broker)
- jq
実行環境の作成
実行環境の構成
まずは構成です。
今回デバイスは自分のPCを使い、mosquittoでPublishするようにします。
環境作成スクリプト
まずはAWS IoTのPolicyとThingsを作成します。 ここは簡単に作りたかったので、 AWS CLI + Bash を使って作成しています。
#!/bin/sh #ポリシー名を入力してもらいます echo -n "INPUT PolicyName>>" read POLICY_NAME #AWS IoTのThingの名前を入力してもらいます echo -n "INPUT NEW ThingName>>" read THING_NAME #AWS IoTのThingを作成します aws iot create-thing --thing-name ${THING_NAME} #Thingに紐づける鍵を作成します。 aws iot create-keys-and-certificate --set-as-active > cert.json cat cert.json | jq .keyPair.PublicKey -r > public-key.pem cat cert.json | jq .keyPair.PrivateKey -r > private-key.pem wget https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem -O rootCA.pem CERT_ARN=`cat cert.json | jq .certificateArn -r` CERT_ID=`cat cert.json | jq .certificateId -r` CURRENT_DIR=`dirname $0` aws iot describe-certificate --certificate-id ${CERT_ID} --output text --query certificateDescription.certificatePem > cert.pem cat <<EOF > policy.json { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action":["iot:*"], "Resource": ["*"] }] } EOF #AWS IoTのポリシーを作成とThingと鍵の紐付けを行います aws iot create-policy --policy-name ${POLICY_NAME} --policy-document file://${CURRENT_DIR}/policy.json aws iot attach-principal-policy --principal ${CERT_ARN} --policy-name ${POLICY_NAME} aws iot attach-thing-principal --thing-name ${THING_NAME} --principal ${CERT_ARN}
データ
PublishするJSONデータを作成します。 単純なものであれば、手で作成する方が早いですが、今回はより多く送ってみようということで、 初心者PythonistがJSONで300項目を用意するプログラムを作成してみました。
ここだけは事前にCloudWatchのPutMetricDataを許可したRoleを作成しておいてください。
# -*- coding: utf-8 -*- import boto3 client = boto3.client('iot') vRoleArn = 'arn:aws:iam::123456789012:role/service-role/Role_IoT-CloudWatch' vMetricNamespace = 'SampleNameSpace' #30個のルールを作成するためのループ for i in range(1, 31): vRuleName='iot20_cloud01_' + str(i) vTopicName="'myTopic/data300'" vDescription='description-' + '{0:03d}'.format(i) vDataDataName=[] vMetricValue=[] #10個のActionを作成するためのループ for j in range(1, 11): vDataDataName.append('${devicePlace}/Temp' + '{0:02d}'.format(i) + '{0:02d}'.format(j)) vMetricValue.append('${Temp' + '{0:02d}'.format(i) + '{0:02d}'.format(j) + '}') #AWS IoTのRuleを作成します #10個のActionはベタ書きしています #パラメータはDocumentを参照してください #http://boto3.readthedocs.io/en/latest/reference/services/iot.html#IoT.Client.create_topic_rule response = client.create_topic_rule( ruleName=vRuleName, topicRulePayload={ 'sql':"SELECT * from " + vTopicName, 'description': vDescription, 'actions': [ { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[0], 'metricValue': vMetricValue[0], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[1], 'metricValue': vMetricValue[1], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[2], 'metricValue': vMetricValue[2], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[3], 'metricValue': vMetricValue[3], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[4], 'metricValue': vMetricValue[4], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[5], 'metricValue': vMetricValue[5], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[6], 'metricValue': vMetricValue[6], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[7], 'metricValue': vMetricValue[7], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[8], 'metricValue': vMetricValue[8], 'metricUnit': 'None' } }, { 'cloudwatchMetric': { 'roleArn': vRoleArn, 'metricNamespace': vMetricNamespace, 'metricName': vDataDataName[9], 'metricValue': vMetricValue[9], 'metricUnit': 'None' } }, ], 'ruleDisabled': False, 'awsIotSqlVersion': '2016-03-23' } )
データをPublish
ここでやっとPublishします。何度でも実行できるようにシェルスクリプトで実装しました。
実装したシェルスクリプトを実行します。
#!/bin/sh CURRENT_DIR=`dirname $0` #AWS IoTのEndpointを取得します ENDPOINT=`aws iot describe-endpoint | jq .endpointAddress` JSON_FILE="awsiot-cloudwatch.json" #mosquittoを使ってAWS IoTにPublishします mosquitto_pub --cafile rootCA.pem --cert cert.pem --key private-key.pem -h ${ENDPOINT} -p 8883 -q 1 -d -t myTopic/data300 -f ${CURRENT_DIR}/${JSON_FILE}
Publishしたデータを可視化
先ほど実行したシェルスクリプト。結果はCloudWatchのメトリクスから確認することができます。
今回は少し異なるデータも用意し、Publishしたため、下の図のようにデータ出力結果が斜めの線になっています。
まとめ
今回はシェルスクリプトやPythonを使って何度でも簡単に実行できるようにしたことと OSSでも実現はできるものの安価で簡単に可視化できるCloudWatchを使いました。
ただ、これが正解ではなく、適材適所、そのシチュエーションを考えて、 どういったAWSサービスを使って、DataSourceや可視化するツールを選択する必要があります。
「こんな感じでするともっとかっこいい」とかあれば、教えていただけると次のネタにさせてもらいます。