In this post we will discover how to:
GitHub source code: https://github.com/vunvulear/IoTHomeProject
What is device twin
It’s a collection of properties that specific for each individual device. Device twins contains 3 types of structure (where the last two are similar, but have different roles)
A good example is customer ID or device location. There is no need to send this data to device if the device doesn’t need this data. In contrast, desired/reported properties are all the time send/received from device. Properties like device configuration, current status or different counters can be found inside them.
More about device twin
Tool that can be used to read reported properties from device twin and set desired properties
- Tool that can be used to read reported properties from device twin and set desired properties
- Read how often sensor data are reported to backend from desired properties
- Write how often sensor data are reported by device using reported properties
GitHub source code: https://github.com/vunvulear/IoTHomeProject
What is device twin
It’s a collection of properties that specific for each individual device. Device twins contains 3 types of structure (where the last two are similar, but have different roles)
- Tags: Device specific information that resides on the Azure IoT Hub and never reach the device
- Desire Properties: Properties set on Azure IoT Hub (by backend) and are delivered to the device
- Reported Properties: Properties set by Device and are delivered to Azure IoT Hub (to backend)
A good example is customer ID or device location. There is no need to send this data to device if the device doesn’t need this data. In contrast, desired/reported properties are all the time send/received from device. Properties like device configuration, current status or different counters can be found inside them.
More about device twin
Tool that can be used to read reported properties from device twin and set desired properties
We could create such a tool, but it doesn't make sense. Also, the Azure IoT Hub team made a great job and created a desktop app that can be used to read, write device twins, see the list of devices, add new devices, sends commands and many more. The tool can be downloaded from here.
There is also a version for Node.JS - https://github.com/Azure/iothub-explorer
To be able to use this tool, you'll need to specify the connect string to IoT Hub in the first tab. Once you done this you can navigate to the 'Management' tab where all the devices that are registered are listed. Select one of the devices and click on 'Twin Pros'.
The new window displays all the information from device twin. Now, to set a new value of 'sensorDataTimeSampleInSec' will need to add it to the right panel and click on Send (as below).
Done, we set a new desired properties, that can be received by device.
Read how often sensor data are reported to backend from desired properties of device twin
The 'getTwin' method of Device.Client retrieves our device twin from the backend, including the desired properties.
The update of the configuration object is simple. Once we update it, the most simple thing that we can do is to write all the configuration back to config file. For this we will use a module called 'jsonfile' that can be used with success when you need to read/write objects to files in JSON format.
And we are done. We can now change the time interval from backend and automatically the device will update himself and change the sensor data time sample.
The code that was impacted by this changes is app.js and DeviceCommunication.js
Write how often sensor data are reported by device using reported properties
At this step we want to update the reported properties of device twin. In this way we can know what is the current configuration of our device and how often the the sensor data is reported. This action shall be called each time when the value of 'sensorDataTimeSampleInSec' is updated.
To update reported properties of device twin we need to create an object with the values that we want to report. The good thing is that we need to specify only the deltas. The one that we don't want to update will not be removed from the reported properties.
As we can see in the below image, each properties has a value that specifies when was updated.
This can be done as follow:
Remember
Next Step
Will create an Azure Function to connect our system to a heating pump.
http://vunvulearadu.blogspot.ro/2017/03/iot-home-project-part-8-connecting-to.html
Done, we set a new desired properties, that can be received by device.
Read how often sensor data are reported to backend from desired properties of device twin
The support from Azure IoT Hub is great from this perspective. The API is well documented, full with examples. On top of this there are SDKs for the most important programming languages.
But for now, if doesn't make sense to develop such an application.
Until now we used HTTP as communication protocol between device and Azure IoT Hub. To be able to use device twins, we need to change the protocol to MQTT. This change will not affect the current code. the only thing that we need to change is the protocol in the DeviceComunication.js.
var Protocol = require('azure-iot-device-mqtt').Mqtt;
We are done, we now use MQTT.The 'getTwin' method of Device.Client retrieves our device twin from the backend, including the desired properties.
client.getTwin((err, twin) => {
...
var sensorDataTimeSampleInSec = twin.properties.desired.sensorDataTimeSampleInSec;
...
}
In the previous step we specified in the desired properties of device twin a property called 'sensorDataTimeSampleInSec'. Once we get this information we need to update the Config object with the new value and update the configuration file.The update of the configuration object is simple. Once we update it, the most simple thing that we can do is to write all the configuration back to config file. For this we will use a module called 'jsonfile' that can be used with success when you need to read/write objects to files in JSON format.
// Update configuration
Config.sensorDataTimeSampleInSec = sensorDataTimeSampleInSec;
// Update configuration file.
Jsonfile.spaces = 4
Jsonfile.writeFileSync('./config.json', Config);
Once we done this we need to stop the timer that was set in 'collectSensorData' and start a new one with the new time interval. To be able to do this we need to store the object that is retried by 'setInterval' method and call clearInterval in the moment when we wast to stop it.
collectSensorInterval = setInterval((grovePiSensors, deviceCommunication) => {
...
// Device Twin updated
clearInterval(collectSensorInterval);
var grovePiSensors = new GrovePiSensors(Config.grovePiConfig);
collectSensorData(grovePiSensors, deviceCommunication);
The thing that I don't like is related to collectSensorInterval object that was set as global var in app.js. In this moment I didn't had time to find a better way how to persist this value and to be able to access it from the callback. For now it works.And we are done. We can now change the time interval from backend and automatically the device will update himself and change the sensor data time sample.
The code that was impacted by this changes is app.js and DeviceCommunication.js
Write how often sensor data are reported by device using reported properties
At this step we want to update the reported properties of device twin. In this way we can know what is the current configuration of our device and how often the the sensor data is reported. This action shall be called each time when the value of 'sensorDataTimeSampleInSec' is updated.
To update reported properties of device twin we need to create an object with the values that we want to report. The good thing is that we need to specify only the deltas. The one that we don't want to update will not be removed from the reported properties.
As we can see in the below image, each properties has a value that specifies when was updated.
This can be done as follow:
function deviceTwinReportUpdated(sensorDataTimeSampleInSec, twin) {
var patch = {
sensorDataTimeSampleInSec: sensorDataTimeSampleInSec
};
twin.properties.reported.update(patch, function (err) {
if (err && this.debug) {
console.log('Error reporting properties: ' + err);
} else {
console.log('Device Twin report completed: ' + JSON.stringify(patch));
}
});
}
We just set the new value and call update method of the reported property, where we specify the patch that we want to update.Remember
- Tags can be set, read and accessed only by backend
- Reported Properties are set by device can be read by backend
- Desired Properties are set by backend and can be read by backend
- Use version and lastUpdated properties to detect updates when necessary
Next Step
Will create an Azure Function to connect our system to a heating pump.
http://vunvulearadu.blogspot.ro/2017/03/iot-home-project-part-8-connecting-to.html
Comments
Post a Comment