Guide to Setting up Azure Digital Twin with IoT Hub and Raspberry Pi

Protonest IoT
12 min readOct 17, 2024

--

Guide to Setting up Azure Digital Twin with IoT Hub and Raspberry Pi with DHT11

A Digital Twin is a virtual model of a physical object, process, or system. With the use of cloud computing and the Internet of Things (IoT), you can simulate the real-time behavior of the physical systems through a digital interface.

Azure Digital Twins is one of the key services provided by Microsoft that allows you to model, monitor, and manage physical environments from the cloud.

In this guide, we will walk you through setting up a Digital Twin instance on Azure and integrating a Raspberry Pi with a DHT11 temperature and humidity sensor.

We will further explain how you can send real-time sensor data to Azure Digital Twins using an Azure Function. By the end of this guide, you will have a Digital Twin model that can visualize sensor data from your Raspberry Pi in the cloud.

Components Needed

Circuit Diagram

Digital Twin Setup Guide

Build the Azure Account

  • Enter to the Azure Website and create a new account by providing required details.

Create .Json file to make Digital Twin instance

  • Create following Json file named “demoTempmodel.json” using VScode.
{
"@context": "dtmi:dtdl:context;2",
"@id": "dtmi:demo:Factory;1",
"@type": "Interface",
"displayName": "Factory Interface Model",
"contents": [
{
"@type": "Property",
"name": "Temperature",
"schema": "double"
},
{
"@type": "Property",
"name": "Humidity",
"schema": "double"
}
]
}

Create a Digital Twin instance on the Azure portal

  • First, enter the Microsoft Azure portal and select Azure Digital Twins from Azure services.
  • Select “create” and enter the required names and details into relevant columns.
  • Click the “Review + create” option.
  • Then click the “Create” option.
  • After deployment complete you can get the Host name and Provisioning state for the digital twin.
  • Update User access permissions by clicking the Access Control (IAM) on demotempdigitaltwin and select “+add” option.
  • Select Add role assignment and enter the email to Azure Digital Twins data owner which is later required to implement the digital twin explorer (The same account can be used which you use to create the account on Azure).

Open Digital Twin Explorer

  • You can open the Digital twin explorer by simply click the “open Azure Digital twins Explorer(preview)” under “overview” in the menu bar. (You need to allow the popups for authentication on the browser).
  • Then select the “upload model” and select the previously saved “demoTempmodel.json” file and upload it.
  • Now, you can view the information of the model by clicking 3 dots on the model and selecting “view model”.
  • Then you have to build the twin for the model by clicking 3 dots on the model and selecting “create a twin”, and naming the twin.
  • You can simply click on the twin, and edit the twin’s parameter and save to process the twin’s data.
  • You can check the twin’s data processing by updating the queries and running them through “Run Query”.

Eg: You can update the query as “SELECT * FROM digitaltwins T WHERE T.Humidity > 60” and click “run query”, the twin will be invisible because the updated twin’s temperature parameters are 28. When we update the query as “SELECT * FROM digitaltwins T WHERE T.Humidity < 60” and run it, then the twin will visible.

  • The Twin build is finished.

Setting Up IoT Hub

  • Go back to the Microsoft Azure Dashboard.
  • Click “select create resource” on the home of Azure portal, enter “IoTHub” on search and select “create” on the IoT Hub menu.
  • Fill the details (remember to fill same resource group, IoT hub name and Region as previous twins’ details) and enter “review+create”.
  • Then Select “Go to Resource”.
  • On the overview you can see the “Host name”, “Tier”, “Daily Message Limit” and “Status” of your IoT Hub.
  • Select the “Devices” under the “Device Management”.
  • Select “+ Add Device” on the Device menu.
  • Fill in the Device ID same as our digital Twin (temphumitwin), leave others as default, and click save.
  • The IoT Hub should look like below,

Develop the Azure function for connect the Twin and real sensor

  • Download and open the Visual Studio Newer Version (Visual Studio Community 2022 used for this demo) and Enter the “Create a new Project”.
  • Search “Azure Function” and Select the Azure function option.
  • Name the project as your favor, and click Next,
  • Select the function as “Event Grid Trigger” while others remain default and click Next.
  • The Project Template display as follow,
  • Then we need to install required packages to our project and you can install the packages by right clicking on your project and select the “Manage NuGet Packages”.
  • Browse and install Following Packages

Azure.DigitalTwins.Core

Azure.Identity

System.Net.Http

Azure.Core

Newtonsoft.Json

  • Copy and paste the following code on “Function1.cs”,
using System;
using System.Text;
using System.Threading.Tasks;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using Azure.Messaging.EventGrid;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Azure.Core.Pipeline;
using System.Net.Http;
using Azure;

