This is an example of how downlink commands are sent back to a device. In this workshop, we will send commands back to faulty devices, using an Azure Function, to start them up again.
This part of the workshop supports both to the TTN Node and to the NodeJs app and to the Java app.
Note: In this workshop, we will create uniquely named Azure resources. The suggested names could be reserved already.
- A running NodeJs or Java app which simulates a machine running duty cycles
- A combination of Azure IoT Hub, Stream Analytics job, Event Hub and Azure Function which are waiting for analyzed telemetry coming from the devices
- Azure account create here (Azure passes will be present for those who have no Azure account (please check your email for final confirmation))
At the end of this part of the workshop, the following steps are performed
- Sending back commands for devices which are in a faulty state
- Handle commands in the devices
- Conclusion
In the previous NodeJs chapter, we passed the telemetry from the device to a Stream Analytics job. This job collected devices which are sending error states. Every two minutes, information about devices that are in a faulty state are passed to an Azure Function.
In this workshop, we will react on these devices by sending them a command to 'repair themselves'.
First, we update the Azure Function. For each device which is passed on, we send a command back.
Sending commands back to devices is a specific feature of the IoT Hub. The IoT Hub registers devices and their security policies. And the IoT Hub has built-in logic to send commands back.
-
On the left, select
Resource groups
. A list of resource groups is shown -
Select the ResourceGroup
IoTWorkshop-rg
. It will open a new blade with all resources in this group -
Select the Azure Function App
IoTWorkshop-fa
-
To the left, the current functions are shown. Select
IoTWorkshopEventHubFunction
-
The Code panel is shown. The code of the function is shown. Note: actually, this code is saved in a JavaScript file named index.js in the Azure storage of the Function app
-
Change the current code into
module.exports = function (context, myEventHubTrigger) { context.log('Stream Analytics produced: ', myEventHubTrigger); var Client = require('azure-iothub').Client; var Message = require('azure-iot-common').Message; var connectionString = "[IOT HUB connection string]"; var serviceClient = Client.fromConnectionString(connectionString); function printResultFor(op) { return function printResult(err, res) { if (err) context.log(op + ' error: ' + err.toString()); if (res) context.log(op + ' status: ' + res.constructor.name); }; } function receiveFeedback(err, receiver){ receiver.on('message', function (msg) { context.log('Feedback message:') context.log(msg.getData().toString('utf-8')); }); } serviceClient.open(function (err) { if (err) { context.log('Could not connect: ' + err.message); } else { context.log('Service client connected'); serviceClient.getFeedbackReceiver(receiveFeedback); var message = new Message('*'); // * = ascii 42 context.log('Sending message: ' + message.getData()); for(i = 0; i < myEventHubTrigger.length; i ++) { var targetDevice = myEventHubTrigger[i].deviceid; context.log('Sending message to: ' + targetDevice); serviceClient.send(targetDevice, message, printResultFor('send')); } } }); context.done(); };
-
Press the
Logs
button at the bottom to open the pane which shows some basic logging -
A 'Logs' panel is shown. This 'Logs' panel works like a trace log.
-
Because we are writing JavaScript, there will be no warning the code above has some flaws. We need to add a connection string and extra libraries. Let's start with the extra libraries.
-
Press the
View Files
button to 'unfold' the pane which shows a directory tree of all files.
-
In the pane you can see that the file currently selected is: index.js
-
Add a new file by pressing
Add
-
Name the new file
package.json
-
Press
Enter
to confirm the name of the file and an empty code editor will be shown for this file. -
The 'package.json' file describes which NodeJS packages have to be referenced. Fill the editor with the following code
{ "name": "azure-javascript-function", "version": "1.0.0", "description": "", "main": "index.js", "author": "", "license": "", "dependencies": { "azure-iot-device": "^1.1.7", "azure-iot-device-amqp": "^1.1.7", "azure-iothub": "^1.1.7" } }
-
Select
Save
. -
Open
the azure console:
- Enter the following command
cd iotworkshop-eh
at the console window to navigate to the iot workshop direction. - Enter
npm install azure-javascript-function
at the console window to install package.json
-
We have added the extra dependencies. Unfortunately the libraries involved are not loaded yet. To make sure all libraries are loaded, all we have to do is simply stop and start our Azure Function. Note: you can press 'save and run', with a test message like "[{"count":16,"deviceid":"MachineCyclesNodeJs"}]" (check out the 'Test' option to the right for more info) but this will not be compiles correctly
-
To the left, press
Manage
-
Disable
andEnable
the Azure Function again -
The combination of libraries and code is now ready
-
There is just one thing left to do: we have to fill in the
Azure IoT Hub security policy connection string
. To send commands back, we have to proof we are authorized to do this -
In the Azure Function, replace '[IOT HUB connection string]' with your remembered IoT Hub
Connection String-primary key
-
Select
Save
again
Now, the Azure Function is ready to receive data about devices which simulate 'faulty machines'. And it can send commands back to 'repair' the 'machines'.
Let's check if your device in already in a faulty state and see how the Azure IoT Platforms sends back a command to repair it.
The javascript client is instrumented to fall into an error state already, every fifth "completed cycle" message results in an error state. This will put the device in an error state.
Just wait for approx. two minutes and see how the error state arrives at the IoT Hub and within two minutes the command is generated to 'fix' the machine.
Again, after five successfull cycles, the app will generate another error state, which will eventually be fixed automatically.
Receiving commands from Azure completes the main part of the workshop.
We hope you did enjoy working with the Azure IoT Platform, as much as we did. Thanks for getting this far!
But wait, there is still more. We added two bonus chapters to the workshop
And for more creative ideas, we can recommand to look at hackster.io. Every day, new IoT projects are added!