In today’s article I’d like to discuss Device Twins and how you can use them with Azure IoT Hub. I will be discussing what Device Twins are, how they are used and then provide a code example of using them with Azure IoT Hub.
What are Device Twins?
Device Twins are JSON documents that store state information about IoT devices. This includes state information along with metadata about the device. Configurations and conditions on the device are also stored. Azure IoT Hub maintains a device twin for each registered device that is connected to that hub.
You can use Device Twins to store specific metadata about your devices in the cloud. For example, you can keep track of a device location by storing location metadata about that device in its Device Twin.
Device Twins can also be used to report state information about the device. This can be useful to determine if a device is connected to IoT Hub, or if it is connected to a WiFi network.
Additionally, the process of updating the firmware on one or more devices can benefit from Device Twins, as firmware installation progress can be reported to a back-end application.
Device Twin Structure
The JSON document that makes up a Device Twin has a few components that I will describe in this section. Here is an example of the overall JSON structure of a Device Twin:

Tags
The Tags section is used exclusively by a back-end solution. Device applications cannot see or query tags at all, but a back-end solution does have the capability to read/write tag values to this section of the Device Twin. The information in this section can be whatever identifying data you need on the back-end solution side. Here is an example, which shows tags for the device location:
{ … "tags": { "deviceLocation": { "city": "Chicago", "building": "Willis Tower", "floor": "12", "room": "NE Conf 1" } }, … }
Reported Properties
This section is used in coordination with the Desired Properties section to synchronize device configurations. The device application has the capability to read and write data to this section while a back-end solution can read information from this section as well as receive change notifications when data changes. Typically, this section is used by the device application to report its current state to the cloud.
For example, let us say that we want to report to a back-end solution the current WiFi information for the device. We would serialize the following JSON string into the proper format for Reported Properties and then report the state to the IoT Hub that the device is registered with.
{ … "properties": { … "reported": { "wifi.wifiIP": “192.168.3.100”, "wifi.wifiMask": “255.255.255.0” } } }

The IoT Hub that maintains the Device Twin for the registered device would update the information being received from the device. In our example, the WiFi IP and Mask values would be updated accordingly in the device’s device twin. A solution back-end can then query the Reported Properties to retrieve these values.

Desired Properties
This section is used in coordination with the Reported Properties section to synchronize device configurations. A back-end solution has the capability to read and write data to this section, and the device application can read and receive change notifications for this section. Typically, this section is used by a back-end solution to communicate to the device of some change requested that the device application should handle.
For example, let us say that we want to change the interval time value on the device that is used for sending data to IoT Hub. A back-end solution could update the desired properties and that change would be communicated to the device. As shown in the JSON snippet below we can set the ‘sendDataInterval’ value in the Desired Properties section to ‘5000’ indicating we want to set the interval value on the device to 5 seconds.
{ … "properties": { "desired": { "sendDataInterval": "5000 }, … } }

When a change is made to the Desired Properties for a device, a notification event is sent to that device informing the device of the change. Code on the device would configure a Device Twin callback method that would be fired when the change notification is sent to the device.

The callback method would extract the JSON information which would contain the Desired Properties section of that device’s Device Twin record. The code would then be able to interpret what has changed and perform whatever necessary actions are required.

A device application should perform whatever actions necessary to process the change in the Desired Properties and then send back an update (via the Reported Properties) to the cloud.
Device Identity Properties
This is the root of the JSON document and contains the read-only properties that specify the device identity. This information can be used to retrieve the device identity along with connection state and authentication type.
{ "deviceId": "devA", "etag": "AAAAAAAAAAc=", "status": "enabled", "statusReason": "provisioned", "statusUpdateTime": "0001-01-01T00:00:00", "connectionState": "connected", "lastActivityTime": "2015-02-30T16:24:48.789Z", "cloudToDeviceMessageCount": 0, "authenticationType": "sas", "x509Thumbprint": { "primaryThumbprint": null, "secondaryThumbprint": null }, "version": 2, … }
I hope this article was helpful in explaining the details of Device Twins. For more detailed information please visit https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-device-twins.
If you would like to download the full source code for this example, please visit my github repository here.
Thanks for reading!