AWS lot of Iot a things, I’ve learned

I’ve been experimenting with AWS Iot and thought when JITR (Just In Time Registration) came out that it would get a lot easier.

I setup my environment to use JITR and realized it really wasn’t what I was trying to accomplish. If I have 1000’s of things which really will never connect individually through MQTT why have a policy and certificate for each of them. I really just wanted to have the thing shadows updated, and use the API for reporting. Realizing that a bridge with TLS certs would provide security I decided to try that method of interfacing with AWS services.

So first I setup a virtual machine that runs mosquitto following the instructions here:

https://aws.amazon.com/blogs/iot/how-to-bridge-mosquitto-mqtt-broker-to-aws-iot/

I didn’t want to use EC2 environment so I started following the directions at the heading of “How to Configure the Bridge to AWS IoT”

After following the above document I was seeing the MQTT messages on the AWS console

mosquitto_pub -h localhost -p 1883 -q 1 -d -t localgateway_to_awsiot  -i clientid1 -m “{\”key\”: \”helloFromLocalGateway\”}”

If you subscribe in the console to both_directions you will see the messages on the test link for MQTT client.

So I wanted more open permissions to things shadows so I could update them through the mosquito broker. After playing around for a couple of days I made the following discovery.

If you define the topic like the following in your broker.conf file you can then post to multiple thing shadows:

topic $aws/things/+/shadow/update out 1

With the topic defined above would mean that any $aws/things/<device>/shadow/update will be forwarded to AWS.

The learning cure for me was how to delimit the mosquitto_pub message in the unix environment. Since my mosquitto vm’s OS is debian jessie.

The following syntax works for updating thing shadows on my debian jessie install.

mosquitto_pub  -h localhost -p 1883 -q 1 -d -t \$aws/things/4562077637/shadow/update -i 4562077637 -m ‘{“state”: { “reported”: { “temperature”: 32749, “message”:”Hello World” }}}’

So the only step left was to first create the many things I need without attached certificates or policies, and not having to manually do it through the Console.

So I ran a simple Node.js script with AWS cli  and sdk installed on my local machine

var AWS = require(‘aws-sdk’);

AWS.config.region = ‘us-east-1’;

var crypto = require(‘crypto’);
var endpoint = <your_endpoint>.us-east-1.amazonaws.com”;
var iot = new AWS.Iot();
var iotdata = new AWS.IotData({endpoint: endpoint});

var lineReader = require(‘readline’).createInterface(
{ input: require(‘fs’).createReadStream(‘mylist.txt’)});
{

lineReader.on(‘line’,function(line) {
  var thing = line;
var thingParams = { thingName: thing };

  iot.createThing(thingParams).on(‘success’, function(response) {
    //Thing Created!
  }).on(‘error’, function(response) {
    console.log(response);
  }).send();
});
}

This allowed me to create my things by loading a simple text file with the thing names extracted directly out of the database of devices I wanted to create.

The JavaScript was modified from the following blog post about “Implementing a Serverless AWS Iot Backend with AWS”. I actually followed that post as well for additional learning on different configurations that can be set up with Lambda functions and using Amazon DynamoDB.

https://aws.amazon.com/blogs/compute/implementing-a-serverless-aws-iot-backend-with-aws-lambda-and-amazon-dynamodb/

Now with my mosquitto server NATed to my local host on port 1883 I can send a message on that port which is then forwarded on port 8883 using TLS and certs setup on broker to AWS. Since my policy for the broker is wide open to use any Iot resource I can update any shadow and subscribe to any topic through the broker.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

So the bridge connection certs and private key are not ones that you want someone to get a hold of, with someone obtaining that they could impact your entire repository of things in AWS.

The last experimenting I did was setting up a java publisher to forward messages to my local mosquitto bridge.

On github I modified the following sample code to work with my local mosquitto broker.

https://github.com/tgrall/mqtt-sample-java

The publisher code was changed to publish messages to

MqttClient client = new MqttClient(“tcp://localhost:1883”,MqttClient.generateClientId());

As stated before that port is Nat’ed to the VM with mosquitto installed on it.

Also all the code for certificates being loaded can be eliminated since our MQTT being published on that local port doesn’t use security.

The only other code I changed was to help write the json message.

I referenced jackson-annotations, jackson-core and jackson-databind libraries.

This allowed me to write the json for AWS reported without having to use a bunch of delimiters and such in code.

The messageString was formatted using Jackson as follows:

ObjectMapper mapper = new ObjectMapper();
             
         ObjectNode objectmessage = mapper.createObjectNode();
          objectmessage.put(“temperature”, 10000);
          objectmessage.put(“company”, “acme”);
        
         ObjectNode objectNodeO = mapper.createObjectNode();
         ObjectNode objectNodeI = mapper.createObjectNode();
        
         objectNodeI.putPOJO(“reported”, objectmessage);
         objectNodeO.putPOJO(“state”, objectNodeI);
        
         String messageString = objectNodeO.toString();

This produces the following json string:   

== START PUBLISHER ==
    Message ‘{“state”:{“reported”:{“temperature”:10000,”company”:”acme”}}}’ to ‘topic’
== END PUBLISHER ==

Then you can change the publishing code to each thing you want to update.

     client.publish(“$aws/things/4562077637/shadow/update”, message);

Well that’s about it, I’m still learning but I hope this helps someone else save some time.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s