[IoT Events] OnEnterとOnInputの実行順序を調べてみた

IoT Eventsの「OnEnter・OnInput・OnExit」の実行順序を調べてみました。
2021.04.02

IoT Eventsの各Stateでは、下記タイミングで様々なアクションを実行できます。

種類 実行タイミング
OnEnter その状態になったとき
OnExit その状態から抜けるとき
OnInput データ入力があったとき

これらがいつ実行されるのかを調べてみました。

おすすめの方

  • AWS IoT Eventsの雰囲気を知りたい方
  • AWS IoT EventsをCloudFormationで作成したい方
  • AWS IoT EventsでOnEnterとOnInputの実行順序を知りたい方

調査方法

下記の探知器モデルを作成します。

検証用の探知器モデル

このとき、それぞれの実行順序を調べます。

  1. 初期実行されるとき
  2. Normal状態でデータ入力があったとき

アクションにSNSトピックへのPublishを行うようにしておき、CloudWatch Logsでログのタイムスタンプを確認します。

IoT Eventsの探知器モデルを作成する

CloudFormationテンプレート

iot_events.yml

AWSTemplateFormatVersion: 2010-09-09
Description: IoT Events Test Sample

Resources:
  TestNotifyTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: sample@example.com
          Protocol: email

  TestlTopicRule:
    Type: AWS::IoT::TopicRule
    Properties:
      RuleName: test_topic_rule
      TopicRulePayload:
        AwsIotSqlVersion: "2016-03-23"
        RuleDisabled: false
        Sql: >-
          SELECT
            topic(2) as deviceId, * as payload
          FROM
            'sample/+/test'
        Actions:
          - IotEvents:
              InputName: !Ref TestEventsInput
              RoleArn: !GetAtt TestTopicRuleRole.Arn

  TestTopicRuleRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: test-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

  TestEventsInput:
    Type: AWS::IoTEvents::Input
    Properties:
      InputName: TestInputData
      InputDefinition:
        Attributes:
          - JsonPath: deviceId
          - JsonPath: payload.point


  TestDetectorModel:
    Type: AWS::IoTEvents::DetectorModel
    Properties:
      DetectorModelName: test-detector-model
      Key: deviceId
      EvaluationMethod: BATCH
      RoleArn: !GetAtt TestEventsDetectorModelRole.Arn
      DetectorModelDefinition:
        InitialStateName: Init
        States:
          - StateName: Init
            OnEnter:
              Events:
                - EventName: OnEnter-at-Init-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnEnter at Init State'"
            OnInput:
              Events:
                - EventName: OnInput-at-Init-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnInput at Init State'"
              TransitionEvents:
                - EventName: to_normal
                  Condition: true
                  NextState: Normal
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'to_normal at Init State'"
            OnExit:
              Events:
                - EventName: OnExit-at-Init-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnExit at Init State'"

          - StateName: Normal
            OnEnter:
              Events:
                - EventName: OnEnter-at-Normal-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnEnter at Normal State'"
            OnInput:
              Events:
                - EventName: OnInput-at-Normal-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnInput at Normal State'"
              TransitionEvents:
                - EventName: to_alert
                  Condition: $input.TestInputData.payload.point > 80
                  NextState: Alert
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'to_alert at Normal State'"
            OnExit:
              Events:
                - EventName: OnExit-at-Normal-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnExit at Normal State'"

          - StateName: Alert
            OnEnter:
              Events:
                - EventName: OnEnter-at-Alert-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnEnter at Alert State'"
            OnInput:
              Events:
                - EventName: OnInput-at-Alert-State
                  Actions:
                    - Sns:
                        TargetArn: !Ref TestNotifyTopic
                        Payload:
                          Type: STRING
                          ContentExpression: "'OnInput at Alert State'"

  TestEventsDetectorModelRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: test-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

  TestDetectorModelLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: /aws/iotevents/test-detector-model

デプロイする

aws cloudformation deploy \
    --template-file iot_events.yml \
    --stack-name IoT-Events-Test-Sample-Stack \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset

データをPublishして、実行順序を確認する

1. 初期実行されるとき

  • トピック: sample/d0001/test
{}

ログを確認したところ、アクションの実行順序は下記でした。

  1. OnEnter-at-Init-State
  2. OnInput-at-Init-State
  3. OnExit-at-Init-State
  4. OnEnter-at-Normal-State

初期実行された場合の実行順序

2. Normal状態でデータ入力があったとき

  • トピック: sample/d0001/test
{
    "point": 100
}

ログを確認したところ、アクションの実行順序は下記でした。

  1. OnInput-at-Normal-State
  2. OnExit-at-Normal-State
  3. OnEnter-at-Alert-State

Normal状態で実行された場合の実行順序

さいごに

探知器モデルを設計する際の参考になれば幸いです。

参考