namespace Temptwiningestfunction
{
public static class Function1
{
private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
private static readonly HttpClient singletonHttpClientInstance = new HttpClient();

[Function("IOTHubtoTwins")]
public async static Task Run([EventGridTrigger] EventGridEvent eventGridEvent, FunctionContext context)
{
var log = context.GetLogger("IOTHubtoTwins");

if (string.IsNullOrEmpty(adtInstanceUrl))
{
log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
return;
}

try
{
// Authenticate using Managed Identity
var credential = new DefaultAzureCredential();
var client = new DigitalTwinsClient(
new Uri(adtInstanceUrl),
credential,
new DigitalTwinsClientOptions
{
Transport = new HttpClientTransport(singletonHttpClientInstance)
});

log.LogInformation("ADT service client connection created.");

if (eventGridEvent != null && eventGridEvent.Data != null)
{
log.LogInformation($"Event received: {eventGridEvent.Data.ToString()}");

// Parse the event data
JObject eventDataObject = JObject.Parse(eventGridEvent.Data.ToString());

// Extract the device ID
string deviceId = (string)eventDataObject["systemProperties"]?["iothub-connection-device-id"];
if (string.IsNullOrEmpty(deviceId))
{
log.LogError("Device ID not found in event data.");
return;
}

// Get the body object directly
JObject bodyObject = eventDataObject["body"] as JObject;
if (bodyObject == null)
{
log.LogError("Message body is empty or not a JSON object.");
return;
}

log.LogInformation($"Message body: {bodyObject.ToString()}");

// Extract temperature and humidity
var temperature = bodyObject["Temperature"];
var humidity = bodyObject["Humidity"];

if (temperature == null || humidity == null)
{
log.LogError("Temperature or Humidity not found in message body.");
return;
}

// Log the extracted values
log.LogInformation($"Device: {deviceId}, Temperature: {temperature}, Humidity: {humidity}");

// Prepare the update payload for Digital Twin
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendReplace("/Temperature", temperature.Value<double>());
updateTwinData.AppendReplace("/Humidity", humidity.Value<double>());

// Update the Digital Twin
await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);

log.LogInformation($"Digital Twin '{deviceId}' updated successfully.");
}
else
{
log.LogWarning("Event data is null.");
}
}
catch (Exception ex)
{
log.LogError($"Error in ingest function: {ex.Message}");
log.LogError($"Stack Trace: {ex.StackTrace}");
}
}
}
}
  • Save and Right Click on your project name and select the publish.
  • Then Select Azure and Click Next,
  • Select “Azure Function App (Windows)” and click Next.
  • Remember you need to sign in with the same email address which you assign with the Azure subscription. Select the “+ Create New” to create the new function.
  • Update the subscription type and locations and click create.
  • Then you can click finish.
  • You can click on publish to publish your digital twin function.
  • The interface should look as follows after successfully published the Azure function.

Note: If you want to change the function code, just open function1.cs change (paste the code) and save. Right-click on your project name, choose publish and after opening the above window select publish blue color button and wait for successfully publish the code.

  • Then you need to check the published function in Azure portal by search the function name on the search bar and select the function if it is available.
  • You will see the our IoTHubtoTwins function under the Temptwiningestfunction.
  • Next, we need to setup security access to Azure function, without using credentials. Go to Identity under Settings, Select Status to On and click save.
  • Select Azure role assignment, press “+Add role assignment” and fill the spaces as follow, and click save.
  • The assigned roles are as follows,
  • Then we need to set environmental variables to make the URL of azure digital twins’ variables to access the function. First go to the Azure digital twins’ instance (demotempdigitaltwin) and copy the Host name.
  • Go back to our function and select Environmental variable under the settings, select ”+Add”, fill name as “ADT_SERVICE_URL” and fill the value as you previously copied Hostname. Press “Apply”.

Connect IoTHub with function

  • Search “subscription” on search bar and select subscription.
  • Then select your subscription.
  • Then select resource providers under settings,
  • Search Microsoft.EventGrid under filter and select it and register that by press register.
  • After that return to Home.
  • Navigate to the IoTHub created earlier, go to the event tab, and click the “+Event subscription”.
  • Fill the following details,
Name: adt-event-subscription
System Topic Name: adt-system-topic
Filter to Event Type: Only select Device Telemetry
Endpoint Type: Select Azure Function
Press “configure an endpoint” autofill the spaces and you need to press confirm selection.
Then click on “Create”.
  • Then you can see the Event subscription appeared under Event.

