Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit aabb34f

Browse files
cartertinneypierreca
authored andcommitted
Changed Python quickstarts and tutorials to use V2 SDK (#15)
* Changed quickstarts to use V2 SDK Edge tutorial compatibility with V2 SDK * fixed message bug
1 parent d4ff76c commit aabb34f

File tree

4 files changed

+86
-168
lines changed

4 files changed

+86
-168
lines changed

iot-edge/Tutorials/PythonFilter/main.py

Lines changed: 33 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -4,121 +4,57 @@
44

55
# For guidance, see https://docs.microsoft.com/azure/iot-edge/tutorial-python-module
66

7-
import os
8-
import random
9-
import time
107
import sys
11-
import iothub_client
12-
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider
13-
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError
14-
15-
# messageTimeout - the maximum time in milliseconds until a message times out.
16-
# The timeout period starts at IoTHubClient.send_event_async.
17-
# By default, messages do not expire.
18-
MESSAGE_TIMEOUT = 10000
8+
import time
9+
import threading
10+
from azure.iot.device import IoTHubModuleClient, Message
1911

2012
# global counters
21-
RECEIVE_CALLBACKS = 0
22-
SEND_CALLBACKS = 0
23-
24-
# Choose HTTP, AMQP or MQTT as transport protocol. Currently only MQTT is supported.
25-
PROTOCOL = IoTHubTransportProvider.MQTT
26-
27-
# String containing Hostname, Device Id & Device Key & Module Id in the format:
28-
# "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>;ModuleId=<module_id>;GatewayHostName=<gateway>"
29-
CONNECTION_STRING = "[Device Connection String]"
30-
31-
# Callback received when the message that we're forwarding is processed.
32-
def send_confirmation_callback(message, result, user_context):
33-
global SEND_CALLBACKS
34-
print ( "Confirmation[%d] received for message with result = %s" % (user_context, result) )
35-
map_properties = message.properties()
36-
key_value_pair = map_properties.get_internals()
37-
print ( " Properties: %s" % key_value_pair )
38-
SEND_CALLBACKS += 1
39-
print ( " Total calls confirmed: %d" % SEND_CALLBACKS )
40-
41-
42-
# receive_message_callback is invoked when an incoming message arrives on the specified
43-
# input queue (in the case of this sample, "input1"). Because this is a filter module,
44-
# we will forward this message onto the "output1" queue.
45-
def receive_message_callback(message, hubManager):
46-
global RECEIVE_CALLBACKS
47-
message_buffer = message.get_bytearray()
48-
size = len(message_buffer)
49-
print ( " Data: <<<%s>>> & Size=%d" % (message_buffer[:size].decode('utf-8'), size) )
50-
map_properties = message.properties()
51-
key_value_pair = map_properties.get_internals()
52-
print ( " Properties: %s" % key_value_pair )
53-
RECEIVE_CALLBACKS += 1
54-
print ( " Total calls received: %d" % RECEIVE_CALLBACKS )
55-
hubManager.forward_event_to_output("output1", message, 0)
56-
return IoTHubMessageDispositionResult.ACCEPTED
57-
58-
59-
class HubManager(object):
60-
61-
def __init__(
62-
self,
63-
connection_string):
64-
self.client_protocol = PROTOCOL
65-
self.client = IoTHubClient(connection_string, PROTOCOL)
66-
67-
# set the time until a message times out
68-
self.client.set_option("messageTimeout", MESSAGE_TIMEOUT)
69-
# some embedded platforms need certificate information
70-
self.set_certificates()
71-
72-
# sets the callback when a message arrives on "input1" queue. Messages sent to
73-
# other inputs or to the default will be silently discarded.
74-
self.client.set_message_callback("input1", receive_message_callback, self)
75-
76-
def set_certificates(self):
77-
isWindows = sys.platform.lower() in ['windows', 'win32']
78-
if not isWindows:
79-
CERT_FILE = os.environ['EdgeModuleCACertificateFile']
80-
print("Adding TrustedCerts from: {0}".format(CERT_FILE))
81-
82-
# this brings in x509 privateKey and certificate
83-
file = open(CERT_FILE)
84-
try:
85-
self.client.set_option("TrustedCerts", file.read())
86-
print ( "set_option TrustedCerts successful" )
87-
except IoTHubClientError as iothub_client_error:
88-
print ( "set_option TrustedCerts failed (%s)" % iothub_client_error )
89-
90-
file.close()
91-
92-
# Forwards the message received onto the next stage in the process.
93-
def forward_event_to_output(self, outputQueueName, event, send_context):
94-
self.client.send_event_async(
95-
outputQueueName, event, send_confirmation_callback, send_context)
96-
97-
def main(connection_string):
13+
RECEIVED_MESSAGES = 0
14+
15+
def receive_message_listener(client):
16+
# This listener function only triggers for messages sent to "input1".
17+
# Messages sent to other inputs or to the default will be silently discarded.
18+
global RECEIVED_MESSAGES
19+
while True:
20+
message = client.receive_message_on_input("input1") # blocking call
21+
RECEIVED_MESSAGES += 1
22+
print("Message received on input1")
23+
print( " Data: <<{}>>".format(message.data) )
24+
print( " Properties: {}".format(message.custom_properties))
25+
print( " Total calls received: {}".format(RECEIVED_MESSAGES))
26+
print("Forwarding message to output1")
27+
client.send_message_to_output(message, "output1")
28+
print("Message successfully forwarded")
29+
30+
def main():
9831
try:
99-
print ( "\nPython %s\n" % sys.version )
32+
print ( "\nPython {}\n".format(sys.version) )
10033
print ( "IoT Hub Client for Python" )
10134

102-
hub_manager = HubManager(connection_string)
35+
client = IoTHubModuleClient.create_from_edge_environment()
36+
37+
# Begin listening for messages
38+
message_listener_thread = threading.Thread(target=receive_message_listener, args=(client,))
39+
message_listener_thread.daemon = True
40+
message_listener_thread.start()
10341

104-
print ( "Starting the IoT Hub Python sample using protocol %s..." % hub_manager.client_protocol )
42+
print ( "Starting the IoT Hub Python sample...")
10543
print ( "The sample is now waiting for messages and will indefinitely. Press Ctrl-C to exit. ")
10644

10745
while True:
10846
time.sleep(1000)
10947

110-
except IoTHubError as iothub_error:
111-
print ( "Unexpected error %s from IoTHub" % iothub_error )
112-
return
11348
except KeyboardInterrupt:
11449
print ( "IoTHubClient sample stopped" )
50+
except:
51+
print ( "Unexpected error from IoTHub" )
52+
return
11553

11654
if __name__ == '__main__':
11755
try:
118-
CONNECTION_STRING = os.environ['EdgeHubConnectionString']
56+
main()
11957

12058
except Exception as error:
12159
print ( error )
12260
sys.exit(1)
123-
124-
main(CONNECTION_STRING)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
azure-iothub-device-client==1.3.0.0b0
1+
azure-iot-device>=2.0.0rc10

iot-hub/Quickstarts/simulated-device-2/SimulatedDevice.py

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,94 +3,90 @@
33

44
import random
55
import time
6-
import sys
6+
import threading
77

88
# Using the Python Device SDK for IoT Hub:
99
# https://github.com/Azure/azure-iot-sdk-python
1010
# The sample connects to a device-specific MQTT endpoint on your IoT Hub.
11-
import iothub_client
12-
# pylint: disable=E0611
13-
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
14-
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue
11+
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
1512

1613
# The device connection string to authenticate the device with your IoT hub.
1714
# Using the Azure CLI:
1815
# az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyNodeDevice --output table
1916
CONNECTION_STRING = "{Your IoT hub device connection string}"
2017

21-
# Using the MQTT protocol.
22-
PROTOCOL = IoTHubTransportProvider.MQTT
23-
MESSAGE_TIMEOUT = 10000
24-
2518
# Define the JSON message to send to IoT Hub.
2619
TEMPERATURE = 20.0
2720
HUMIDITY = 60
28-
MSG_TXT = "{\"temperature\": %.2f,\"humidity\": %.2f}"
21+
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}}}'
2922

