この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS IoT Eventsを使えば、LambdaやDynamoDBを使わずにハートビート監視ができます。
実際に案件等で使う場合、CloudFormationを使うことになるので、実際に作ってみました。
おすすめの方
- AWS IoT Eventsの雰囲気を知りたい方
- AWS IoT Eventsでハートビートを実現したい方
- AWS IoT EventsをCloudFormationで作成したい方
ハートビートの動作を決める
デバイスの動作
- 下記のトピックにハートビート用のデータを送信する
sample/<デバイスID>/heartbeat
- 2分毎に送信する
- ハートビート用のデータは下記とする(データが届いたかどうかで判断するため、EmptyでOK)
{}
クラウドの動作
- ハートビート用のタイマーがゼロになったとき、デバイス切断と判断してSNSトピックを発行する(メール送信する)
- デバイス切断状態でハートビート用のデータが届いたとき、デバイス接続が復旧したと判断してSNSトピックを発行する(メール送信する)
- デバイス接続状態でハートビート用のデータが届いたとき、ハートビート用のタイマーをReStartする
- ハートビート用のタイマーは5分とする
AWS IoT EventsをCloudFormationで作成する
CloudFormationテンプレート
下記を定義しています。
- メール通知用のSNSトピック
- IoTルール
- IoTルール用のIAMロール
- IoT Eventsの入力情報
- IoT Eventsの探知器モデル
- IoT Eventsの探知器モデル用のIAMロール
iot_events.yml
AWSTemplateFormatVersion: 2010-09-09
Description: IoT Events Heartbeat Sample
Parameters:
HeartbeatTimerDefaultSeconds:
Type: String
Default: 300
Resources:
HeartbeatNotifyTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: sample@example.com
Protocol: email
HeartbeatlTopicRule:
Type: AWS::IoT::TopicRule
Properties:
RuleName: heartbeat_topic_rule
TopicRulePayload:
AwsIotSqlVersion: "2016-03-23"
RuleDisabled: false
Sql: >-
SELECT
topic(2) as deviceId, * as payload
FROM
'sample/+/heartbeat'
Actions:
- IotEvents:
InputName: !Ref HeartbeatEventsInput
RoleArn: !GetAtt HeartbeatTopicRuleRole.Arn
HeartbeatTopicRuleRole:
Type: AWS::IAM::Role
Properties:
RoleName: heartbeat-topic-rule-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iot.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSIoTEventsFullAccess
HeartbeatEventsInput:
Type: AWS::IoTEvents::Input
Properties:
InputName: HeartbeatInputData
InputDefinition:
Attributes:
- JsonPath: deviceId
HeartbeatDetectorModel:
Type: AWS::IoTEvents::DetectorModel
Properties:
DetectorModelName: heartbeat-detector-model
Key: deviceId
EvaluationMethod: BATCH
RoleArn: !GetAtt HeartbeatEventsDetectorModelRole.Arn
DetectorModelDefinition:
InitialStateName: Online
States:
- StateName: Online
OnEnter:
Events:
- EventName: init_timer
Condition: true
Actions:
- SetTimer:
TimerName: HeartbeatTimer
Seconds: !Ref HeartbeatTimerDefaultSeconds
OnInput:
Events:
- EventName: reset_timer
Condition: currentInput("HeartbeatInputData")
Actions:
- ResetTimer:
TimerName: HeartbeatTimer
TransitionEvents:
- EventName: to_offline
Condition: timeout("HeartbeatTimer")
NextState: Offline
- StateName: Offline
OnEnter:
Events:
- EventName: send-mail-to-offline
Actions:
- Sns:
TargetArn: !Ref HeartbeatNotifyTopic
Payload:
Type: STRING
ContentExpression: "'デバイスの切断を検知しました。対象デバイスID: ${$input.HeartbeatInputData.deviceId}'"
OnInput:
TransitionEvents:
- EventName: to_online
Condition: currentInput("HeartbeatInputData")
NextState: Online
OnExit:
Events:
- EventName: send-mail-to-online
Actions:
- Sns:
TargetArn: !Ref HeartbeatNotifyTopic
Payload:
Type: STRING
ContentExpression: "'デバイスの接続が復旧しました。対象デバイスID: ${$input.HeartbeatInputData.deviceId}'"
HeartbeatEventsDetectorModelRole:
Type: AWS::IAM::Role
Properties:
RoleName: heartbeat-detector-model-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iotevents.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSIoTEventsFullAccess
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
デプロイする
aws cloudformation deploy \
--template-file iot_events.yml \
--stack-name IoT-Events-Heartbeat-Sample-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
デプロイされた探知器モデルを確認する
バッチリですね。
動作確認
1. データ送信すると、Online状態になる
- トピック: sample/d0001/heartbeat
{}
タイマーも5分後に設定されています。
2. 2分毎にデータ送信すると、Online状態のまま
- トピック: sample/d0001/heartbeat
{}
タイマーも更新(ReStart)されています。
3. 5分ほど放置すると、Offline状態になる
デバイス切断のメールも来ました。
4. データ送信すると、Online状態に戻る
- トピック: sample/d0001/heartbeat
{}
デバイス接続復旧のメールも来ました。