Skip to content

Message routing based on IoT device registry attribute

5 minute read
Content level: Advanced
0

Use the IoT Core registry attribute as a cost effective way of enriching a message and routing to a queue or topic using a single IoT Core Rule.

Message routing based on IoT device registry attribute.

In this article, I will show you how you can route messages to different SQS queues using a single IoT Rule without requiring any changes to your devices. By modifying a user property for the device in the IoT Device Registry, you can configure that attribute to be automatically added to the MQTT 5 user properties of the message. This attribute can then be queried using an IoT Rule function (at no additional cost) and appended to the message sent via the configured rule action or used as part of the rule action using a substitution template.

Use Cases

What are some use cases for this approach?

  • Dynamic Workflow Adjustments: Suppose you have a fleet of devices and want to implement a new workflow for some of them.
  • Subscription-Based Routing: You might want to change the workflow based on a subscription change by the end-user.

You can programmatically adjust a registry attribute to route messages to a different work-stream or, in this demo, a different SQS queue. This is documented as Adding propagating attributes for message enrichment.

Example Scenario

In this example, we have a fleet of devices publishing telemetry data to a topic (aircon/telemetry). These devices are MQTT 3.1.1 devices but will enrich the message with key-value pairs from the IoT Core Device Registry as MQTT 5 User Properties. We have created a thing type called Aircon_Unit and defined a propagating attribute named environment. The simulated aircon units have a thing attribute called environment, and by default, this is set to prod. The aircon devices are configured as thing type Aircon_Unit.

Enter image description here

Architecture overview:

Enter image description here

Routing Messages Based on the environment Attribute

With all units publishing to aircon/telemetry and their environment attribute set to prod, all messages are sent to the SQS queue:

sqs.us-west-2.amazonaws.com/012345678901/prod

By changing just the environment attribute for unit 4 to dev, all messages from that unit will now be sent to:

sqs.us-west-2.amazonaws.com/012345678901/dev

This change can be made in the AWS IoT Console or via the AWS CLI:

Using the AWS CLI

aws iot update-thing \
    --thing-name aircondition_unit_4 \
    --attribute-payload attributes={environment=dev}

Using the IoT Console:

Enter image description here

Configuring the AWS IoT Rule Action

The AWS IoT Rule Action uses a substitution template to replace the SQS queue name with the value from the MQTT 5 user properties. To set up this rule, you will need to use the AWS CLI.

Step 1: Create the rulePayload.json File Create a JSON file called rulePayload.json using the template below. Be sure to replace the region and account ID with your actual AWS region and account ID.

rulePayload.json Template

{
    "sql": "SELECT * FROM 'aircon/telemetry'",
    "description": "Route messages to SQS based on environment",
    "actions": [
        {
            "sqs": {
                "roleArn": "arn:aws:iam::012345678901:role/service-role/iot_to_sqs_role",
                "queueUrl": "https://sqs.us-west-2.amazonaws.com/012345678901/${replace(replace(replace(get_user_properties('environment'), '[', ''), ']', ''), '\"', '')}",
                "useBase64": true
            }
        }
    ],
    "ruleDisabled": false,
    "awsIotSqlVersion": "2016-03-23"
}

Notes:

  • sql: Specifies the SQL statement that selects messages from the aircon/telemetry topic.
  • description: Provides a description of the rule.
  • actions: Defines the action to send messages to an SQS queue, using the environment variable from the MQTT 5 user properties.
  • roleArn: Replace 012345678901 and iot_to_sqs_role with your AWS account ID and the IAM role that grants permission to write to the SQS queue.
  • queueUrl: Uses a substitution template ${environment} to dynamically route messages to the appropriate SQS queue based on the environment value.

Step 2: Create the IoT Rule Using the AWS CLI Use the AWS CLI to create the IoT Rule with the rulePayload.json file you just created:

aws iot create-topic-rule \
--rule-name "SendToSQSBasedOnMQTT5UserProperty" \
--topic-rule-payload [file://rulePayload.json](file://rulepayload.json/)

Explanation:

  • aws iot create-topic-rule: AWS CLI command to create a new IoT Rule.
  • --rule-name: Assigns a name to the rule (e.g., SendToSQSBasedOnEnvironment).
  • --topic-rule-payload: Specifies the path to the JSON file containing the rule definition.

Step 3: View the IoT Rule Using the AWS CLI

aws iot get-topic-rule --rule-name SendToSQSBasedOnMQTT5UserProperty

Output:

{
    "ruleArn": "arn:aws:iot:us-west-2:012345678901:rule/SendToSQSBasedOnMQTT5UserProperty",
    "rule": {
        "ruleName": "SendToSQSBasedOnMQTT5UserProperty",
        "sql": "SELECT * FROM 'aircon/telemetry'",
        "description": "Route messages to SQS based on environment",
        "createdAt": "2024-11-17T20:01:01-08:00",
        "actions": [
            {
                "sqs": {
                    "roleArn": "arn:aws:iam::012345678901:role/service-role/iot_to_sqs_role",
                    "queueUrl": "https://sqs.us-west-2.amazonaws.com/012345678901/${replace(replace(replace(get_user_properties('environment'), '[', ''), ']', ''), '\"', '')}",
                    "useBase64": true
                }
            }
        ],
        "ruleDisabled": false,
        "awsIotSqlVersion": "2016-03-23"
    }
}

Step 4: Verify the Rule After creating the rule, you can verify that it's working correctly:

  1. Publish Test Messages:

    • Use your MQTT client or a simulation to publish messages to the aircon/telemetry topic.
    • Ensure that the devices have the environment attribute set in the IoT Device Registry.
  2. Check the SQS Queues:

    • Verify that messages are arriving in the SQS queues corresponding to the environment values (e.g., prod, dev).
  3. Monitor AWS IoT Core Logs:

    • Use CloudWatch Logs to monitor the IoT Rule execution and troubleshoot any issues.

Summary

  • Propagating Attributes:
    • By defining environment as a propagating attribute in the thing type Aircon_Unit, the attribute is automatically added to the MQTT 5 user properties when the device publishes a message.
    • This allows you to dynamically route messages without modifying the devices themselves.
  • Use Cases:
    • This setup is useful for scenarios where you need to adjust workflows or message routing based on device attributes, such as rolling out new features to a subset of devices or handling subscription changes.
  • No Device Changes Required:
    • Since the environment attribute is managed in the IoT Device Registry and propagated automatically, there is no need to update the firmware or configuration on the physical devices.
AWS
EXPERT
published a year ago604 views
1 Comment

Hey, very nice approach! We wanted to use this to dynamically determine the environment of a device message instead of relying the device to provide it's environment in the message. The only problem for this is that the propagated attributes take a while to be updated (approx 10 minutes). So if we change a device from dev -> prod, it will keep sending messages to the dev resources until the attribute is updated.

I guess this is a problem with fleet indexing? If we want to have instant switching of environments we have to rely on get_thing_shadow by having a desired property like 'environment': 'prod'.

Do you also have this problem with the propagated attribute change latency?

replied 8 months ago