DEV Community

Nenad Ilic for IoT Builders

Posted on

Developing Your First Greengrass Publish Component on Raspberry Pi

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"
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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": {}
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)