Connecting Azure Twin with the real sensor system

  • First, we need to setup raspberry pi with the DHT11 sensor. Use following circuit diagram to setup the raspberrypi,
  • Open the terminal on raspberry pi and install the python by enter following command in the terminal,
sudo apt-get update
sudo apt-get upgrade -y
  • Python usually comes pre-installed on Raspberry Pi OS.
1. Verify the installation:
python3 - - version
2. If Python 3 is not installed, install it:
sudo apt-get install python3
3. Install Pip for Python 3:
sudo apt-get install python3-pip
  • Install Adafruit DHT11 Library by enter following commands on the terminal.
1. Install build tools:
sudo apt-get install build-essential python3-dev
2. Download and install the library:
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT
sudo python3 setup.py install –force-pi
  • Install IoT device SDK by enter following command on the terminal.
sudo pip3 install azure-iot-device –break-system-packages
sudo apt-get install libssl-dev libffi-dev
sudo pip3 install azure-iot-hub –break-system-packages
  • Then we need to create a new python script by enter following command on raspberry pi terminal.
nano raspberrypiprogram.py
  • Paste the following code into editor,
import asyncio
import signal
import sys
import time
import board
import adafruit_dht
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import Message
import json

# Initialize the DHT11 sensor connected to GPIO4
dhtDevice = adafruit_dht.DHT11(board.D4)

# Azure IoT Hub connection details
DEVICE_CONNECTION_STRING = "HostName=demotempdigitaltwin.azure-devices.net;DeviceId=temphumitwin;SharedAccessKey=D0ZipOuTri19VJcKonifW5wAI2dYleCVBAIoTIle4Go="

# Cancellation event
stop_event = asyncio.Event()

def handle_exit(*args):
print("Exiting...")
stop_event.set()

async def send_device_to_cloud_message():
# Create instance of the device client using the connection string
device_client = IoTHubDeviceClient.create_from_connection_string(DEVICE_CONNECTION_STRING)
await device_client.connect()

try:
while not stop_event.is_set():
try:
# Read temperature and humidity from the DHT11 sensor
temperature_c = dhtDevice.temperature
humidity = dhtDevice.humidity

if humidity is not None and temperature_c is not None:
# Create the telemetry message JSON
telemetry_data = {
"Temperature": temperature_c,
"Humidity": humidity
}
message = Message(json.dumps(telemetry_data))
message.content_encoding = "utf-8"
message.content_type = "application/json"

# Send the message to Azure IoT Hub
print(f"{time.strftime('%Y-%m-%d %H:%M:%S')} > Sending message: {telemetry_data}")
await device_client.send_message(message)
print("Message successfully sent")
else:
print("Failed to retrieve data from sensor")

except RuntimeError as error:
# Handle sensor read errors
print(f"Reading from DHT failure: {error.args[0]}")

# Wait before sending the next message (e.g., 5 seconds)
await asyncio.sleep(5)

except asyncio.CancelledError:
pass
finally:
await device_client.shutdown()
dhtDevice.exit()

async def main():
# Set up signal handlers for graceful shutdown
loop = asyncio.get_running_loop()
for sig in (signal.SIGINT, signal.SIGTERM):
loop.add_signal_handler(sig, handle_exit)

print("Press Ctrl+C to exit")
await send_device_to_cloud_message()

if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
pass
  • Copy the connection string from the demotempdigitaltwin IoT hub by navigating to the your IoT hub in Azure portal, selecting the devices and click your device ID. Then you see the keys and strings from that you need to copy the “primary connection string” and replace it in your python code.
  • Run the python script
python3 dht11_azure_iot.py
  • If you get errors on Adafruit_DHT11 libraries type following commands on the terminal,
sudo pip3 uninstall Adafruit_DHT –break-system-packages
sudo pip3 install adafruit-circuitpython-dht –break-system-packages
sudo apt-get install libgpiod2 –break-system-packages
  • You can see the data update on the terminal and the Azure IoTHub Events.
  • Open IoT digital Twin explorer and you can see your digital twin on the twin graph, press “Run Query” and that will update the object Temperature and Humidity.

Through this article, you will be able to make an Azure digital twin implementation using a real sensor from scratch.

Hope you enjoyed the article. Please comment below or send us an email to info@protonest.co, if you face any issues when implementing.

Contact us for any consultations or projects related to IoT and embedded systems.

Email: info@protonest.co

Protonest for more details.

Protonest specializes in transforming IoT ideas into reality. We offer prototyping services from concept to completion. Our commitment ensures that your visionary IoT concepts become tangible, innovative, and advanced prototypes.

Our Website: https://www.protonest.co/

Cheers!

--

--

Protonest IoT
Protonest IoT

Written by Protonest IoT

We make your IoT ideas a reality

No responses yet