

지원 종료 알림: 2026년 5월 20일에 AWS 에 대한 지원이 종료됩니다 AWS IoT Events. 2026년 5월 20일 이후에는 AWS IoT Events 콘솔 또는 AWS IoT Events 리소스에 더 이상 액세스할 수 없습니다. 자세한 내용은 [AWS IoT Events 지원 종료를 참조하세요](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-end-of-support.html).

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 주석이 달린 예제:를 사용한 HVAC 온도 제어 AWS IoT Events
<a name="iotevents-commented-example"></a>

다음 예제 JSON 파일 중 일부에는 주석이 인라인으로 포함되어 있어 유효하지 않은 JSON이 됩니다. 이러한 예제의 전체 버전(주석 제외)은 [예:에서 HVAC 온도 제어 사용 AWS IoT Events](iotevents-examples-hvac.md)에서 확인할 수 있습니다.

이 예제는 다음 작업을 수행할 수 있는 온도 조절기 제어 모델을 구현합니다.
+ 여러 영역을 모니터링하고 제어하는 데 사용할 수 있는 감지기 모델을 하나만 정의합니다. 감지기 인스턴스는 각 영역에 대해 생성됩니다.
+ 각 제어 영역의 여러 센서에서 온도 데이터를 수집합니다.
+ 특정 지역의 온도 설정점을 변경합니다.
+ 인스턴스가 사용 중인 동안 각 영역의 작동 파라미터를 설정하고 이러한 파라미터를 재설정합니다.
+ 영역에 센서를 동적으로 추가 또는 삭제합니다.
+ 냉난방 장치를 보호할 수 있는 최소 런타임을 지정하십시오.
+ 비정상적인 센서 판독값을 거부합니다.
+ 센서 중 하나에서 지정된 임계값보다 온도가 높거나 낮다고 보고하는 경우 즉시 난방 또는 냉방을 작동시키는 비상 설정점을 정의합니다.
+ 비정상적인 측정값 및 온도 급상승을 보고합니다.

**Topics**
+ [

# 의 감지기 모델에 대한 입력 정의 AWS IoT Events
](iotevents-commented-example-inputs.md)
+ [

# AWS IoT Events 감지기 모델 정의 생성
](iotevents-commented-example-detector-model.md)
+ [

# BatchUpdateDetector를 사용하여 AWS IoT Events 감지기 모델 업데이트
](iotevents-commented-example-batch-update-detector.md)
+ [

# 의 입력에 BatchPutMessage 사용 AWS IoT Events
](iotevents-commented-example-input-usage-examples.md)
+ [

# 에서 MQTT 메시지 수집 AWS IoT Events
](iotevents-commented-example-ingest-mqtt.md)
+ [

# 에서 Amazon SNS 메시지 생성 AWS IoT Events
](iotevents-commented-example-generated-sns.md)
+ [

# 에서 DescribeDetector API 구성 AWS IoT Events
](iotevents-commented-example-describe-detector.md)
+ [

# 에 규칙 AWS IoT Core 엔진 사용 AWS IoT Events
](iotevents-commented-examples-iot-rules-examples.md)

# 의 감지기 모델에 대한 입력 정의 AWS IoT Events
<a name="iotevents-commented-example-inputs"></a>

여러 영역의 온도를 모니터링하고 제어하는 데 사용할 수 있는 하나의 감지기 모델을 만들려고 합니다. 각 영역에는 온도를 보고하는 센서가 여러 개 있을 수 있습니다. 각 구역에는 냉난방 장치가 각각 하나씩 있으며, 이 장치를 켜거나 끄면 해당 구역의 온도를 제어할 수 있다고 가정합니다. 각 영역은 하나의 감지기 인스턴스로 제어됩니다.

모니터링하고 제어하는 영역마다 특성이 다르기 때문에 제어 파라미터가 다를 수 있으므로 각 영역에 해당 파라미터를 제공하도록 `'seedTemperatureInput'`을 정의합니다. 이러한 입력 메시지 중 하나를 AWS IoT Events에 보내면 해당 영역에서 사용하려는 파라미터가 포함된 새 감지기 모델 인스턴스가 생성됩니다. 해당 입력의 정의는 다음과 같습니다.

CLI 명령:

```
aws iotevents create-input --cli-input-json file://seedInput.json
```

파일: `seedInput.json`

```
{
  "inputName": "seedTemperatureInput",
  "inputDescription": "Temperature seed values.",
  "inputDefinition": {
    "attributes": [
      { "jsonPath": "areaId" },
      { "jsonPath": "desiredTemperature" },
      { "jsonPath": "allowedError" },
      { "jsonPath": "rangeHigh" },
      { "jsonPath": "rangeLow" },
      { "jsonPath": "anomalousHigh" },
      { "jsonPath": "anomalousLow" },
      { "jsonPath": "sensorCount" },
      { "jsonPath": "noDelay" }
    ]
  }
}
```

응답:

```
{
    "inputConfiguration": {
        "status": "ACTIVE", 
        "inputArn": "arn:aws:iotevents:us-west-2:123456789012:input/seedTemperatureInput", 
        "lastUpdateTime": 1557519620.736, 
        "creationTime": 1557519620.736, 
        "inputName": "seedTemperatureInput", 
        "inputDescription": "Temperature seed values."
    }
}
```

