Accessing shadow documents on AWS Greengrass

AWS Greengrass is an amazing product bringing AWS IoT to the edge but also cloud development tools and the Lambda execution environment. This is going to be one of many short posts giving tips on using AWS Greengrass and accessing some of the basic functionality.

What are Device Shadows

If you’re worked with AWS IoT Core before you’ll know that shadows are copies of the state information for a device. They are extremely useful for tracking the status of devices without actually having to query a device directly. They are also critical in all command and control situations allowing us to change state in a deterministic fashion.

Shadows on AWS Greengrass

With AWS Greengrass you can have local shadows and those can also be synchronized with the cloud so that devices or systems that are remote or cloud based can still access and change shadow information.

So how to we access these shadow documents within our Lambda functions on the core? There is an SDK for the core that you deploy as part of your Lambda function however, it is not obvious how to actually get a shadow and more importantly, that the shadow data is actually double stringified! This is a common pattern with AWS, payloads are JSON stringified but so is the actual response object from a query.

Here is a short code snippet that fetches the shadow in Python:

client = greengrasssdk.client('iot-data')
shadowRaw = client.get_thing_shadow(thingName = "name_of_your_greengrassDevice")
shadowData = shadowRaw["payload"]
shadow = json.loads(shadowData)
speed = shadow["state"]["reported"]["your_attribute"]

You can see from the above, we can now access the “reported” or “desired” state of our shadow.

Updating the shadow

Here is another code snippet to update the shadow:

client = greengrasssdk.client('iot-data')
shadowData = client.get_thing_shadow(thingName = "name_of_your_greengrassDevice")
shadow = json.loads(shadowData['payload'])
shadow["state"]["reported"]["speed"] = event['speed']
shadow["state"]["desired"]["speed"] = event['speed']
client.update_thing_shadow(thingName = "name_of_your_greengrassDevice", payload = json.dumps(shadow))

In the above example, we’ll setting the speed value of our device in both the reported and desired sections of the shadow. This is just an example, usually you’re updating desired and the device updates reported.

Hopefully this helps those working with AWS Greengrass.