Python Azure IoT SDK: How to use device twins in IoT Hub
Introduction
Recently, Microsoft has released the new version of Python Azure IoT SDK (V2.0) (refer to this page on IoT blog: New version of the Python SDK released). According to the release announcement, we should upgrade SDK from V1 to V2 since the v2 SDK aims to provide a simplified, more natural experience for developers. It’s designed in native Python.
In the previous tutorials, we first Installed the new Python Azure IoT SDK on Windows 10 and made a demo Python project with Visual Studio to send simulation date to the Azure IoTHub. Then we showed how to invoke Direct Methods from Backend App. For more details, please refer to the pervious toturials:
- How to use Python Azure IoT SDK with Visual Studio
- How to receive direct methods from IoT Hub with Python Azure IoT SDK
In this article, we will walk you through the steps required to build a sample application for sending and receiving device twins from IoT Hub with Python Azure IoT SDK.
Device twins in IoT Hub
Device twins are JSON documents that store device state information including metadata, configurations, and conditions. Azure IoT Hub maintains a device twin for each device that you connect to IoT Hub. Device twins are very useful to store device-specific metadata in the cloud, report current state information from your device app, and synchronize the state between device app and back-end app. The overview of the device twins is shown in Fig. 1.
Fig. 1 Overview of device twins
A device twin is a JSON document that includes:
- Tags. A section of the JSON document that the solution back end can read from and write to. Tags are not visible to device apps.
- Desired properties. Used along with reported properties to synchronize device configuration or conditions. The solution back end can set desired properties, and the device app can read them. The device app can also receive notifications of changes in the desired properties.
- Reported properties. Used along with desired properties to synchronize device configuration or conditions. The device app can set reported properties, and the solution back end can read and query them.
- Device identity properties. The root of the device twin JSON document contains the read-only properties from the corresponding device identity stored in the identity registry.
For more information about device twins, please refer to this page “Understand and use device twins in IoT Hub”.
Prerequisites
1. Windows 10 with Visual Studio 2019 Community (“Python development” workload required)
2. Python Azure IoT SDK: https://github.com/Azure/azure-iot-sdk-python/tree/master/azure-iot-device/samples
Reported properties of the device twins
First, we will demonstrate how to use reported properties of the device twins. Create a Python project with “Python Application” project temple, give a name such as “PythonIoTDemo”. Copy and paste the following code to “PythonIoTDemo.py”. Make sure that you substitute with your own connection string in the code.
import os
import asyncio
import random
from azure.iot.device.aio import IoTHubDeviceClient
async def main():
conn_str = "HostName=***.azure-devices.net;DeviceId=***;SharedAccessKey=***"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
# connect the client.
await device_client.connect()
# update the reported properties
reported_properties = {"temperature": random.randint(320, 800) / 10}
print("Setting reported temperature to {}".format(reported_properties["temperature"]))
await device_client.patch_twin_reported_properties(reported_properties)
# Finally, disconnect
await device_client.disconnect()
if __name__ == "__main__":
asyncio.run(main())
# If using Python 3.6 or below, use the following code instead of asyncio.run(main()):
# loop = asyncio.get_event_loop()
# loop.run_until_complete(main())
# loop.close()
In this application, we will report the temperature with a random value between 32.0 and 80.0. Once the device twin is sent, we will see the output message as shown in Fig. 2.
Fig. 2 Debug output in Visual Studio
Now, as soon as the Azure IoTHub receive the device twin, we can see the instant value on Azure Portal as presented in Fig. 3.
Fig. 3 Device twin on Azure portal
Desire properties of the device twins
Now, if we want to update the configurations in the device, we can use desire properties of the device twins. Create a Python project with “Python Application” project temple, give a name such as “PythonIoTDemo”. Copy and paste the following code to “PythonIoTDemo.py”. Make sure that you substitute with your own connection string in the code.
import os
import asyncio
import random
from azure.iot.device.aio import IoTHubDeviceClient
async def main():
conn_str = "HostName=***.azure-devices.net;DeviceId=***;SharedAccessKey=***"
device_client = IoTHubDeviceClient.create_from_connection_string(conn_str)
# connect the client.
await device_client.connect()
# define behavior for receiving a twin patch
async def twin_patch_listener(device_client):
while True:
patch = await device_client.receive_twin_desired_properties_patch() # blocking call
print("the data in the desired properties patch was: {}".format(patch))
# define behavior for halting the application
def stdin_listener():
while True:
selection = input("Press Q to quit\n")
if selection == "Q" or selection == "q":
print("Quitting...")
break
# Schedule task for twin patch
asyncio.create_task(twin_patch_listener(device_client))
# Run the stdin listener in the event loop
loop = asyncio.get_running_loop()
user_finished = loop.run_in_executor(None, stdin_listener)
# Wait for user to indicate they are done listening for messages
await user_finished
# Finally, disconnect
await device_client.disconnect()
if __name__ == "__main__":
asyncio.run(main())
# If using Python 3.6 or below, use the following code instead of asyncio.run(main()):
# loop = asyncio.get_event_loop()
# loop.run_until_complete(main())
# loop.close()
Run the application. Then, we add the following “desired” JSON code to the Device twin on Azure Portal
"desired": {
"temperature": 40.1,
"telemetryConfig": {
"sendFrequency": "1m"
},
"$metadata": {}
},
Which is shown in Fig. 4.
Fig. 4 Add desired properties to the device twin
Now, as soon as the device receives the desired properties, it will print the settings in the output windows as shown in Fig. 5
Fig. 5 The received desired properties of the device twin
We can see that not only the device twins are received, but also the version of the message is added automatically.
Summary
In this tutorial, we have presented the process to use device twins of Azure IoT Python SDK, including “reported properties of the device twin” and “desired properties of the device twin”.
Resources
- Microsoft Docs: Understand and use device twins in IoT Hub
- IoT Blog: New version of the Python SDK released
- azure-iot-sdk-python: https://github.com/Azure/azure-iot-sdk-python/tree/master/azure-iot-device/samples
- My Projects on Hackster: Jiong Shi
- Azure IoT Docs: Azure IoTHub
See Also
- How to use Python Azure IoT SDK with Visual Studio
- Python Azure IoT SDK: How to receive direct methods from IoT Hub
- Python Azure IoT SDK: How to use device provision service with symmetric keys
- Python Azure IoT SDK: How to send and receive C2D messages
- Build a Azure Sphere IoT Car with Remote Control