![]() |
Morse Micro IoT SDK
2.11.2
|
AWS IoT example to demonstrate connecting to AWS Shadow service and demonstrate a simple light bulb example.
This example application demonstrates how to use AWS IoT Core services to connect to an AWS endpoint and use the shadow service to mirror the state of a light bulb shadow state maintained by AWS.
The following steps need to be done to run this application:
AllowAll AllowAll policy is selectedCongratulations! Your device should now be created.
Download the certificates and key files and proceed to the next step. Specifically you will need the Device Certificate, Device Private Key amd the Amazon RSA Root Certificate.
openssh to create the device certificate and keys and upload them using AWS CLI.https://docs.aws.amazon.com/iot/latest/developerguide/jit-provisioning.html This method loads all devices with a common provisioning certificate, which then gets replaced with a unique device certificate when the device first connects to the AWS endpoint.AmazonRootCA.pem, certificate.pem.crt, and private.pem.key with the files downloaded from AWS in the previous step. Rename the downloaded files to match the target file names. Note: Amazon provides you with 2 root CA files to download, please use the file named AmazonRootCA1.pem.config.hjson file.aws.thingname with the name of the thing you created in the previous section.aws.endpoint with the server name in the URL. Ensure you remove the https:// and everything after amazonaws.com config.hjson file to the device. powerOn variable."<your_thing_name>" with the name of the thing you created.powerOn parameter printed on the console output should change.AWS Shadow service allows us to cache the state of an IoT device on the cloud. This allows the IoT device to go to sleep and wake up once in a while to update its state on the cloud and act on pending state change requests on the cloud. For example a temperature sensor could periodically measure and update the temperature using the AWS Shadow service and go to sleep for minutes or even hours at a time while AWS Shadow caches this data and makes it available persistently to anyone who may be interested in the temperature even though the sensor is asleep and no longer reachable on the network.
Likewise, for a light bulb, AWS Shadow remembers the state of the light bulb even though the light bulb itself may have been unplugged and so not connected to the network. In fact the AWS Shadow can accept state change requests on behalf of the light bulb when it is unplugged and then convey the desired state to the light bulb when it connects again.
This is how it works:
"$aws/things/<your_thing_name>/shadow/update" "$aws/things/<your_thing_name>/shadow/update/delta" as "$aws/things/<your_thing_name>/shadow/update" "$aws/things/<your_thing_name>/shadow/update/accepted" "$aws/things/<your_thing_name>/shadow/update/rejected" For more information see: https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html
Now that we have seen AWS Shadow being used to connect to and control our IoT device, how can we put this to practice with a real world application?
Amazon shows us how we can use Alexa to post messages to AWS IoT devices with an example smart hotel application: https://aws.amazon.com/blogs/iot/implement-a-connected-building-with-alexa-and-aws-iot/
In this example they show us how to create an Alexa skill that can post JSON messages to our IoT device using AWS Shadow. You can use the tutorial above to customize this application for your specific smart device needs.
In the example above we used the AWS IoT console to create certificates and publish/subscribe to MQTT messages. While this may be convenient for development and testing, it is hardly a practical approach for real world applications. Luckily, we have options - Amazon provides us with the AWS CLI (Command Line Interface), which lets us do everything above using a command line interface such as creating certificates, registering devices, publishing and subscribing to MQTT messages. This allows us to automate and script production and registration of devices and even implement M2M communications using the MQTT publish/subscribe API. A full reference of the available commands is at: https://docs.aws.amazon.com/cli/latest/index.html
The steps above describe how to provision one device at a time for AWS IoT. This however is not practical when we have to provision thousands of devices in the field. Thankfully AWS provides a mechanism called Fleet Provisioning that allows us to automate this process.
For more information on Fleet Provisioning see: https://docs.aws.amazon.com/whitepapers/latest/device-manufacturing-provisioning/provisioning-identity-in-aws-iot-core-for-device-connections.html
There are multiple mechanisms of implementing Fleet Provisioning - we have implemented the Fleet Provisioning by claim mechanism. In this mechanism a batch of devices (say 1000) will be loaded with a shared claim certificate and keys. The device will make first contact with the AWS endpoint using this shared certificate and key just as it would with regular device certificates and keys. The device then generates a new set of keys and sends the certificate to AWS for signing. AWS signs the certificate and assigns the device a new thing name based on the provisioning template - the provisioning template may specify the thing name is an amalgam of the device serial number (in our case the MAC address) and some prefix. The device saves the signed certificate, generated keys and thing name and uses them for all connections henceforth.
Use the steps below to implement fleet provisioning. Alternatively, if you prefer to use the AWS command line, then all the steps below are described here for the command line: https://www.freertos.org/iot-fleet-provisioning/demo.html#setting-up
Ensure you have the required permissions and roles to implement fleet provisioning. Your AWS administrator can setup the roles using the following commands on the AWS command line:
FleetProvisioningRole role AWSIoTThingsRegistration policy to the role AllowAll policy as described in Create a Thing_fp_demo_things_ and click Create thing typetemplates/fleet_provisioning_policy.json): _FleetProvisioningTemplate_ with the name of the template you specified in Create provisioning template. Set the aws.provisioningtemplate key to the provisioning template name you specified here._FleetProvisioningTemplate_ IAM role_ is unchecked.templates/fleet_provisioning_template.json): _AllowAll_ matches the name of the AllowAll policy you created in the prerequisites. Ensure _fp_demo_things_ matches the thing type you created in Create a thing typeaws.provisioningtemplate key to the provisioning template name you set in Create provisioning template.Wi-Fi credentials and country code.aws.thingname and atomically replace the claim credentials with the newly generated credentials.aws.thingname key. However, be aware that claim certificates are intended to be used temporarily and may expire or be revoked. So this method of re-provisioning may fail if the claim certificate is no longer valid.create-from-csr and provisioning-templates resources. In our case the AllowAll policy allows everything including these claim permissions. To re-provision, the application simply deletes the aws.thingname key to trigger the provisioning process. This method has the advantage of requiring less resources by not needing to keep a copy of the claim certificate and key which saves around 3KB of storage in persistent store. Definition in file aws_iot.c.
#include <string.h>#include "mmhal_app.h"#include "mmosal.h"#include "mmconfig.h"#include "mm_app_loadconfig.h"#include "mmipal.h"#include "mqtt_agent_task.h"#include "sntp_client.h"#include "core_json.h"#include "mm_app_common.h"#include "aws_iot_config.h"
Go to the source code of this file.
Macros | |
| #define | NTP_MIN_TIMEOUT 3000 |
| Minimum NTP timeout per attempt. More... | |
| #define | NTP_MIN_BACKOFF 60000 |
| We need to back-off at least 60 seconds or most NTP Servers will tell us to go away. More... | |
| #define | NTP_MIN_BACKOFF_JITTER 3000 |
| Minimum back-off jitter per attempt. More... | |
| #define | NTP_MAX_BACKOFF_JITTER 60000 |
| Maximum back-off jitter per attempt. More... | |
| #define | SHADOW_PUBLISH_JSON |
| Format string representing a Shadow document with a "reported" state. More... | |
Functions | |
| void | app_init (void) |
| Main entry point to the application. More... | |
| #define NTP_MAX_BACKOFF_JITTER 60000 |
| #define NTP_MIN_BACKOFF 60000 |
| #define NTP_MIN_BACKOFF_JITTER 3000 |
| #define NTP_MIN_TIMEOUT 3000 |
| #define SHADOW_PUBLISH_JSON |
Format string representing a Shadow document with a "reported" state.
The real json document will look like this:
Note the client token, which is optional. The token is used to identify the response to an update. The client token must be unique at any given time, but may be reused once the update is completed. For this demo, a timestamp is used for a client token.