Skip to content

Commit 00b497b

Browse files
Merge pull request #107357 from JimacoMS3/python-device-twin-howto-v2
Updated python device twin how-to for SDK
2 parents 11fb4cc + d513a48 commit 00b497b

File tree

5 files changed

+42
-54
lines changed

5 files changed

+42
-54
lines changed

articles/iot-hub/iot-hub-python-twin-getstarted.md

Lines changed: 42 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.service: iot-hub
66
services: iot-hub
77
ms.devlang: python
88
ms.topic: conceptual
9-
ms.date: 08/26/2019
9+
ms.date: 03/11/2020
1010
ms.author: robinsh
1111
---
1212
# Get started with device twins (Python)
@@ -23,7 +23,7 @@ At the end of this tutorial, you will have two Python console apps:
2323

2424
## Prerequisites
2525

26-
[!INCLUDE [iot-hub-include-python-installation-notes](../../includes/iot-hub-include-python-installation-notes.md)]
26+
[!INCLUDE [iot-hub-include-python-v2-installation-notes](../../includes/iot-hub-include-python-v2-installation-notes.md)]
2727

2828
* Make sure that port 8883 is open in your firewall. The device sample in this article uses MQTT protocol, which communicates over port 8883. This port may be blocked in some corporate and educational network environments. For more information and ways to work around this issue, see [Connecting to IoT Hub (MQTT)](iot-hub-mqtt-support.md#connecting-to-iot-hub).
2929

@@ -48,89 +48,73 @@ In this section, you create a Python console app that adds location metadata to
4848
1. In your working directory, open a command prompt and install the **Azure IoT Hub Service SDK for Python**.
4949

5050
```cmd/sh
51-
pip install azure-iothub-service-client
51+
pip install azure-iot-hub
5252
```
5353

54-
> [!NOTE]
55-
> The pip package for azure-iothub-service-client is currently available only for Windows OS. For Linux/Mac OS, please refer to the Linux and Mac OS-specific sections on the [Prepare your development environment for Python](https://github.com/Azure/azure-iot-sdk-python/blob/v1-deprecated/doc/python-devbox-setup.md) post.
56-
>
57-
5854
2. Using a text editor, create a new **AddTagsAndQuery.py** file.
5955

6056
3. Add the following code to import the required modules from the service SDK:
6157

6258
```python
6359
import sys
64-
import iothub_service_client
65-
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod
66-
from iothub_service_client import IoTHubDeviceTwin, IoTHubError
60+
from time import sleep
61+
from azure.iot.hub import IoTHubRegistryManager
62+
from azure.iot.hub.models import Twin, TwinProperties, QuerySpecification, QueryResult
6763
```
6864

6965
4. Add the following code. Replace `[IoTHub Connection String]` with the IoT hub connection string you copied in [Get the IoT hub connection string](#get-the-iot-hub-connection-string). Replace `[Device Id]` with the device ID you registered in [Register a new device in the IoT hub](#register-a-new-device-in-the-iot-hub).
7066

7167
```python
72-
CONNECTION_STRING = "[IoTHub Connection String]"
68+
IOTHUB_CONNECTION_STRING = "[IoTHub Connection String]"
7369
DEVICE_ID = "[Device Id]"
74-
75-
UPDATE_JSON = "{\"properties\":{\"desired\":{\"location\":\"Redmond\"}}}"
76-
77-
UPDATE_JSON_SEARCH = "\"location\":\"Redmond\""
78-
UPDATE_JSON_CLIENT_SEARCH = "\"connectivity\":\"cellular\""
7970
```
8071

8172
5. Add the following code to the **AddTagsAndQuery.py** file:
8273

8374
```python
8475
def iothub_service_sample_run():
8576
try:
86-
iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)
87-
88-
iothub_registry_statistics = iothub_registry_manager.get_statistics()
89-
print ( "Total device count : {0}".format(iothub_registry_statistics.totalDeviceCount) )
90-
print ( "Enabled device count : {0}".format(iothub_registry_statistics.enabledDeviceCount) )
91-
print ( "Disabled device count : {0}".format(iothub_registry_statistics.disabledDeviceCount) )
92-
print ( "" )
77+
iothub_registry_manager = IoTHubRegistryManager(IOTHUB_CONNECTION_STRING)
9378

94-
number_of_devices = iothub_registry_statistics.totalDeviceCount
95-
dev_list = iothub_registry_manager.get_device_list(number_of_devices)
79+
new_tags = {
80+
'location' : {
81+
'region' : 'US',
82+
'plant' : 'Redmond43'
83+
}
84+
}
9685

97-
iothub_twin_method = IoTHubDeviceTwin(CONNECTION_STRING)
86+
twin = iothub_registry_manager.get_twin(DEVICE_ID)
87+
twin_patch = Twin(tags=new_tags, properties= TwinProperties(desired={'power_level' : 1}))
88+
twin = iothub_registry_manager.update_twin(DEVICE_ID, twin_patch, twin.etag)
9889

99-
for device in range(0, number_of_devices):
100-
if dev_list[device].deviceId == DEVICE_ID:
101-
twin_info = iothub_twin_method.update_twin(dev_list[device].deviceId, UPDATE_JSON)
90+
# Add a delay to account for any latency before executing the query
91+
sleep(1)
10292

103-
print ( "Devices in Redmond: " )
104-
for device in range(0, number_of_devices):
105-
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)
93+
query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'")
94+
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
95+
print("Devices in Redmond43 plant: {}".format(', '.join([twin.device_id for twin in query_result.items])))
10696

107-
if twin_info.find(UPDATE_JSON_SEARCH) > -1:
108-
print ( dev_list[device].deviceId )
97+
print()
10998

110-
print ( "" )
99+
query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity = 'cellular'")
100+
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
101+
print("Devices in Redmond43 plant using cellular network: {}".format(', '.join([twin.device_id for twin in query_result.items])))
111102

112-
print ( "Devices in Redmond using cellular network: " )
113-
for device in range(0, number_of_devices):
114-
twin_info = iothub_twin_method.get_twin(dev_list[device].deviceId)
115-
116-
if twin_info.find(UPDATE_JSON_SEARCH) > -1:
117-
if twin_info.find(UPDATE_JSON_CLIENT_SEARCH) > -1:
118-
print ( dev_list[device].deviceId )
119-
120-
except IoTHubError as iothub_error:
121-
print ( "Unexpected error {0}".format(iothub_error) )
103+
except Exception as ex:
104+
print("Unexpected error {0}".format(ex))
122105
return
123106
except KeyboardInterrupt:
124-
print ( "IoTHub sample stopped" )
107+
print("IoT Hub Device Twin service sample stopped")
125108
```
126109

127-
The **Registry** object exposes all the methods required to interact with device twins from the service. The code first initializes the **Registry** object, then updates the device twin for **deviceId**, and finally runs two queries. The first selects only the device twins of devices located in the **Redmond43** plant, and the second refines the query to select only the devices that are also connected through cellular network.
110+
The **IoTHubRegistryManager** object exposes all the methods required to interact with device twins from the service. The code first initializes the **IoTHubRegistryManager** object, then updates the device twin for **DEVICE_ID**, and finally runs two queries. The first selects only the device twins of devices located in the **Redmond43** plant, and the second refines the query to select only the devices that are also connected through a cellular network.
128111

129112
6. Add the following code at the end of **AddTagsAndQuery.py** to implement the **iothub_service_sample_run** function:
130113

131114
```python
132115
if __name__ == '__main__':
133-
print ( "Starting the IoT Hub Device Twins Python service sample..." )
116+
print("Starting the Python IoT Hub Device Twin service sample...")
117+
print()
134118

135119
iothub_service_sample_run()
136120
```
@@ -203,16 +187,16 @@ In this section, you create a Python console app that connects to your hub as yo
203187
while True:
204188
time.sleep(1000000)
205189
except KeyboardInterrupt:
206-
print ( "IoTHubClient sample stopped" )
190+
print ( "IoT Hub Device Twin device sample stopped" )
207191
```
208192

209-
The **Client** object exposes all the methods you require to interact with device twins from the device. The previous code, after it initializes the **Client** object, retrieves the device twin for your device and updates its reported property with the connectivity information.
193+
The **IoTHubModuleClient** object exposes all the methods you require to interact with device twins from the device. The previous code, after it initializes the **IoTHubModuleClient** object, retrieves the device twin for your device and updates its reported property with the connectivity information.
210194

211195
6. Add the following code at the end of **ReportConnectivity.py** to implement the **iothub_client_sample_run** function:
212196

213197
```python
214198
if __name__ == '__main__':
215-
print ( "Starting the IoT Hub Device Twins Python client sample..." )
199+
print ( "Starting the Python IoT Hub Device Twin device sample..." )
216200
print ( "IoTHubModuleClient waiting for commands, press Ctrl-C to exit" )
217201

218202
iothub_client_sample_run()
@@ -224,9 +208,9 @@ In this section, you create a Python console app that connects to your hub as yo
224208
python ReportConnectivity.py
225209
```
226210

227-
You should see confirmation the device twins were updated.
211+
You should see confirmation the device twin reported properties were updated.
228212

229-
![update twins](./media/iot-hub-python-twin-getstarted/device-1.png)
213+
![update reported properties from device app](./media/iot-hub-python-twin-getstarted/device-1.png)
230214

231215
8. Now that the device reported its connectivity information, it should appear in both queries. Go back and run the queries again:
232216

@@ -236,7 +220,11 @@ In this section, you create a Python console app that connects to your hub as yo
236220

237221
This time your **{Device ID}** should appear in both query results.
238222

239-
![second query](./media/iot-hub-python-twin-getstarted/service-2.png)
223+
![second query on service app](./media/iot-hub-python-twin-getstarted/service-2.png)
224+
225+
In your device app, you'll see confirmation that the desired properties twin patch sent by the service app was received.
226+
227+
![receive desired properties on device app](./media/iot-hub-python-twin-getstarted/device-2.png)
240228

241229
## Next steps
242230

-1.24 KB
Loading
11.8 KB
Loading
-2.49 KB
Loading
-3.67 KB
Loading

0 commit comments

Comments
 (0)