3023
INTERVAL = 1
3124

32-
def send_confirmation_callback(message, result, user_context):
33-
print ( "IoT Hub responded to message with status: %s" % (result) )
34-
3525
def iothub_client_init():
3626
# Create an IoT Hub client
37-
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
27+
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
3828
return client
3929

40-
# Handle direct method calls from IoT Hub
41-
def device_method_callback(method_name, payload, user_context):
30+
31+
def device_method_listener(device_client):
4232
global INTERVAL
43-
print ( "\nMethod callback called with:\nmethodName = %s\npayload = %s" % (method_name, payload) )
44-
device_method_return_value = DeviceMethodReturnValue()
45-
if method_name == "SetTelemetryInterval":
46-
try:
47-
INTERVAL = int(payload)
48-
# Build and send the acknowledgment.
49-
device_method_return_value.response = "{ \"Response\": \"Executed direct method %s\" }" % method_name
50-
device_method_return_value.status = 200
51-
except ValueError:
52-
# Build and send an error response.
53-
device_method_return_value.response = "{ \"Response\": \"Invalid parameter\" }"
54-
device_method_return_value.status = 400
55-
else:
56-
# Build and send an error response.
57-
device_method_return_value.response = "{ \"Response\": \"Direct method not defined: %s\" }" % method_name
58-
device_method_return_value.status = 404
59-
return device_method_return_value
33+
while True:
34+
method_request = device_client.receive_method_request()
35+
print (
36+
"\nMethod callback called with:\nmethodName = {method_name}\npayload = {payload}".format(
37+
method_name=method_request.name,
38+
payload=method_request.payload
39+
)
40+
)
41+
if method_request.name == "SetTelemetryInterval":
42+
try:
43+
INTERVAL = int(method_request.payload)
44+
except ValueError:
45+
response_payload = {"Response": "Invalid parameter"}
46+
response_status = 400
47+
else:
48+
response_payload = {"Response": "Executed direct method {}".format(method_request.name)}
49+
response_status = 200
50+
else:
51+
response_payload = {"Response": "Direct method {} not defined".format(method_request.name)}
52+
response_status = 404
53+
54+
method_response = MethodResponse(method_request.request_id, response_status, payload=response_payload)
55+
device_client.send_method_response(method_response)
56+
57+
6058