**참고**
+ 모든 메시지에서 `'areaId'` 수신된 각 고유자에 대해 새 감지기 인스턴스가 생성됩니다. `'areaDetectorModel'` 정의의 `'key'` 필드를 참조하십시오.
+ 평균 온도는 `'allowedError'`에 의해 해당 지역의 난방 또는 냉방 장치가 활성화되기 전의 `'desiredTemperature'`와 다를 수 있습니다.
+ 센서가 `'rangeHigh'`보다 높은 온도를 보고하면 감지기가 급상승을 보고하고 즉시 냉각 장치를 가동합니다.
+ 센서가 `'rangeLow'`보다 낮은 온도를 보고하면 감지기는 스파이크를 보고하고 즉시 난방 장치를 가동합니다.
+ 센서가 `'anomalousHigh'`보다 높거나 `'anomalousLow'`보다 낮은 온도를 보고하는 경우 감지기는 비정상적인 센서 판독값을 보고하지만 보고된 온도 판독값은 무시합니다. 
+ `'sensorCount'`은(는) 해당 구역에 대해 보고하는 센서 수를 감지기에 알려줍니다. 감지기는 수신한 각 온도 측정값에 적절한 가중치를 부여하여 해당 구역의 평균 온도를 계산합니다. 따라서 감지기는 각 센서가 보고하는 내용을 추적할 필요가 없으며 필요에 따라 센서 수를 동적으로 변경할 수 있습니다. 하지만 개별 센서가 오프라인 상태가 되면 감지기는 이를 인식하지 못하거나 허용치를 적용하지 못합니다. 각 센서의 연결 상태를 모니터링하기 위해 다른 감지기 모델을 특별히 생성하는 것이 좋습니다. 상호 보완적인 두 개의 감지기 모델을 사용하면 두 모델의 설계가 단순해집니다.
+ `'noDelay'` 값은 `true` 또는 `false`일 수 있습니다. 장치의 무결성을 보호하고 작동 수명을 연장하려면 난방 또는 냉방 장치를 작동한 후, 최소 일정 시간 동안 켜두어야 합니다. `'noDelay'`가 `false`로 설정된 경우, 감지기 인스턴스는 냉방 및 난방 장치의 전원을 끄기 전에 지연 시간을 적용하여 최소 시간 동안 작동되도록 합니다. 변수 값을 사용하여 타이머를 설정할 수 없기 때문에 감지기 모델 정의에 지연 시간(초)이 하드코딩되었습니다.

센서 데이터를 감지기 인스턴스로 전송하는 데 `'temperatureInput'`이 사용됩니다.

CLI 명령:

```
aws iotevents create-input --cli-input-json file://temperatureInput.json
```

파일: `temperatureInput.json`

```
{
  "inputName": "temperatureInput",
  "inputDescription": "Temperature sensor unit data.",
  "inputDefinition": {
    "attributes": [
      { "jsonPath": "sensorId" },
      { "jsonPath": "areaId" },
      { "jsonPath": "sensorData.temperature" }
    ]
  }
}
```

응답:

```
{
    "inputConfiguration": {
        "status": "ACTIVE", 
        "inputArn": "arn:aws:iotevents:us-west-2:123456789012:input/temperatureInput", 
        "lastUpdateTime": 1557519707.399, 
        "creationTime": 1557519707.399, 
        "inputName": "temperatureInput", 
        "inputDescription": "Temperature sensor unit data."
    }
}
```

**참고**
+ 예제 감지기 인스턴스에서 센서를 직접 제어하거나 모니터링하는 데 `'sensorId'`가 사용되지 않습니다. 감지기 인스턴스가 보낸 알림에 자동으로 전달됩니다. 이를 통해 오류가 발생한 센서(예: 비정상적인 판독값을 정기적으로 전송하는 센서가 곧 고장날 수 있음) 또는 오프라인 상태가 된 센서(장치의 심장 박동을 모니터링하는 추가 감지기 모델의 입력으로 사용되는 경우)를 식별하는 데 사용할 수 있습니다. 또한 측정값이 평균과 정기적으로 다를 경우 `'sensorId'`은(는) 해당 구역의 따뜻한 곳이나 차가운 곳을 식별하는 데도 도움이 됩니다.
+ 센서의 데이터를 적절한 감지기 인스턴스로 라우팅하는 데 `'areaId'`가 사용됩니다. 감지기 인스턴스는 모든 메시지에서 `'areaId'` 수신된 각 고유에 대해 생성됩니다. `'areaDetectorModel'` 정의의 `'key'` 필드를 참조하십시오.

# AWS IoT Events 감지기 모델 정의 생성
<a name="iotevents-commented-example-detector-model"></a>

`'areaDetectorModel'` 예제에는 주석이 인라인으로 되어 있습니다.

CLI 명령:

```
aws iotevents create-detector-model --cli-input-json file://areaDetectorModel.json
```

파일: `areaDetectorModel.json`

