Skip to content

Zone state

Zones + GgEdgeLooptelemetry/+ · actuator/+
→
IoT rules…_telemetry_ddb · …_actuator_ddb
→
DynamoDBPK thing · SK kind
S3 keeps history. This table answers “what is each zone doing right now” — latest telemetry and who last drove actuator.

S3 keeps the history. DynamoDB answers the question “what is each zone doing right now”. Every rule writes with PutItem, using the zone as the partition key and the message kind as the sort key, so each new message overwrites the last one of the same kind.

thing (PK)

kind (SK)

Written byPage
zone Thing nametelemetry

Rule on gg-edge/telemetry/+

This page
zone Thing nameactuator

Rule on gg-edge/actuator/+

This page
zone Thing namecloud-ack

Rule on gg-edge/cloud/ack/+

Cloud commands
zone Thing nameinference

Rule on gg-edge/inference/+

Edge inference

The IoT rule
AWS IoT rule — SQL over an MQTT topic filter plus actions (S3, DynamoDB, CloudWatch, …). This is how IoT Core hands bridged Greengrass data to other AWS services.
dynamoDBv2 action writes each selected field as its own attribute (DynamoDBv2 action). The SQL must therefore produce the thing and kind keys itself.

Terminal window
set -a && source config/walkthrough.env && set +a
export GG_EDGE_ALLOW_AWS=1
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
RULE_PREFIX=$(echo "${PROJECT_NAME}_${ENVIRONMENT}" | tr '-' '_')
IOT_RULE_ROLE="${PROJECT_NAME}-${ENVIRONMENT}-iot-rules"
IOT_RULE_ROLE_ARN=$(aws iam get-role --role-name "$IOT_RULE_ROLE" --query Role.Arn --output text)
ZONE_TABLE="${ZONE_TABLE:-${PROJECT_NAME}-${ENVIRONMENT}-zone-state}"
echo "$ZONE_TABLE"
gg-edge-wt-dev-zone-state

The IoT rule role was created on Archive telemetry.

Terminal window
aws dynamodb create-table --table-name "$ZONE_TABLE" \
--attribute-definitions AttributeName=thing,AttributeType=S AttributeName=kind,AttributeType=S \
--key-schema AttributeName=thing,KeyType=HASH AttributeName=kind,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--query TableDescription.TableStatus --output text
aws dynamodb wait table-exists --table-name "$ZONE_TABLE"
CREATING
Terminal window
ZONE_TABLE_ARN=$(aws dynamodb describe-table --table-name "$ZONE_TABLE" \
--query Table.TableArn --output text)
sed "s|ZONE_TABLE_ARN|${ZONE_TABLE_ARN}|g" artifacts/policies/iot-rule-dynamodb.json \
> /tmp/iot-rule-dynamodb.json
aws iam put-role-policy --role-name "$IOT_RULE_ROLE" \
--policy-name iot-rule-dynamodb --policy-document file:///tmp/iot-rule-dynamodb.json
(no output)

telemetry-to-dynamodb.json and actuator-to-dynamodb.json take the zone name from topic(3), the third topic segment.

Terminal window
for r in telemetry actuator; do
sed -e "s|ZONE_TABLE|${ZONE_TABLE}|g" -e "s|IOT_RULE_ROLE_ARN|${IOT_RULE_ROLE_ARN}|g" \
"artifacts/iot-rules/${r}-to-dynamodb.json" > "/tmp/rule-${r}-ddb.json"
aws iot create-topic-rule --rule-name "${RULE_PREFIX}_${r}_ddb" \
--topic-rule-payload "file:///tmp/rule-${r}-ddb.json"
done
(no output)
Terminal window
sleep 15
aws dynamodb scan --table-name "$ZONE_TABLE" \
--filter-expression "#k = :k" --expression-attribute-names '{"#k":"kind"}' \
--expression-attribute-values '{":k":{"S":"telemetry"}}' \
--query "Items[].[thing.S,tempC.N,rssi.N,uptimeS.N,rgb.S]" --output table
----------------------------------------------------------
| Scan |
+-------------------------+-------+------+-------+-------+
| gg-edge-wt-dev-esp32-2 | 26.5 | -28 | 7053 | off |
| gg-edge-wt-dev-esp32-1 | 29.9 | -28 | 7053 | off |
+-------------------------+-------+------+-------+-------+

Keep each zone’s tempC. Raise an alarm sets its threshold relative to this baseline.

Press and release BOOT on esp32-1, then:

Terminal window
aws dynamodb get-item --table-name "$ZONE_TABLE" \
--key "{\"thing\":{\"S\":\"${CLIENT_THING_NAME}\"},\"kind\":{\"S\":\"actuator\"}}" \
--query "Item.{state:state.S,color:color.S,source:source.S}"
{
"state": "off",
"color": "green",
"source": "com.example.GgEdgeLoop"
}

off is the release. Holding the button while you run the command shows on. On the next pages the same item records source: cloud (blue) and source: com.example.ZoneAnomaly (red). One table holds the audit of which layer acted.

If actuator never appears but telemetry does, confirm the deployment has ActuatorPubsubToIotCore.

Next: Raise an alarm.