6159
def iothub_client_telemetry_sample_run():
6260

6361
try:
6462
client = iothub_client_init()
6563
print ( "IoT Hub device sending periodic messages, press Ctrl-C to exit" )
6664

67-
# Set up the callback method for direct method calls from the hub.
68-
client.set_device_method_callback(
69-
device_method_callback, None)
65+
# Start a thread to listen
66+
device_method_thread = threading.Thread(target=device_method_listener, args=(client,))
67+
device_method_thread.daemon = True
68+
device_method_thread.start()
7069

7170
while True:
7271
# Build the message with simulated telemetry values.
7372
temperature = TEMPERATURE + (random.random() * 15)
7473
humidity = HUMIDITY + (random.random() * 20)
75-
msg_txt_formatted = MSG_TXT % (temperature, humidity)
76-
message = IoTHubMessage(msg_txt_formatted)
74+
msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity)
75+
message = Message(msg_txt_formatted)
7776

7877
# Add a custom application property to the message.
7978
# An IoT hub can filter on these properties without access to the message body.
80-
prop_map = message.properties()
8179
if temperature > 30:
82-
prop_map.add("temperatureAlert", "true")
80+
message.custom_properties["temperatureAlert"] = "true"
8381
else:
84-
prop_map.add("temperatureAlert", "false")
82+
message.custom_properties["temperatureAlert"] = "false"
8583

