The shadow document for devices tracks state of local resources. In the case of the motor board, this is led
which maps to the second motor controller, which is not used. This give an indicator that things are working without having to activate the motor.
The led_ring
is the round ring and count
determine how many LED elements to light up, and the color is the RBG color for all active elements. Each of these below will always be in the desired state of the shadow and once online, in the reported state for the device.
{
"led_ring": {
"count": 0,
"color": "#RRGGBB"
},
"led": "on|off",
"dispense_time_ms": 2500,
}
There are also a temporary request and response objects used to track command state. The cloud logic will create the request object in the desired state section of the shadow, and once processed by the device, it will create the response object in the reported state section. Finally, cloud logic will reconcile and clean up the shadow document of any entries left.
Below are what the request and response objects should look like. The command
and requestId
attribute and values must match. For the request object, the timestamp
attribute is when the request was made, while in the response object it is when the dispenser completed the operation.
{
"desired": {
"request": {
"command": "dispense",
"requestId": "1234-5678",
"timestamp": 12345
}
},
"reported": {
"response": {
"command": "dispense",
"requestId": "1234-5678",
"result": "success",
"timestamp": 45678
}
},
}
The following sequence diagrams show the flows for different uses. The first flows are device-to-cloud, then Rules Engine actions, and then API generated flows.
Uses the device shadow to set the desired state of an LED. The unused motor controller’s associated LED can be set on
or off
, while the LED ring can be addressed with an RGB color and number of LEDs to light. All LED operations take place through the device shadow.
At creation, the LEDs are all set to a desired state of off. The dispenser hardware should read and honor the shadow settings for the LED.
In this flow:
$aws/things/123/shadow/delta
led
(LED for second motor controller)"led": "on"
is sent to the dispenserThis is the same flow for led1
and led_ring
. For led_ring
, the attributes are the amount of LEDs to light (0-5) and the RBG color in hex, e.g., #ff0000
for full red.
Uses the device’s shadow desired state to send a command (request) to the dispenser. After the dispenser has completed the operation, it updates the shadow’s reported state to acknowledge the request.
In this flow:
The response operation is decoupled from the request in that the dispenser may be in an offline state. Once online, the response flow continues:
$aws/things/shadow/123/delta
or $aws/things/shadow/123/update/accepted
result=ERROR
indicator (optional - if submitted no credits will be deducted)requestId
state.reported.response
objects and if found invokes the Lambda functionnull
) and request and response objects in the dispensers shadownull
) and request and response objects in the dispensers shadowThe Lambda will also clear out a stale dispense request. There can only be one in-flight dispense request in the dispenser’s record.
These flows are subscriptions made by the rules, and the actions they take.
The logging rule monitors all messages published to events
and events/#
, and invokes a Lambda to persist the events into the DynamoDB EventsTable.
There are three logging rules for the workshop, all which log events to the EventsTable. The LogShadowEvents rule monitors for shadow update documents, adds the topic which will identify the dispenser, then invokes the ProcessEvents Lambda function. Similarly for messages published to the events
and events/nnn
(dispenser ID) topics, the LogGenericEvents and LogDispenserEvents rules process the messages and invoke ProcessEvents.
The Lambda function parses the incoming details and creates the formatted entries that then published to the DynamoDB EventsTable.