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: 

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 - 

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 =;
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
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
  };, 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.


  • 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.


Popular posts from this blog

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 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 …

GET call of REST API that contains '/'-slash character in the value of a parameter

Let’s assume that we have the following scenario: I have a public HTTP endpoint and I need to post some content using GET command. One of the parameters contains special characters like “\” and “/”. If the endpoint is an ApiController than you may have problems if you encode the parameter using the http encoder.
using (var httpClient = new HttpClient()) { httpClient.BaseAddress = baseUrl; Task<HttpResponseMessage> response = httpClient.GetAsync(string.Format("api/foo/{0}", "qwert/qwerqwer"))); response.Wait(); response.Result.EnsureSuccessStatusCode(); } One possible solution would be to encode the query parameter using UrlTokenEncode method of HttpServerUtility class and GetBytes method ofUTF8. In this way you would get the array of bytes of the parameter and encode them as a url token.
The following code show to you how you could write the encode and decode methods.

Entity Framework (EF) TransactionScope vs Database.BeginTransaction

In today blog post we will talk a little about a new feature that is available on EF6+ related to Transactions.
Until now, when we had to use transaction we used ‘TransactionScope’. It works great and I would say that is something that is now in our blood.
using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (SqlConnection conn = new SqlConnection("...")) { conn.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = conn; sqlCommand.CommandText = ... sqlCommand.ExecuteNonQuery(); ... } scope.Complete(); } Starting with EF6.0 we have a new way to work with transactions. The new approach is based on Database.BeginTransaction(), Database.Rollback(), Database.Commit(). Yes, no more TransactionScope.
In the followi…