A digital twin is a cloud representation of the state of a physical device.
In Azure IoT Hub, this twin is called the Device Twin. It allows us to have properties reported by the device, desired properties from the cloud, and direct methods to request specific actions.
It is not just about sending data periodically. It is about turning the device into something the cloud can query, configure, and govern in an orderly manner.
Here we are talking about the IoT Hub Device Twin. Azure Digital Twins is another, broader service for modeling buildings, factories, or complete systems. They are related by concept, but are not exactly the same.
Reported and Desired Properties
A Device Twin has two important groups of properties:
- Reported properties: Written by the device. For example, firmware, battery, IP, current temperature, or active mode.
- Desired properties: Written by the cloud. For example, alarm threshold, sampling frequency, or whether to activate a power-saving mode.
The idea is simple: the device says “this is my state”, and the cloud says “this is how I want you to be configured”.
Reading the Twin from nanoFramework
The DeviceClient class allows you to get the current twin using GetTwin. From there, you can review its desired properties and apply configuration.
using System.Diagnostics;
using System.Threading;
using nanoFramework.Azure.Devices.Client;
using nanoFramework.Azure.Devices.Shared;
DeviceClient client = new DeviceClient(
"my-hub.azure-devices.net",
"esp32-salon",
"DEVICE_KEY");
if (client.Open())
{
Twin twin = client.GetTwin(new CancellationTokenSource(10000).Token);
if (twin?.Properties?.Desired != null &&
twin.Properties.Desired.Contains("samplePeriodSeconds"))
{
int samplePeriod = (int)twin.Properties.Desired["samplePeriodSeconds"];
Debug.WriteLine($"New sampling period: {samplePeriod}s");
}
}With this, the cloud can change the configuration without reflashing the ESP32, which is especially useful on remotely deployed devices.
Reporting Device Status
We can also send reported properties using UpdateReportedProperties. This is not fast telemetry, but relatively stable status.
using nanoFramework.Azure.Devices.Shared;
TwinCollection reported = new TwinCollection();
reported.Add("firmware", "1.0.3");
reported.Add("wifiRssi", -62);
reported.Add("samplePeriodSeconds", 30);
reported.Add("status", "running");
bool ok = client.UpdateReportedProperties(
reported,
new CancellationTokenSource(10000).Token);When viewed from Azure IoT Hub, you will have a device card with its status. Very convenient for administration panels, technical support, or deployments with many nodes.
Use reported properties for things that change little. For constant sensor readings, stick to normal telemetry with SendMessage.
Direct Methods
Direct methods are used to ask the device to do something right now. For example:
- Reboot itself.
- Temporarily change mode.
- Turn on a relay.
- Force a sensor reading.
- Activate a calibration routine.
In nanoFramework, we register a function using AddMethodCallback.
using System.Diagnostics;
using nanoFramework.Azure.Devices.Client;
client.AddMethodCallback(OnDirectMethod);
private static string OnDirectMethod(int requestId, string payload)
{
Debug.WriteLine($"Method received. RequestId: {requestId}");
Debug.WriteLine($"Payload: {payload}");
// Execute the actual action here.
// For example, change a mode, turn on a GPIO, or reboot.
return "{ \"result\": \"ok\" }";
}The method returns a JSON response. Do not turn it into an endless operation: a direct method should be fast and predictable.
Do not use direct methods for long processes that could block the device. For that, it is better to receive the command, save a pending task, and respond quickly.
A Practical Pattern
A fairly clean structure for a real device would be:
- On startup, connect Wi-Fi and open
DeviceClient. - Read the
Twinto load desired configuration. - Report firmware version, IP, RSSI, and initial status.
- Send periodic telemetry with
SendMessage. - Listen for direct methods for specific actions.
- Report important status changes.
With this pattern, the device is no longer a black box. The cloud knows what version it has, how it is configured, and whether it responds to commands.
Digital twins make an IoT project much more manageable. We no longer just send temperature every 30 seconds. Now we can configure the device from the cloud, know its status, and request specific actions.