Skip to main content

[IoT Home Project] Part 7 - Read/Write data to device twin

In this post we will discover how to:
  • 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
Previous post: [IoT Home Project] Part 6 - Stream Analytics and Power BI
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)
You might find odd that there are 2 types of properties/structures in device twin – tags and desired/reported properties. From the usability point of view, this is useful and handy. Tags are used when you want to store information related to a device on the backend without sending it to the device.
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 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

Popular posts from this blog

How to check in AngularJS if a service was register or not

There are cases when you need to check in a service or a controller was register in AngularJS.
For example a valid use case is when you have the same implementation running on multiple application. In this case, you may want to intercept the HTTP provider and add a custom step there. This step don’t needs to run on all the application, only in the one where the service exist and register.
A solution for this case would be to have a flag in the configuration that specify this. In the core you would have an IF that would check the value of this flag.
Another solution is to check if a specific service was register in AngularJS or not. If the service was register that you would execute your own logic.
To check if a service was register or not in AngularJS container you need to call the ‘has’ method of ‘inhector’. It will return TRUE if the service was register.
if ($injector.has('httpInterceptorService')) { $httpProvider.interceptors.push('httpInterceptorService&#…

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

[Post-Event] Codecamp Conference Cluj-Napoca - Nov 19, 2016

Last day I was invited to another Codecamp Conference, that took place in Cluj-Napoca. Like other Codecamp Conferences, the event was very big, with more than 1.000 participants and 70 sessions. There were 10 tracks in parallel, so it was pretty hard to decide at  what session you want to join.
It was great to join this conference and I hope that you discovered something new during the conference.
At this event I talked about Azure IoT Hub and how we can use it to connect devices from the field. I had a lot of demos using Raspberry PI 3 and Simplelink SensorTag. Most of the samples were written in C++ and Node.JS and people were impressed that even if we are using Microsoft technologies, we are not limited to C# and .NET. World and Microsoft are changing so fast. Just looking and Azure IoT Hub and new features that were launched and I'm pressed (Jobs, Methods, Device Twin).
On backend my demos covered Stream Analytics, Event Hub, Azure Object Storage and DocumentDB.

Title:
What abo…