Cranes
Background story
An operator of many cranes wants to detect when the machines need maintenance or replacement and trigger appropriate notifications. Each crane has a motor. A motor emits messages (inputs) with information about pressure and temperature. The operator wants two levels of event detectors:
-
A crane-level event detector
-
A motor-level event detector
Using messages from the motors (that contain metadata with both the "craneId"
and
the "motorId"
), the operator can execute both levels of event detectors using appropriate
routing. When event conditions are met, notifications should be sent to appropriate Amazon SNS topics.
The operator can configure the detector models so that duplicate notifications are not raised.
This example demonstrates the following functional capabilities:
-
Create, Read, Update, Delete (CRUD) of inputs.
-
Create, Read, Update, Delete (CRUD) of event detector models and different versions of event detectors.
-
Routing one input to multiple event detectors.
-
Ingestion of inputs into a detector model.
-
Evaluation of trigger conditions and lifecycle events.
-
Ability to refer to state variables in conditions and set their values depending on conditions.
-
Runtime orchestration with definition, state, trigger evaluator, and actions executor.
-
Execution of actions in
ActionsExecutor
with an SNS target.
Commands
#Create Pressure Input aws iotevents create-input --cli-input-json file://pressureInput.json aws iotevents describe-input --input-name PressureInput aws iotevents update-input --cli-input-json file://pressureInput.json aws iotevents list-inputs aws iotevents delete-input --input-name PressureInput #Create Temperature Input aws iotevents create-input --cli-input-json file://temperatureInput.json aws iotevents describe-input --input-name TemperatureInput aws iotevents update-input --cli-input-json file://temperatureInput.json aws iotevents list-inputs aws iotevents delete-input --input-name TemperatureInput #Create Motor Event Detector using pressure and temperature input aws iotevents create-detector-model --cli-input-json file://motorDetectorModel.json aws iotevents describe-detector-model --detector-model-name motorDetectorModel aws iotevents update-detector-model --cli-input-json file://updateMotorDetectorModel.json aws iotevents list-detector-models aws iotevents list-detector-model-versions --detector-model-name motorDetectorModel aws iotevents delete-detector-model --detector-model-name motorDetectorModel #Create Crane Event Detector using temperature input aws iotevents create-detector-model --cli-input-json file://craneDetectorModel.json aws iotevents describe-detector-model --detector-model-name craneDetectorModel aws iotevents update-detector-model --cli-input-json file://updateCraneDetectorModel.json aws iotevents list-detector-models aws iotevents list-detector-model-versions --detector-model-name craneDetectorModel aws iotevents delete-detector-model --detector-model-name craneDetectorModel #Replace craneIds sed -i '' "s/100008/100009/g" messages/* #Replace motorIds sed -i '' "s/200008/200009/g" messages/* #Send HighPressure message aws iotevents-data batch-put-message --cli-input-json file://messages/highPressureMessage.json --cli-binary-format raw-in-base64-out #Send HighTemperature message aws iotevents-data batch-put-message --cli-input-json file://messages/highTemperatureMessage.json --cli-binary-format raw-in-base64-out #Send LowPressure message aws iotevents-data batch-put-message --cli-input-json file://messages/lowPressureMessage.json --cli-binary-format raw-in-base64-out #Send LowTemperature message aws iotevents-data batch-put-message --cli-input-json file://messages/lowTemperatureMessage.json --cli-binary-format raw-in-base64-out
Detector models
File:
craneDetectorModel.json
{ "detectorModelName": "craneDetectorModel", "detectorModelDefinition": { "states": [ { "stateName": "Running", "onEnter": { "events": [ { "eventName": "init", "condition": "true", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "0" } } ] } ] }, "onInput": { "events": [ { "eventName": "Overheated", "condition": "$input.TemperatureInput.temperature > 35", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "$variable.craneThresholdBreached + 1" } } ] }, { "eventName": "Crane Threshold Breached", "condition": "$variable.craneThresholdBreached > 5", "actions": [ { "sns": { "targetArn": "arn:aws:sns:us-east-1:123456789012:CraneSNSTopic" } } ] }, { "eventName": "Underheated", "condition": "$input.TemperatureInput.temperature < 25", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "0" } } ] } ] } } ], "initialStateName": "Running" }, "key": "craneid", "roleArn": "arn:aws:iam::123456789012:role/columboSNSRole" }
To update an existing detector model. File: updateCraneDetectorModel.json
{ "detectorModelName": "craneDetectorModel", "detectorModelDefinition": { "states": [ { "stateName": "Running", "onEnter": { "events": [ { "eventName": "init", "condition": "true", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "0" } }, { "setVariable": { "variableName": "alarmRaised", "value": "'false'" } } ] } ] }, "onInput": { "events": [ { "eventName": "Overheated", "condition": "$input.TemperatureInput.temperature > 30", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "$variable.craneThresholdBreached + 1" } } ] }, { "eventName": "Crane Threshold Breached", "condition": "$variable.craneThresholdBreached > 5 && $variable.alarmRaised == 'false'", "actions": [ { "sns": { "targetArn": "arn:aws:sns:us-east-1:123456789012:CraneSNSTopic" } }, { "setVariable": { "variableName": "alarmRaised", "value": "'true'" } } ] }, { "eventName": "Underheated", "condition": "$input.TemperatureInput.temperature < 10", "actions": [ { "setVariable": { "variableName": "craneThresholdBreached", "value": "0" } } ] } ] } } ], "initialStateName": "Running" }, "roleArn": "arn:aws:iam::123456789012:role/columboSNSRole" }
File:
motorDetectorModel.json
{ "detectorModelName": "motorDetectorModel", "detectorModelDefinition": { "states": [ { "stateName": "Running", "onEnter": { "events": [ { "eventName": "init", "condition": "true", "actions": [ { "setVariable": { "variableName": "motorThresholdBreached", "value": "0" } } ] } ] }, "onInput": { "events": [ { "eventName": "Overheated And Overpressurized", "condition": "$input.PressureInput.pressure > 70 && $input.TemperatureInput.temperature > 30", "actions": [ { "setVariable": { "variableName": "motorThresholdBreached", "value": "$variable.motorThresholdBreached + 1" } } ] }, { "eventName": "Motor Threshold Breached", "condition": "$variable.motorThresholdBreached > 5", "actions": [ { "sns": { "targetArn": "arn:aws:sns:us-east-1:123456789012:MotorSNSTopic" } } ] } ] } } ], "initialStateName": "Running" }, "key": "motorid", "roleArn": "arn:aws:iam::123456789012:role/columboSNSRole" }
To update an existing detector model. File: updateMotorDetectorModel.json
{ "detectorModelName": "motorDetectorModel", "detectorModelDefinition": { "states": [ { "stateName": "Running", "onEnter": { "events": [ { "eventName": "init", "condition": "true", "actions": [ { "setVariable": { "variableName": "motorThresholdBreached", "value": "0" } } ] } ] }, "onInput": { "events": [ { "eventName": "Overheated And Overpressurized", "condition": "$input.PressureInput.pressure > 70 && $input.TemperatureInput.temperature > 30", "actions": [ { "setVariable": { "variableName": "motorThresholdBreached", "value": "$variable.motorThresholdBreached + 1" } } ] }, { "eventName": "Motor Threshold Breached", "condition": "$variable.motorThresholdBreached > 5", "actions": [ { "sns": { "targetArn": "arn:aws:sns:us-east-1:123456789012:MotorSNSTopic" } } ] } ] } } ], "initialStateName": "Running" }, "roleArn": "arn:aws:iam::123456789012:role/columboSNSRole" }
Inputs
File:
pressureInput.json
{ "inputName": "PressureInput", "inputDescription": "this is a pressure input description", "inputDefinition": { "attributes": [ {"jsonPath": "pressure"} ] } }
File:
temperatureInput.json
{ "inputName": "TemperatureInput", "inputDescription": "this is temperature input description", "inputDefinition": { "attributes": [ {"jsonPath": "temperature"} ] } }
Messages
File:
highPressureMessage.json
{ "messages": [ { "messageId": "1", "inputName": "PressureInput", "payload": "{\"craneid\": \"100009\", \"pressure\": 80, \"motorid\": \"200009\"}" } ] }
File:
highTemperatureMessage.json
{ "messages": [ { "messageId": "2", "inputName": "TemperatureInput", "payload": "{\"craneid\": \"100009\", \"temperature\": 40, \"motorid\": \"200009\"}" } ] }
File:
lowPressureMessage.json
{ "messages": [ { "messageId": "1", "inputName": "PressureInput", "payload": "{\"craneid\": \"100009\", \"pressure\": 20, \"motorid\": \"200009\"}" } ] }
File:
lowTemperatureMessage.json
{ "messages": [ { "messageId": "2", "inputName": "TemperatureInput", "payload": "{\"craneid\": \"100009\", \"temperature\": 20, \"motorid\": \"200009\"}" } ] }