Developing Your First Greengrass Publish Component on Raspberry Pi
Nenad Ilic
Posted on July 20, 2023
In the previous blog post, we delved into the world of AWS IoT Greengrass V2, focusing on the usage of the Greengrass Development Kit (GDK) and how it can be automated with GitHub Actions. Today, we're going to take it a step further. We'll walk through the process of developing your first AWS IoT Greengrass Publish component on a Raspberry Pi.
Step 1: Setting Up Your Environment
Before we start, ensure that you have your Raspberry Pi is set up by using the Fleet Provisioning mehtod as we will be using now those GitHub Actions and the project we created in our previous blog post to deploy our component. In scenarios that you are working with a different OS, you would need to follow the instruction on installing AWS IoT Greengrass as well.
Step 2: Designing the Message Publisher Component
The first step in creating our messaging system is to create the message publisher component. This component will be responsible for sending data, such as sensor readings or application logs, to a specified topic.
In the AWS IoT Greengrass, components are defined by a recipe, which is a JSON or YAML file that specifies the component's metadata, lifecycle, configuration, and dependencies. For our message publisher component, we'll need to define a recipe that includes the necessary AWS IoT Greengrass component to publish messages to a topic.
Here's an example of what the recipe might look like:
---
RecipeFormatVersion: "2020-01-25"
ComponentName: "{COMPONENT_NAME}"
ComponentVersion: "{COMPONENT_VERSION}"
ComponentDescription: "A component that publishes temperature data to AWS IoT Core"
ComponentPublisher: "{COMPONENT_AUTHOR}"
ComponentConfiguration:
DefaultConfiguration:
accessControl:
aws.greengrass.ipc.mqttproxy:
'com.example.pub:mqttproxy:1':
policyDescription: Allows access to publish the temperature to topic.
operations:
- aws.greengrass#PublishToTopic
resources:
- 'CPU/info'
Manifests:
- Platform:
os: all
Artifacts:
- URI: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.pub.zip"
Unarchive: ZIP
Lifecycle:
Run: "python3 -u {artifacts:decompressedPath}/com.example.pub/main.py"
In this recipe, we're creating a component with the name com.example.pub
. This component is different from our previous examples due to the inclusion of an accessControl:
configuration. This configuration allows the component to publish messages to a specific MQTT topic.
In our case, the resource
is set to CPU/info
. This setting means that our component has permission to publish only to the CPU/info
MQTT topic.
If you need the component to publish to multiple topics, you can extend the list of resources
with additional topic names. Alternatively, if you want the component to have permission to publish to any topic, you can replace CPU/info
with *
. This wildcard character represents all possible topics, granting the component full publishing access.
Step 3: Implementing the Message Publisher Component
With the component designed, we can now move on to implementing the message publisher component. This involves writing the main.py
script that we referenced in the component recipe.
The main.py
script will use the AWS SDK for Python which uses awsiot.greengrasscoreipc.clientv2
to interact with Greengrass IPC in order to publish messages to a specified AWS IoT topic. Here's an example of what the script would look like:
import os
import time
import json
import awsiot.greengrasscoreipc.clientv2 as clientV2
TOPIC="CPU/info"
def get_cpu_temp():
temp_file = open("/sys/class/thermal/thermal_zone0/temp")
cpu_temp = temp_file.read()
temp_file.close()
return float(cpu_temp)/1000
def main():
# Create an IPC client.
ipc_client = clientV2.GreengrassCoreIPCClientV2()
while True:
cpu_temp = get_cpu_temp()
print("CPU temperature: {:.2f} C".format(cpu_temp))
# Create a payload.
payload = json.dumps({"temperature": cpu_temp})
# Publish the payload to AWS IoT Core.
resp = ipc_client.publish_to_iot_core(topic_name=TOPIC, qos="1", payload=payload)
time.sleep(1) # sleep for 1 second
ipc_client.close()
if __name__ == "__main__":
main()
In this script, we're creating a loop that continuously publishes a message to the CPU/info
topic. The message contains a json payload with temperature
value, which could be then extended further in a real-world application.
Step 4: Deploying the Message Publisher Component
For deploying the new component to the device we should extend the deployment.json.template:
{
"targetArn": "arn:aws:iot:$AWS_REGION:$AWS_ACCOUNT_ID:thinggroup/$THING_GROUP",
"deploymentName": "Main deployment",
"components": {
"com.example.hello": {
"componentVersion": "LATEST",
"runWith": {}
},
"com.example.world": {
"componentVersion": "LATEST",
"runWith": {}
},
"com.example.pub": {
"componentVersion": "LATEST",
"runWith": {}
}
},
"deploymentPolicies": {
"failureHandlingPolicy": "ROLLBACK",
"componentUpdatePolicy": {
"timeoutInSeconds": 60,
"action": "NOTIFY_COMPONENTS"
},
"configurationValidationPolicy": {
"timeoutInSeconds": 60
}
},
"iotJobConfiguration": {}
}
If you've followed our previous blog post, you should have your GitHub Actions set up for your repository. This setup allows for automatic deployment of your components.
When you create a new component and commit it to your repository, make sure to add it to the deployment.json.template
. This step is crucial as it ensures your component is included in the deployment process.
After committing the new component, the GitHub Actions workflow will trigger, resulting in the automatic deployment of your component to the targeted device, in this case, a Raspberry Pi.
Once deployed, the component will start running on the Raspberry Pi. It will begin publishing messages to the specified AWS IoT topic.
To verify that your component is functioning correctly, you can subscribe to the topic in the AWS IoT Core console. Here, you'll be able to observe the incoming messages, confirming that your component is publishing as expected.
Conclusion
In this blog post, we've walked through the process of developing a Greengrass Publish component on a Raspberry Pi. This is a great way to use the messaging system for your IoT applications, and I hope it helps you on your journey with AWS IoT Greengrass.
For reference, please refer to this GitHub repo.
Stay tuned for more posts on advanced Greengrass component development and other IoT topics. Happy coding!
If you have any feedback about this post, or you would like to see more related content, please reach out to me here, or on Twitter or LinkedIn.
Posted on July 20, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.