```
{
  "detectorModelName": "areaDetectorModel",
  "detectorModelDefinition": {
    "states": [
      {
        "stateName": "start",
        // In the 'start' state we set up the operation parameters of the new detector instance. 
        //   We get here when the first input message arrives. If that is a 'seedTemperatureInput' 
        //   message, we save the operation parameters, then transition to the 'idle' state. If 
        //   the first message is a 'temperatureInput', we wait here until we get a 
        //   'seedTemperatureInput' input to ensure our operation parameters are set. We can 
        //   also reenter this state using the 'BatchUpdateDetector' API. This enables us to
        //   reset the operation parameters without needing to delete the detector instance.
        "onEnter": {
          "events": [
            {
              "eventName": "prepare",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    // initialize 'sensorId' to an invalid value (0) until an actual sensor reading 
                    //   arrives
                    "variableName": "sensorId",
                    "value": "0"
                  }
                },
                {
                  "setVariable": {
                    // initialize 'reportedTemperature' to an invalid value (0.1) until an actual 
                    //   sensor reading arrives
                    "variableName": "reportedTemperature",
                    "value": "0.1"
                  }
                },
                {
                  "setVariable": {
                    // When using 'BatchUpdateDetector' to re-enter this state, this variable should 
                    //   be set to true.
                    "variableName": "resetMe",
                    "value": "false"
                  }
                }
              ]
            }
          ]
        },
        "onInput": {
          "transitionEvents": [
            {
              "eventName": "initialize",
              "condition": "$input.seedTemperatureInput.sensorCount > 0",
              // When a 'seedTemperatureInput' message with a valid 'sensorCount' is received,
              //   we use it to set the operational parameters for the area to be monitored.
              "actions": [
                { 
                  "setVariable": {
                    "variableName": "rangeHigh",
                    "value": "$input.seedTemperatureInput.rangeHigh"
                  }
                },
                { 
                  "setVariable": {
                    "variableName": "rangeLow",
                    "value": "$input.seedTemperatureInput.rangeLow"
                  }
                },
                { 
                  "setVariable": {
                    "variableName": "desiredTemperature",
                    "value": "$input.seedTemperatureInput.desiredTemperature"
                  }
                },
                { 
                  "setVariable": {
                    // Assume we're at the desired temperature when we start.
                    "variableName": "averageTemperature",
                    "value": "$input.seedTemperatureInput.desiredTemperature"
                  }
                },
                { 
                  "setVariable": {
                    "variableName": "allowedError",
                    "value": "$input.seedTemperatureInput.allowedError"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "anomalousHigh",
                    "value": "$input.seedTemperatureInput.anomalousHigh"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "anomalousLow",
                    "value": "$input.seedTemperatureInput.anomalousLow"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "sensorCount",
                    "value": "$input.seedTemperatureInput.sensorCount"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "noDelay",
                    "value": "$input.seedTemperatureInput.noDelay == true"
                  }
                }
              ],
              "nextState": "idle"
            },
            {
              "eventName": "reset",
              "condition": "($variable.resetMe == true) && ($input.temperatureInput.sensorData.temperature < $variable.anomalousHigh && $input.temperatureInput.sensorData.temperature > $variable.anomalousLow)",
              // This event is triggered if we have reentered the 'start' state using the 
              //   'BatchUpdateDetector' API with 'resetMe' set to true. When we reenter using
              //   'BatchUpdateDetector' we do not automatically continue to the 'idle' state, but
              //   wait in 'start' until the next input message arrives. This event enables us to 
              //   transition to 'idle' on the next valid 'temperatureInput' message that arrives.
              "actions": [
                {
                  "setVariable": {
                    "variableName": "averageTemperature",
                    "value": "((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount)"
                  }
                }
              ],
              "nextState": "idle"
            }
          ]
        },
        "onExit": {
          "events": [
            {
              "eventName": "resetHeatCool",
              "condition": "true",
              // Make sure the heating and cooling units are off before entering 'idle'.
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOff"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOff"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/Off"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/Off"
                  }
                }
              ]
            }
          ]
        }
      },


      {
        "stateName": "idle",
        "onInput": {
          "events": [
            {
              "eventName": "whatWasInput",
              "condition": "true",
              // By storing the 'sensorId' and the 'temperature' in variables, we make them 
              //   available in any messages we send out to report anomalies, spikes, or just
              //   if needed for debugging.
              "actions": [
                {
                  "setVariable": {
                    "variableName": "sensorId",
                    "value": "$input.temperatureInput.sensorId"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "reportedTemperature",
                    "value": "$input.temperatureInput.sensorData.temperature"
                  }
                }
              ]
            },
            {
              "eventName": "changeDesired",
              "condition": "$input.seedTemperatureInput.desiredTemperature != $variable.desiredTemperature",
              // This event enables us to change the desired temperature at any time by sending a
              //   'seedTemperatureInput' message. But note that other operational parameters are not
              //   read or changed.
              "actions": [
                { 
                  "setVariable": {
                    "variableName": "desiredTemperature",
                    "value": "$input.seedTemperatureInput.desiredTemperature"
                  }
                }
              ]
            },
            {
              "eventName": "calculateAverage",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.anomalousHigh && $input.temperatureInput.sensorData.temperature > $variable.anomalousLow",
              // If a valid temperature reading arrives, we use it to update the average temperature.
              //   For simplicity, we assume our sensors will be sending updates at about the same rate,
              //   so we can calculate an approximate average by giving equal weight to each reading we receive.
              "actions": [
                {
                  "setVariable": {
                    "variableName": "averageTemperature",
                    "value": "((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount)"
                  }
                }
              ]
            }
          ],
          "transitionEvents": [
            {
              "eventName": "anomalousInputArrived",
              "condition": "$input.temperatureInput.sensorData.temperature >= $variable.anomalousHigh || $input.temperatureInput.sensorData.temperature <= $variable.anomalousLow",
              // When an anomalous reading arrives, send an MQTT message, but stay in the current state.
              "actions": [
                { 
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/anomaly"
                  }
                }
              ],
              "nextState": "idle"
            },

            {
              "eventName": "highTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature > $variable.rangeHigh",
              // When even a single temperature reading arrives that is above the 'rangeHigh', take
              //   emergency action to begin cooling, and report a high temperature spike.
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/On"
                  }
                },
                {
                  "setVariable": {
                    // This is necessary because we want to set a timer to delay the shutoff
                    //   of a cooling/heating unit, but we only want to set the timer when we 
                    //   enter that new state initially.
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "cooling"
            },

            {
              "eventName": "lowTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.rangeLow",
              // When even a single temperature reading arrives that is below the 'rangeLow', take
              //   emergency action to begin heating, and report a low-temperature spike.
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/On"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "heating"
            },

            {
              "eventName": "highTemperatureThreshold",
              "condition": "(((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount) > ($variable.desiredTemperature + $variable.allowedError))",
              // When the average temperature is above the desired temperature plus the allowed error factor,
              //   it is time to start cooling. Note that we calculate the average temperature here again
              //   because the value stored in the 'averageTemperature' variable is not yet available for use
              //   in our condition.
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/On"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "cooling"
            },

            {
              "eventName": "lowTemperatureThreshold",
              "condition": "(((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount) < ($variable.desiredTemperature - $variable.allowedError))",
              // When the average temperature is below the desired temperature minus the allowed error factor,
              //   it is time to start heating. Note that we calculate the average temperature here again
              //   because the value stored in the 'averageTemperature' variable is not yet available for use
              //   in our condition.
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/On"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "heating"
            }
          ]
        }
      },


      {
        "stateName": "cooling",
        "onEnter": {
          "events": [
            {
              "eventName": "delay",
              "condition": "!$variable.noDelay && $variable.enteringNewState",
              // If the operational parameters specify that there should be a minimum time that the 
              //   heating and cooling units should be run before being shut off again, we set
              //   a timer to ensure the proper operation here.
              "actions": [
                {
                  "setTimer": {
                    "timerName": "coolingTimer",
                    "seconds": 180
                  }
                },
                {
                  "setVariable": {
                    // We use this 'goodToGo' variable to store the status of the timer expiration 
                    //   for use in conditions that also use input variable values. If 
                    //   'timeout()' is used in such mixed conditionals, its value is lost.
                    "variableName": "goodToGo",
                    "value": "false"
                  }
                }
              ]
            },
            {
              "eventName": "dontDelay",
              "condition": "$variable.noDelay == true",
              // If the heating/cooling unit shutoff delay is not used, no need to wait.
              "actions": [
                {
                  "setVariable": {
                    "variableName": "goodToGo",
                    "value": "true"
                  }
                }
              ]
            },
            {
              "eventName": "beenHere",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "false"
                  }
                }
              ]
            }
          ]
        },

        "onInput": {
          "events": [
            // These are events that occur when an input is received (if the condition is
            //   satisfied), but don't cause a transition to another state.
            {
              "eventName": "whatWasInput",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "sensorId",
                    "value": "$input.temperatureInput.sensorId"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "reportedTemperature",
                    "value": "$input.temperatureInput.sensorData.temperature"
                  }
                }
              ]
            },
            {
              "eventName": "changeDesired",
              "condition": "$input.seedTemperatureInput.desiredTemperature != $variable.desiredTemperature",
              "actions": [
                { 
                  "setVariable": {
                    "variableName": "desiredTemperature",
                    "value": "$input.seedTemperatureInput.desiredTemperature"
                  }
                }
              ]
            },
            {
              "eventName": "calculateAverage",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.anomalousHigh && $input.temperatureInput.sensorData.temperature > $variable.anomalousLow",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "averageTemperature",
                    "value": "((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount)"
                  }
                }
              ]
            },
            {
              "eventName": "areWeThereYet",
              "condition": "(timeout(\"coolingTimer\"))",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "goodToGo",
                    "value": "true"
                  }
                }
              ]
            }
          ],
          "transitionEvents": [
            // Note that some tests of temperature values (for example, the test for an anomalous value) 
            //   must be placed here in the 'transitionEvents' because they work together with the tests 
            //   in the other conditions to ensure that we implement the proper "if..elseif..else" logic. 
            //   But each transition event must have a destination state ('nextState'), and even if that 
            //   is actually the current state, the "onEnter" events for this state will be executed again.
            //   This is the reason for the 'enteringNewState' variable and related.
            {
              "eventName": "anomalousInputArrived",
              "condition": "$input.temperatureInput.sensorData.temperature >= $variable.anomalousHigh || $input.temperatureInput.sensorData.temperature <= $variable.anomalousLow",
              "actions": [
                { 
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/anomaly"
                  }
                }
              ],
              "nextState": "cooling"
            },

            {
              "eventName": "highTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature > $variable.rangeHigh",
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                }
              ],
              "nextState": "cooling"
            },

            {
              "eventName": "lowTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.rangeLow",
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOff"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/Off"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/On"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "heating"
            },

            {
              "eventName": "desiredTemperature",
              "condition": "(((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount) <= ($variable.desiredTemperature - $variable.allowedError)) && $variable.goodToGo == true",
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOff"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/Off"
                  }
                }
              ],
              "nextState": "idle"
            }
          ]
        }
      },


      {
        "stateName": "heating",
        "onEnter": {
          "events": [
            {
              "eventName": "delay",
              "condition": "!$variable.noDelay && $variable.enteringNewState",
              "actions": [
                {
                  "setTimer": {
                    "timerName": "heatingTimer",
                    "seconds": 120
                  }
                },
                {
                  "setVariable": {
                    "variableName": "goodToGo",
                    "value": "false"
                  }
                }
              ]
            },
            {
              "eventName": "dontDelay",
              "condition": "$variable.noDelay == true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "goodToGo",
                    "value": "true"
                  }
                }
              ]
            },
            {
              "eventName": "beenHere",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "false"
                  }
                }
              ]
            }
          ]
        },

        "onInput": {
          "events": [
            {
              "eventName": "whatWasInput",
              "condition": "true",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "sensorId",
                    "value": "$input.temperatureInput.sensorId"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "reportedTemperature",
                    "value": "$input.temperatureInput.sensorData.temperature"
                  }
                }
              ]
            },
            {
              "eventName": "changeDesired",
              "condition": "$input.seedTemperatureInput.desiredTemperature != $variable.desiredTemperature",
              "actions": [
                { 
                  "setVariable": {
                    "variableName": "desiredTemperature",
                    "value": "$input.seedTemperatureInput.desiredTemperature"
                  }
                }
              ]
            },
            {
              "eventName": "calculateAverage",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.anomalousHigh && $input.temperatureInput.sensorData.temperature > $variable.anomalousLow",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "averageTemperature",
                    "value": "((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount)"
                  }
                }
              ]
            },
            {
              "eventName": "areWeThereYet",
              "condition": "(timeout(\"heatingTimer\"))",
              "actions": [
                {
                  "setVariable": {
                    "variableName": "goodToGo",
                    "value": "true"
                  }
                }
              ]
            }
          ],
          "transitionEvents": [
            {
              "eventName": "anomalousInputArrived",
              "condition": "$input.temperatureInput.sensorData.temperature >= $variable.anomalousHigh || $input.temperatureInput.sensorData.temperature <= $variable.anomalousLow",
              "actions": [
                { 
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/anomaly"
                  }
                }
              ],
              "nextState": "heating"
            },

            {
              "eventName": "highTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature > $variable.rangeHigh",
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOff"
                  }
                },
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:coolOn"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/Off"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Cooling/On"
                  }
                },
                {
                  "setVariable": {
                    "variableName": "enteringNewState",
                    "value": "true"
                  }
                }
              ],
              "nextState": "cooling"
            },

            {
              "eventName": "lowTemperatureSpike",
              "condition": "$input.temperatureInput.sensorData.temperature < $variable.rangeLow",
              "actions": [
                {
                  "iotTopicPublish": {
                    "mqttTopic": "temperatureSensor/spike"
                  }
                }
              ],
              "nextState": "heating"
            },

            {
              "eventName": "desiredTemperature",
              "condition": "(((($variable.averageTemperature * ($variable.sensorCount - 1)) + $input.temperatureInput.sensorData.temperature) / $variable.sensorCount) >= ($variable.desiredTemperature + $variable.allowedError)) && $variable.goodToGo == true",
              "actions": [
                {
                  "sns": {
                    "targetArn": "arn:aws:sns:us-west-2:123456789012:heatOff"
                  }
                },
                {
                  "iotTopicPublish": {
                    "mqttTopic": "hvac/Heating/Off"
                  }
                }
              ],
              "nextState": "idle"
            }
          ]
        }
      } 

    ],

    "initialStateName": "start"
  },
  "key": "areaId",
  "roleArn": "arn:aws:iam::123456789012:role/IoTEventsRole" 
}
```