8684
# Send the message.
87-
print( "Sending message: %s" % message.get_string() )
88-
client.send_event_async(message, send_confirmation_callback, None)
85+
print( "Sending message: {}".format(message) )
86+
client.send_message(message)
87+
print( "Message sent" )
8988
time.sleep(INTERVAL)
9089

91-
except IoTHubError as iothub_error:
92-
print ( "Unexpected error %s from IoTHub" % iothub_error )
93-
return
9490
except KeyboardInterrupt:
9591
print ( "IoTHubClient sample stopped" )
9692

iot-hub/Quickstarts/simulated-device/SimulatedDevice.py

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,25 @@
33

44
import random
55
import time
6-
import sys
76

87
# Using the Python Device SDK for IoT Hub:
98
# https://github.com/Azure/azure-iot-sdk-python
109
# The sample connects to a device-specific MQTT endpoint on your IoT Hub.
11-
import iothub_client
12-
# pylint: disable=E0611
13-
from iothub_client import IoTHubClient, IoTHubClientError, IoTHubTransportProvider, IoTHubClientResult
14-
from iothub_client import IoTHubMessage, IoTHubMessageDispositionResult, IoTHubError, DeviceMethodReturnValue
10+
from azure.iot.device import IoTHubDeviceClient, Message
1511

1612
# The device connection string to authenticate the device with your IoT hub.
1713
# Using the Azure CLI:
1814
# az iot hub device-identity show-connection-string --hub-name {YourIoTHubName} --device-id MyNodeDevice --output table
1915
CONNECTION_STRING = "{Your IoT hub device connection string}"
2016

21-
# Using the MQTT protocol.
22-
PROTOCOL = IoTHubTransportProvider.MQTT
23-
MESSAGE_TIMEOUT = 10000
24-
2517
# Define the JSON message to send to IoT Hub.
2618
TEMPERATURE = 20.0
2719
HUMIDITY = 60
28-
MSG_TXT = "{\"temperature\": %.2f,\"humidity\": %.2f}"
29-
30-
def send_confirmation_callback(message, result, user_context):
31-
print ( "IoT Hub responded to message with status: %s" % (result) )
20+
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}}}'
3221

3322
def iothub_client_init():
3423
# Create an IoT Hub client
35-
client = IoTHubClient(CONNECTION_STRING, PROTOCOL)
24+
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
3625
return client
3726

3827
def iothub_client_telemetry_sample_run():
@@ -45,25 +34,22 @@ def iothub_client_telemetry_sample_run():
4534
# Build the message with simulated telemetry values.
4635
temperature = TEMPERATURE + (random.random() * 15)
4736
humidity = HUMIDITY + (random.random() * 20)
48-
msg_txt_formatted = MSG_TXT % (temperature, humidity)
49-
message = IoTHubMessage(msg_txt_formatted)
37+
msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity)
38+
message = Message(msg_txt_formatted)
5039

5140
# Add a custom application property to the message.
5241
# An IoT hub can filter on these properties without access to the message body.
53-
prop_map = message.properties()
5442
if temperature > 30:
55-
prop_map.add("temperatureAlert", "true")
43+
message.custom_properties["temperatureAlert"] = "true"
5644
else:
57-
prop_map.add("temperatureAlert", "false")
45+
message.custom_properties["temperatureAlert"] = "false"
5846

5947
# Send the message.
60-
print( "Sending message: %s" % message.get_string() )
61-
client.send_event_async(message, send_confirmation_callback, None)
48+
print( "Sending message: {}".format(message) )
49+
client.send_message(message)
50+
print ( "Message successfully sent" )
6251
time.sleep(1)
6352

64-
except IoTHubError as iothub_error:
65-
print ( "Unexpected error %s from IoTHub" % iothub_error )
66-
return
6753
except KeyboardInterrupt:
6854
print ( "IoTHubClient sample stopped" )
6955

0 commit comments

Comments
 (0)