MQTT - how to get shadow working in AWS

Hi Travis,

Some time ago we spoke about an ‘all in one’ temperature and humidity sensor for AWS IoT integration. You recommended a MQTT sensor and wrote me this guide:

I’ve only just now got around to doing this and have 2x issues…

  1. My “topic format” is “CTS_MAN/::Sensor_ID::”, however, in AWS when I try and subscribe to “CTS_MAN/#” I get a message saying “You cannot publish messages to a wildcard topic”.

  2. In AWS under devices I can see my device, however, when I setup a device shadow (classic with no name) I am NOT getting any update shadows from the device

Can you assist with these two points please

Scott

As an update to this thread,

When I first open MQTT test client for the device I can see data when I subscribe to “CTS_MAN/#”. However, the “$aws/things/CTS_MAN/shadow/update/documents” subscription shows no data at all. I can see this subscription working for my AWS gateway (previously integrated) however not for this new MQTT device.

Updating the device shadow requires publishing to a different topic. The device is currently publishing to the topic CTS_MAN/::Sensor_ID:: rather than the Shadow Document topic.

Hi Travis,

Could you spell it out for me thanks… what should I put in the topic.

Bit of a beginner here… is it “CTS_MAN/shadow”

Tried all of these with no luck:

  • $aws/things/CTS_MAN/shadow
  • shadow
  • /shadow
  • CTS_MAN/shadow
  • CTS_MAN/shadow/update/documents
  • shadow/update/documents

??

Hi Travis,

Still haven’t managed to figure this one out. Can you offer some advice please.

Scott

Sorry @scott.wells not sure why I’m not getting notifications about this thread. Please tag me in future replies.

AWS IoT Core Doc here outlines everything about interacting with the Shadow Document through MQTT:

Keep in mind the policy attached to the AWS IoT Thing you created needs to specify the device is allowed to update the shadow document. If you’re not sure please provide the device policy document here so I can take a look. It needs to specify allow:publish for the Device Shadow Document resource like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish"
      ],
      "Resource": [
        "arn:aws:iot:region:account:topic/$aws/things/thingName/shadow/update"
      ]
    }
  ]
}

The topic the device needs to publish to in order to update the Shadow Document is:
$aws/things/thingName /shadow/update

Hi @TravisE_NCD_Technica

Stil struggling here.

I’ve updated the “topic” to “$aws/things/CTS_MAN_11/shadow/update”. CTS_MAN_11 is the thing name.

The security policy I used was the one created when adding a NCD AWS Gateway previously. To try and eliminate this issue I have created a new policy specifically for this new device. I followed your instructions here: Connecting MQTT WiFi Sensors to AWS IoT Core - NCD.io

The resulting policy looks like this:

{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “iot:Connect”,
“Resource”: “arn:aws:iot:::client/"
},
{
“Effect”: “Allow”,
“Action”: “iot:Publish”,
“Resource”: "arn:aws:iot:
::topic/
}
]
}

The device does connect (green light), but does not publish on the shadow topic. What I do notice is an error code “400” in the MQTT test client.

Subscription $aws/things//CTS_MAN_11/shadow/+/rejected is reporting the following message:

{
“code”: 400,
“message”: “Missing required node: state”
}

Perhaps this is the issue? I don’t know how to resolve it if it is.

I think I see the problem. It’s been a long time since I wrote the AWS Gateway firmware. It looks like updating the shadow document requires the payload JSON to be in a particular format including reported state like this:

{
  "state": {
    "reported": {
      "color": "red",
      "power": "on"
    }
  }
}

Try setting the Message Format to:
{"state":{"reported":::Sensor_Data::}}

Hi @TravisE_NCD_Technica

BINGO!! That’s got it. Working perfect now thanks!

1 Like

Awesome. Sorry that took a minute to figure out.

H @TravisE_NCD_Technica ,

One more question here.

Is there anyway I can add the “Client_ID” into the message format? Or, a fixed value?

I need to be able to send a specific “base” ID in the message format so that I can use that ID to align with an external ID for reporting data.

I need to get the ID “11” into the topic. As a stab in the dark, I tried these, but both were an invalid topic format:

  1. {“state”:{“reported”:::Sensor_Data::}:“base”:“11”}
  2. {“state”:{“reported”:::Sensor_Data:::“base”:::Client_ID::}}

Hopefully the above gives you an idea I need to get the ID 11 in anywhere in the topic.

Try:

{“state”:{“reported”:::Sensor_Data::,“base”:::Client_ID::}}

Hey @TravisE_NCD_Technica

Tried that, but got invalid json format message in the error channel.

Try:
{“state”:{“reported”:::Sensor_Data::,“base”:::Sensor_ID::}}

::Client_ID:: isn’t a valid token.