응답:

```
{
    "detectorModelConfiguration": {
        "status": "ACTIVATING", 
        "lastUpdateTime": 1557523491.168, 
        "roleArn": "arn:aws:iam::123456789012:role/IoTEventsRole", 
        "creationTime": 1557523491.168, 
        "detectorModelArn": "arn:aws:iotevents:us-west-2:123456789012:detectorModel/areaDetectorModel", 
        "key": "areaId", 
        "detectorModelName": "areaDetectorModel", 
        "detectorModelVersion": "1"
    }
}
```

# BatchUpdateDetector를 사용하여 AWS IoT Events 감지기 모델 업데이트
<a name="iotevents-commented-example-batch-update-detector"></a>

`BatchUpdateDetector` 작업을 사용하여 타이머 및 변수 값을 포함하여 감지기 인스턴스를 알려진 상태로 만들 수 있습니다. 다음 예제에서 `BatchUpdateDetector` 작업은 온도 모니터링 및 제어 중인 영역의 작동 파라미터를 재설정합니다. 이 작업을 통해 감지기 모델을 삭제, 재생성 또는 업데이트할 필요 없이 이를 수행할 수 있습니다.

CLI 명령:

```
aws iotevents-data batch-update-detector --cli-input-json file://areaDM.BUD.json
```

