Cronjob at the edge with AWS IoT
I’m working on a project where I have to manage a cronjob that runs on a small computer with an unreliable Internet connection. I want to configure the cronjob schedule expression (e.g., 0 10 * * *
) remotely but the cronjob should not be interrupted if the Internet connection fails. If an Internet connection is available, I would also like to report if the cronjob execution was successful.
An excellent fit to manage the state of a device with an unreliable Internet connection is the Device Shadow Service for AWS IoT. A device shadow has a desired and reported state. Let’s assume the following state.
{ |
As you can see, the desired
state contains the cronexpression
attribute which is not present on the reported
state. The device has not yet reported anything to the device shadow.
If the device comes online, it receives the new desired state, applies the changes, and reports the new state on the device to AWS IoT. The state will look like this:
{ |
The device is now in sync with the device shadow. You can change the desired state of the device shadow at any time by making a call to AWS IoT.
{ |
Again, if the device is online it will receive the new desrired state and apply changes.
Implementation
First, you need to create an IoT Thing.
Visit the AWS IoT Core Management Console
Click on Secure > Policies on the left
Click the Create button
Set Name to
cloudonaut
Click on Advanced mode
Enter the following policy, replace
REGION
with your AWS region andACCOUNT_ID
with your AWS account id, and click the Create button{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Subscribe",
"Resource": "arn:aws:iot:REGION:ACCOUNT_ID:topicfilter/$aws/things/cloudonaut/shadow/*"
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": "arn:aws:iot:REGION1:ACCOUNT_ID:topic/$aws/things/cloudonaut/shadow/*"
},
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "arn:aws:iot:REGION:ACCOUNT_ID:client/cloudonaut-*"
},
{
"Effect": "Allow",
"Action": [
"iot:GetThingShadow",
"iot:UpdateThingShadow"
],
"Resource": "arn:aws:iot:REGION:ACCOUNT_ID:thing/cloudonaut"
}
]
}Click on Manage > Things on the left
Click the Create button
Click the Create a single thing button
Set the Name to
cloudonaut
Click the Next button
Click Create certificate
Download the certificate, private key, public key, and root CA
Click the Activate button
Click the Attach a policy button
Select the
cloudonaut
Click the Register Thing button
Click on Settings on the left
Take a note of the endpoint
The AWS IoT service is now configured. Let’s implement the device logic in Node.js using the aws-iot-device-sdk package. To install the package, run npm i aws-iot-device-sdk
.
First, the device needs to connect to AWS IoT using MQTT.
const awsIot = require('aws-iot-device-sdk'); |
To connect to its shadow the device has to call the register
method using a name that identifies the IoT thing. As soon the device has registered, it asks for the latest state of its shadow.
thingShadow.register(thingName, {}, function(err) { |
Finally, the device receives the initial status and delta updates of its shadow.
thingShadow.on('status', function(thingName, stat, clientToken, stateObject) { |
The only missing piece is the implementation of createOrUpdateCronjob
that also reports the cronexpression
back AWS IoT. The device also reports the last time the cronjob executed via the cronexecution
attribute. If the device has no Internet connection, the cronjob still executes. To install the package, run npm i node-cron
.
const cron = require('node-cron'); |
Summary
A device shadow is an excellent choice to deploy configuration information to devices that are temporarily online. You can manage the desired configuration of your device at any time by updating the device shadow. Once the device comes online, the desired state is applied and reported back to the shadow.
Further reading
- Article Download YouTube videos with AWS Lambda and store them on S3
- Article Introducing AWS Lambda
- Article Three ways to run Docker on AWS
- Tag iot