Skip to content

IoT Rule to republish Birth / Close / Last Will messages

0

I'm looking for a robust and simple way to instantly know if an IoT Thing is connected via MQTT or not. I tried to utilize MQTT's “birth” and “close” messages to update my IoT Thing's device shadow.

After spending a few hours, I read this:

MQTT LWT messages sent to AWS IoT reserved topics (topics that begin with $) are ignored by the AWS IoT Device Shadow service. However, they are processed by subscribed clients and by the AWS IoT rules engine, so you will need to create an LWT message that is sent to a non-reserved topic and a rule that republishes the MQTT LWT message as a shadow update message to the shadow's reserved update topic, ShadowTopicPrefix/update. Source

I followed the documentation to set up a rule to republish from a custom LWT topic to a reserved topic. However, I don't want to set up an individual rule for each of the hundreds of devices I have, so I define a variable for the Thing's name:

SELECT * AS message, topic(2) AS controllerId FROM 'controller/+/shadow/status/update

My action is to republish to:

$$aws/things/**${controllerId}**/shadow/name/status/update

However, I found out that when the rule is triggered, the variable controllerId is empty, leading to the message be republished to

$aws/things//shadow/name/status/update

Can that be solved? Can I use the variable from the SELECT statement in the republishing action?

asked 2 years ago341 views

1 Answer
-1

Yes, you can use variables from the SELECT statement in the republishing action, but there might be an issue with your current setup. Let's address your problem and provide a solution.

The issue you're experiencing is likely due to the way you've structured your topic and SELECT statement. In your current setup, you're trying to extract the controllerId from the second level of the topic, but your topic structure doesn't align with this.

To fix this, you need to adjust your rule query statement to correctly extract the controllerId. Here's a corrected version:

SELECT * AS message, topic(3) AS controllerId FROM 'controller/+/shadow/status/update'

In this corrected version, we're using topic(3) instead of topic(2) because the controllerId is the third element in your topic structure (controller/[controllerId]/shadow/status/update).

For the republish action, you can use the extracted controllerId like this:

$aws/things/${controllerId}/shadow/name/status/update

This should correctly populate the controllerId in the republished topic.

Regarding your overall approach to tracking device connection status, using MQTT Last Will and Testament (LWT) messages with a rule to update the device shadow is a valid and robust method. Here's a summary of how you can implement this:

  1. When your device connects to AWS IoT, it should set up an LWT message on a non-reserved topic (like the one you're using: 'controller/[controllerId]/shadow/status/update').

  2. Create an AWS IoT rule (as you've done) to listen for messages on this topic and republish them to the device shadow topic.

  3. When the device connects, it should publish a "connected" status to the same topic.

  4. If the device disconnects unexpectedly, the LWT message will be published, and your rule will update the shadow to reflect the disconnected status.

This approach will allow you to track the connection status of your IoT Things effectively, with the device shadow always reflecting the current state.

Remember to ensure that your IAM role associated with the republish action has the necessary permissions to publish to the shadow topics.
Sources
Republish - AWS IoT Core
Tutorial: Republishing an MQTT message - AWS IoT Core
Using shadows in apps and services - AWS IoT Core

answered 2 years ago

  • Why should 'controllerId' be the third element of the topic? That doesn't make sense to me.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.