파일: `areaDM.BUD.json`

```
{
  "detectors": [
    {
      "messageId": "0001",
      "detectorModelName": "areaDetectorModel",
      "keyValue": "Area51",
      "state": {
        "stateName": "start",
        "variables": [
          {
            "name": "desiredTemperature",
            "value": "22"
          },
          {
            "name": "averageTemperature",
            "value": "22"
          },
          {
            "name": "allowedError",
            "value": "1.0"
          },
          {
            "name": "rangeHigh",
            "value": "30.0"
          },
          {
            "name": "rangeLow",
            "value": "15.0"
          },
          {
            "name": "anomalousHigh",
            "value": "60.0"
          },
          {
            "name": "anomalousLow",
            "value": "0.0"
          },
          {
            "name": "sensorCount",
            "value": "12"
          },
          {
            "name": "noDelay",
            "value": "true"
          },
          {
            "name": "goodToGo",
            "value": "true"
          },
          {
            "name": "sensorId",
            "value": "0"
          },
          {
            "name": "reportedTemperature",
            "value": "0.1"
          },
          {
            "name": "resetMe",
            // When 'resetMe' is true, our detector model knows that we have reentered the 'start' state
            //   to reset operational parameters, and will allow the next valid temperature sensor
            //   reading to cause the transition to the 'idle' state.
            "value": "true"
          }
        ],
        "timers": [
        ]
      }
    }
  ]
}
```

