本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
备注示例:暖通空调温度控制
以下是含内联注释(使 JSON 无效)的 JSON 文件示例 这些示例的完整版本(无注释)可见HVAC 温度控制。
背景
此示例实现了一个恒温器控制模型,该模型使您能够执行以下操作。
-
仅定义一个可用于监视和控制多个区域的检测程序模型。为每个区域创建一个检测程序实例。
-
从每个控制区域的多个传感器摄取温度数据。
-
更改某个区域的温度设定点。
-
为每个区域设定操作参数,并在使用实例时重置这些参数。
-
动态地添加或删除某个区域的传感器。
-
指定最短运行时间以供暖和制冷装置。
-
拒绝异常传感器读数。
-
定义紧急设定点,如果任何传感器报告的温度高于或低于给定阈值,该设定点会立即启动供暖或制冷。
-
报告异常读数及温度峰值。
输入定义
我们想创建一个检测程序模型,可用于监测和控制多个不同区域的温度。每个区域可以有多个温度报告传感器。我们假定每个区域均配备一台供暖装置和一台制冷装置,其可以打开或关闭以控制该区域的温度。每个区域都由检测程序实例控制。
由于我们监视和控制的不同区域可能具有不同的特征,需要不同的控制参数,因此我们定义'seedTemperatureInput'
,以便为每个区域提供这些参数。当我们将其中一条输入消息发送至Amazon 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'
字段。 -
激活该区域的供暖或制冷装置前,平均温度可能与
'desiredTemperature'
不同,可能会相差'allowedError'
。 -
如果任何传感器报告的温度高于
'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'
字段。
检测程序模型定义
'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 示例
您可以使用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 示例
例 1
使用 BatchPutMessage
操作发送一条"seedTemperatureInput"
消息,为受温度控制和监视的给定区域设置操作参数。Amazon IoT Events收到的包含新"areaId"
的消息会导致创建新检测程序实例。但是,在收到新区域的"idle"
消息前,新的检测程序实例不会将状态更改为"seedTemperatureInput"
,也不会开始监视温度、控制供暖或制冷。
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": [] }
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": [] }
例 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 消息
如果传感器计算资源无法使用 "BatchPutMessage"
API,但可以使用轻量级 MQTT 客户端将其数据发送到 Amazon IoT Core 消息代理,则您可以创建一个 Amazon IoT Core 主题规则,以将消息数据重定向至 Amazon IoT Events 输入。以下是对 Amazon IoT Events 主题规则的定义,该规则采用 MQTT 主题中的"areaId"
和"sensorId"
输入字段,以及消息有效负载"sensorData.temperature"
字段中的"temp"
字段,并将这些数据摄提取至我们的Amazon IoT Events "temperatureInput"
。
如果传感器计算资源无法使用 "BatchPutMessage"
API,但可以使用轻量级 MQTT 客户端将其数据发送到 Amazon IoT Core 消息代理,则您可以创建一个 Amazon IoT Core 主题规则,以将消息数据重定向至 Amazon IoT Events 输入。以下是对 Amazon IoT Events 主题规则的定义,该规则采用 MQTT 主题中的"areaId"
和"sensorId"
输入字段,以及消息有效负载"sensorData.temperature"
字段中的"temp"
字段,并将这些数据摄提取至我们的Amazon 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 }
这会导致数据会被摄取到Amazon IoT Events 中,就像进行以下"BatchPutMessage"
API 调用一样。
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 消息
以下是 "Area51"
检测程序实例生成的 SNS 消息示例。
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
您可以使用 DescribeDetector
操作查看检测程序实例的当前状态、变量值和计时器。
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" } }
Amazon IoT Core 规则引擎示例
以下规则将 Amazon IoT Core MQTT 消息以影子更新请求消息的形式重新发布。我们假定已定义了检测程序模型控制的每个区域的供暖和制冷装置的Amazon 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" } } ] } }
响应:[空]