응답:

```
{
    "batchUpdateDetectorErrorEntries": []
}
```

# 의 입력에 BatchPutMessage 사용 AWS IoT Events
<a name="iotevents-commented-example-input-usage-examples"></a>

**Example 1**  
`BatchPutMessage` 작업을 사용하여 온도 제어 및 모니터링 중인 특정 영역에 대한 작동 파라미터를 설정하는 `"seedTemperatureInput"` 메시지를 보낼 수 있습니다. 새가 AWS IoT Events 있는에서 수신한 모든 메시지로 `"areaId"` 인해 새 감지기 인스턴스가 생성됩니다. 하지만 새 감지기 인스턴스는 새로운 구역에 대한 `"seedTemperatureInput"` 메시지가 수신될 때까지 `"idle"`로 상태를 변경하거나 온도 모니터링과 난방 또는 냉방 장치 제어를 시작하지 않습니다.  
CLI 명령:  

```
aws iotevents-data batch-put-message --cli-input-json file://seedExample.json --cli-binary-format raw-in-base64-out
```
파일: `seedExample.json`  

```
{
  "messages": [
    {
      "messageId": "00001",
      "inputName": "seedTemperatureInput",
      "payload": "{\"areaId\": \"Area51\", \"desiredTemperature\": 20.0, \"allowedError\": 0.7, \"rangeHigh\": 30.0, \"rangeLow\": 15.0, \"anomalousHigh\": 60.0, \"anomalousLow\": 0.0, \"sensorCount\": 10, \"noDelay\": false}"
    }
  ]
}
```
응답:  

```
{
    "BatchPutMessageErrorEntries": []
}
```

**Example**  
2  
`BatchPutMessage` 작업을 통해 `"temperatureInput"` 메시지를 전송하여 지정된 제어 및 모니터링 영역에 있는 센서의 온도 센서 데이터를 보고할 수 있습니다.  
CLI 명령:  

```
aws iotevents-data batch-put-message --cli-input-json file://temperatureExample.json --cli-binary-format raw-in-base64-out
```
파일: `temperatureExample.json`  

```
{
  "messages": [
    {
      "messageId": "00005",
      "inputName": "temperatureInput",
      "payload": "{\"sensorId\": \"05\", \"areaId\": \"Area51\", \"sensorData\": {\"temperature\": 23.12} }"
    }
  ]
}
```
응답:  

```
{
    "BatchPutMessageErrorEntries": []
}
```

**Example 3**  
`BatchPutMessage` 작업을 통해 `"seedTemperatureInput"` 메시지를 전송하여 주어진 구역에 대해 원하는 온도 값을 변경할 수 있습니다.  
CLI 명령:  

```
aws iotevents-data batch-put-message --cli-input-json file://seedSetDesiredTemp.json --cli-binary-format raw-in-base64-out
```
파일: `seedSetDesiredTemp.json`  

```
{
  "messages": [
    {
      "messageId": "00001",
      "inputName": "seedTemperatureInput",
      "payload": "{\"areaId\": \"Area51\", \"desiredTemperature\": 23.0}"
    }
  ]
}
```
응답:  

```
{
    "BatchPutMessageErrorEntries": []
}
```

# 에서 MQTT 메시지 수집 AWS IoT Events
<a name="iotevents-commented-example-ingest-mqtt"></a>

센서 컴퓨팅 리소스가 `"BatchPutMessage"` API를 사용할 수 없지만 경량 MQTT 클라이언트를 사용하여 AWS IoT Core 메시지 브로커로 데이터를 전송할 수 있는 경우 AWS IoT Core 주제 규칙을 생성하여 메시지 데이터를 AWS IoT Events 입력으로 리디렉션할 수 있습니다. 다음은 MQTT AWS IoT Events 주제의 `"areaId"` 및 `"sensorId"` 입력 필드와 메시지 페이로드 `"sensorData.temperature"` 필드의 `"temp"` 필드를 가져와이 데이터를 로 수집하는 주제 규칙의 정의입니다 AWS IoT Events `"temperatureInput"`.

CLI 명령:

```
aws iot create-topic-rule --cli-input-json file://temperatureTopicRule.json
```

파일: `seedSetDesiredTemp.json`

```
{
  "ruleName": "temperatureTopicRule",
  "topicRulePayload": {
    "sql": "SELECT topic(3) as areaId, topic(4) as sensorId, temp as sensorData.temperature FROM 'update/temperature/#'",
    "description": "Ingest temperature sensor messages into IoT Events",
    "actions": [
      {
        "iotEvents": {
          "inputName": "temperatureInput",
          "roleArn": "arn:aws:iam::123456789012:role/service-role/anotheRole" 
        }
      }
    ],
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23"
  }
}
```

응답: [없음]

센서가 다음 페이로드와 함께 주제 `"update/temperature/Area51/03"`에 대한 메시지를 보내는 경우.

```
{ "temp": 24.5 }
```

이렇게 하면 다음 `"BatchPutMessage"` API 호출이 이루어진 AWS IoT Events 것처럼 데이터가에 수집됩니다.

```
aws iotevents-data batch-put-message --cli-input-json file://spoofExample.json --cli-binary-format raw-in-base64-out
```

파일: `spoofExample.json`

```
{
  "messages": [
    {
      "messageId": "54321",
      "inputName": "temperatureInput",
      "payload": "{\"sensorId\": \"03\", \"areaId\": \"Area51\", \"sensorData\": {\"temperature\": 24.5} }"
    }
  ]
}
```

# 에서 Amazon SNS 메시지 생성 AWS IoT Events
<a name="iotevents-commented-example-generated-sns"></a>

다음은 `"Area51"` 감지기 인스턴스에서 생성된 SNS 메시지의 예입니다.

AWS IoT Events 는 Amazon SNS와 통합하여 감지된 이벤트를 기반으로 알림을 생성하고 게시할 수 있습니다. 이 섹션에서는 AWS IoT Events 감지기 인스턴스, 특히 "Area51" 감지기가 Amazon SNS 메시지를 생성하는 방법을 보여줍니다. 이 예제에서는 AWS IoT Events 감지기 내의 다양한 상태 및 이벤트에 의해 트리거되는 Amazon SNS 알림의 구조와 콘텐츠를 보여 주며, 실시간 알림 및 통신을 위해 Amazon SNS AWS IoT Events 와를 결합하는 기능을 보여줍니다.

```
Heating system off command> {
  "eventTime":1557520274729,
  "payload":{
    "actionExecutionId":"f3159081-bac3-38a4-96f7-74af0940d0a4",
    "detector":{
      "detectorModelName":"areaDetectorModel","keyValue":"Area51","detectorModelVersion":"1"},"eventTriggerDetails":{"inputName":"seedTemperatureInput","messageId":"00001","triggerType":"Message"},"state":{"stateName":"start","variables":{"sensorCount":10,"rangeHigh":30.0,"resetMe":false,"enteringNewState":true,"averageTemperature":20.0,"rangeLow":15.0,"noDelay":false,"allowedError":0.7,"desiredTemperature":20.0,"anomalousHigh":60.0,"reportedTemperature":0.1,"anomalousLow":0.0,"sensorId":0},"timers":{}}},"eventName":"resetHeatCool"}
```

```
Cooling system off command> {"eventTime":1557520274729,"payload":{"actionExecutionId":"98f6a1b5-8f40-3cdb-9256-93afd4d66192","detector":{"detectorModelName":"areaDetectorModel","keyValue":"Area51","detectorModelVersion":"1"},"eventTriggerDetails":{"inputName":"seedTemperatureInput","messageId":"00001","triggerType":"Message"},"state":{"stateName":"start","variables":{"sensorCount":10,"rangeHigh":30.0,"resetMe":false,"enteringNewState":true,"averageTemperature":20.0,"rangeLow":15.0,"noDelay":false,"allowedError":0.7,"desiredTemperature":20.0,"anomalousHigh":60.0,"reportedTemperature":0.1,"anomalousLow":0.0,"sensorId":0},"timers":{}}},"eventName":"resetHeatCool"}
```

# 에서 DescribeDetector API 구성 AWS IoT Events
<a name="iotevents-commented-example-describe-detector"></a>

의 `DescribeDetector` API AWS IoT Events 를 사용하면 특정 감지기 인스턴스에 대한 세부 정보를 검색할 수 있습니다. 이 작업은 감지기의 현재 상태, 변수 값 및 활성 타이머에 대한 인사이트를 제공합니다. 이 API를 사용하면 AWS IoT Events 탐지기의 실시간 상태를 모니터링하여 IoT 이벤트 처리 워크플로의 디버깅, 분석 및 관리를 용이하게 할 수 있습니다.

CLI 명령:

```
aws iotevents-data describe-detector --detector-model-name areaDetectorModel --key-value Area51
```

응답:

```
{
    "detector": {
        "lastUpdateTime": 1557521572.216, 
        "creationTime": 1557520274.405, 
        "state": {
            "variables": [
                {
                    "name": "resetMe", 
                    "value": "false"
                }, 
                {
                    "name": "rangeLow", 
                    "value": "15.0"
                }, 
                {
                    "name": "noDelay", 
                    "value": "false"
                }, 
                {
                    "name": "desiredTemperature", 
                    "value": "20.0"
                }, 
                {
                    "name": "anomalousLow", 
                    "value": "0.0"
                }, 
                {
                    "name": "sensorId", 
                    "value": "\"01\""
                }, 
                {
                    "name": "sensorCount", 
                    "value": "10"
                }, 
                {
                    "name": "rangeHigh", 
                    "value": "30.0"
                }, 
                {
                    "name": "enteringNewState", 
                    "value": "false"
                }, 
                {
                    "name": "averageTemperature", 
                    "value": "19.572"
                }, 
                {
                    "name": "allowedError", 
                    "value": "0.7"
                }, 
                {
                    "name": "anomalousHigh", 
                    "value": "60.0"
                }, 
                {
                    "name": "reportedTemperature", 
                    "value": "15.72"
                }, 
                {
                    "name": "goodToGo", 
                    "value": "false"
                }
            ], 
            "stateName": "idle", 
            "timers": [
                {
                    "timestamp": 1557520454.0, 
                    "name": "idleTimer"
                }
            ]
        }, 
        "keyValue": "Area51", 
        "detectorModelName": "areaDetectorModel", 
        "detectorModelVersion": "1"
    }
}
```

# 에 규칙 AWS IoT Core 엔진 사용 AWS IoT Events
<a name="iotevents-commented-examples-iot-rules-examples"></a>

다음 규칙은 AWS IoT Core MQTT 메시지를 섀도우 업데이트 요청 메시지로 다시 게시합니다. 감지기 모델에 의해 제어되는 각 영역의 난방 장치 및 냉각 장치에 AWS IoT Core 사물이 정의되어 있다고 가정합니다. 이 예제에서는 이름이 `"Area51HeatingUnit"` 및 `"Area51CoolingUnit"`인 항목을 정의했습니다.

CLI 명령:

```
aws iot create-topic-rule --cli-input-json file://ADMShadowCoolOffRule.json
```

파일: `ADMShadowCoolOffRule.json`

```
{
  "ruleName": "ADMShadowCoolOff",
  "topicRulePayload": {
    "sql": "SELECT topic(3) as state.desired.command FROM 'hvac/Cooling/Off'",
    "description": "areaDetectorModel mqtt topic publish to cooling unit shadow request",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
      {
        "republish": {
          "topic": "$$aws/things/${payload.detector.keyValue}CoolingUnit/shadow/update",
          "roleArn": "arn:aws:iam::123456789012:role/service-role/ADMShadowRole" 
        }
      }
    ]
  }
}
```

응답: [비어 있음]

CLI 명령:

```
aws iot create-topic-rule --cli-input-json file://ADMShadowCoolOnRule.json
```

파일: `ADMShadowCoolOnRule.json`

```
{
  "ruleName": "ADMShadowCoolOn",
  "topicRulePayload": {
    "sql": "SELECT topic(3) as state.desired.command FROM 'hvac/Cooling/On'",
    "description": "areaDetectorModel mqtt topic publish to cooling unit shadow request",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
      {
        "republish": {
          "topic": "$$aws/things/${payload.detector.keyValue}CoolingUnit/shadow/update",
          "roleArn": "arn:aws:iam::123456789012:role/service-role/ADMShadowRole" 
        }
      }
    ]
  }
}
```

응답: [비어 있음]

CLI 명령:

```
aws iot create-topic-rule --cli-input-json file://ADMShadowHeatOffRule.json
```

파일: `ADMShadowHeatOffRule.json`

```
{
  "ruleName": "ADMShadowHeatOff",
  "topicRulePayload": {
    "sql": "SELECT topic(3) as state.desired.command FROM 'hvac/Heating/Off'",
    "description": "areaDetectorModel mqtt topic publish to heating unit shadow request",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
      {
        "republish": {
          "topic": "$$aws/things/${payload.detector.keyValue}HeatingUnit/shadow/update",
          "roleArn": "arn:aws:iam::123456789012:role/service-role/ADMShadowRole" 
        }
      }
    ]
  }
}
```

응답: [비어 있음]

CLI 명령:

```
aws iot create-topic-rule --cli-input-json file://ADMShadowHeatOnRule.json
```

파일: `ADMShadowHeatOnRule.json`

```
{
  "ruleName": "ADMShadowHeatOn",
  "topicRulePayload": {
    "sql": "SELECT topic(3) as state.desired.command FROM 'hvac/Heating/On'",
    "description": "areaDetectorModel mqtt topic publish to heating unit shadow request",
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23",
    "actions": [
      {
        "republish": {
          "topic": "$$aws/things/${payload.detector.keyValue}HeatingUnit/shadow/update",
          "roleArn": "arn:aws:iam::123456789012:role/service-role/ADMShadowRole" 
        }
      }
    ]
  }
}
```

응답: [비어 있음]