Get started with device management (Python)
This article shows you how to create:
dmpatterns_getstarted_device.py: a simulated device app with a direct method that reboots the device and reports the last reboot time. Direct methods are invoked from the cloud.
dmpatterns_getstarted_service.py: a Python console app that calls the direct method in the simulated device app through your IoT hub. It displays the response and updated reported properties.
Note
For more information about the SDK tools available to build both device and back-end apps, see Azure IoT SDKs.
Prerequisites
An active Azure account. (If you don't have an account, you can create a Trial in just a couple of minutes.)
An IoT Hub. Create one with the CLI or the Azure portal.
A registered device. Register one in the Azure portal.
Python version 3.7 or later is recommended. Make sure to use the 32-bit or 64-bit installation as required by your setup. When prompted during the installation, make sure to add Python to your platform-specific environment variable.
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).
Register a new device in the IoT hub
In this section, you use the Azure CLI to create a device identity for this article. Device IDs are case sensitive.
Run the following command to install the Azure IoT Extension for Azure CLI:
az extension add --name azure-iot
Create a new device identity called
myDeviceId
and retrieve the device connection string with these commands:az iot hub device-identity create --device-id myDeviceId --hub-name {Your IoT Hub name} --resource-group {Resource group of the Hub} az iot hub device-identity connection-string show --device-id myDeviceId --hub-name {Your IoT Hub name} --resource-group {Resource group of the Hub} -o table
Important
The device ID may be visible in the logs collected for customer support and troubleshooting, so make sure to avoid any sensitive information while naming it.
Make a note of the device connection string from the result. This device connection string is used by the device app to connect to your IoT Hub as a device.
Create a device app with a direct method
In this section, you:
Create a Python console app that responds to a direct method called by the cloud.
Simulate a device reboot.
Use the reported properties to enable device twin queries to identify devices and when they last rebooted.
At your command prompt, run the following command to install the azure-iot-device package:
pip install azure-iot-device
Using a text editor, create a file named dmpatterns_getstarted_device.py in your working directory.
Add the following
import
statements at the start of the dmpatterns_getstarted_device.py file.import time import datetime from azure.iot.device import IoTHubDeviceClient, MethodResponse
Add the CONNECTION_STRING variable. Replace the
{deviceConnectionString}
placeholder value with your device connection string. You copied this connection string previously in Register a new device in the IoT hub.CONNECTION_STRING = "{deviceConnectionString}"
Add the following function to instantiate a client configured for direct methods on the device.
def create_client(): # Instantiate the client client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING) # Define the handler for method requests def method_request_handler(method_request): if method_request.name == "rebootDevice": # Act on the method by rebooting the device print("Rebooting device") time.sleep(20) print("Device rebooted") # ...and patching the reported properties current_time = str(datetime.datetime.now()) reported_props = {"rebootTime": current_time} client.patch_twin_reported_properties(reported_props) print( "Device twins updated with latest rebootTime") # Create a method response indicating the method request was resolved resp_status = 200 resp_payload = {"Response": "This is the response from the device"} method_response = MethodResponse(method_request.request_id, resp_status, resp_payload) else: # Create a method response indicating the method request was for an unknown method resp_status = 404 resp_payload = {"Response": "Unknown method"} method_response = MethodResponse(method_request.request_id, resp_status, resp_payload) # Send the method response client.send_method_response(method_response) try: # Attach the handler to the client client.on_method_request_received = method_request_handler except: # In the event of failure, clean up client.shutdown() return client
Start the direct method sample and wait.
def main(): print ("Starting the IoT Hub Python sample...") client = create_client() print ("Waiting for commands, press Ctrl-C to exit") try: # Wait for program exit while True: time.sleep(1000) except KeyboardInterrupt: print("IoTHubDeviceClient sample stopped") finally: # Graceful exit print("Shutting down IoT Hub Client") client.shutdown() if __name__ == '__main__': main()
Save and close the dmpatterns_getstarted_device.py file.
Note
To keep things simple, this tutorial does not implement any retry policy. In production code, you should implement retry policies, as suggested in the article, Transient Fault Handling.
Get the IoT hub connection string
In this article, you create a backend service that invokes a direct method on a device. To invoke a direct method on a device through IoT Hub, your service needs the service connect permission. By default, every IoT Hub is created with a shared access policy named service that grants this permission.
To get the IoT Hub connection string for the service policy, follow these steps:
In the Azure portal, select Resource groups. Select the resource group where your hub is located, and then select your hub from the list of resources.
On the left-side pane of your IoT hub, select Shared access policies.
From the list of policies, select the service policy.
Copy the Primary connection string and save the value.
For more information about IoT Hub shared access policies and permissions, see Access control and permissions.
Create a service app to trigger a reboot
In this section, you create a Python console app that initiates a remote reboot on a device using a direct method. The app uses device twin queries to discover the last reboot time for that device.
At your command prompt, run the following command to install the azure-iot-hub package:
pip install azure-iot-hub
Using a text editor, create a file named dmpatterns_getstarted_service.py in your working directory.
Add the following
import
statements at the start of the dmpatterns_getstarted_service.py file.import sys, time from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult, Twin
Add the following variable declarations. Replace the
{IoTHubConnectionString}
placeholder value with the IoT hub connection string you copied previously in Get the IoT hub connection string. Replace the{deviceId}
placeholder value with the device ID you registered in Register a new device in the IoT hub.CONNECTION_STRING = "{IoTHubConnectionString}" DEVICE_ID = "{deviceId}" METHOD_NAME = "rebootDevice" METHOD_PAYLOAD = "{\"method_number\":\"42\"}" TIMEOUT = 60 WAIT_COUNT = 10
Add the following function to invoke the device method to reboot the target device, then query for the device twins and get the last reboot time.
def iothub_devicemethod_sample_run(): try: # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(CONNECTION_STRING) print ( "" ) print ( "Invoking device to reboot..." ) # Call the direct method. deviceMethod = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD) response = registry_manager.invoke_device_method(DEVICE_ID, deviceMethod) print ( "" ) print ( "Successfully invoked the device to reboot." ) print ( "" ) print ( response.payload ) while True: print ( "" ) print ( "IoTHubClient waiting for commands, press Ctrl-C to exit" ) status_counter = 0 while status_counter <= WAIT_COUNT: twin_info = registry_manager.get_twin(DEVICE_ID) if twin_info.properties.reported.get("rebootTime") != None : print ("Last reboot time: " + twin_info.properties.reported.get("rebootTime")) else: print ("Waiting for device to report last reboot time...") time.sleep(5) status_counter += 1 except Exception as ex: print ( "" ) print ( "Unexpected error {0}".format(ex) ) return except KeyboardInterrupt: print ( "" ) print ( "IoTHubDeviceMethod sample stopped" ) if __name__ == '__main__': print ( "Starting the IoT Hub Service Client DeviceManagement Python sample..." ) print ( " Connection string = {0}".format(CONNECTION_STRING) ) print ( " Device ID = {0}".format(DEVICE_ID) ) iothub_devicemethod_sample_run()
Save and close the dmpatterns_getstarted_service.py file.
Run the apps
You're now ready to run the device code and the service code that initiates a reboot of the device.
At the command prompt where you created the device, run the following command to begin listening for the reboot direct method.
python dmpatterns_getstarted_device.py
At the command prompt where you create the service, run the following command to trigger the remote reboot and query for the device twin to find the last reboot time.
python dmpatterns_getstarted_service.py
You see the device response to the direct method in the console.
The following shows the device response to the reboot direct method:
The following shows the service calling the reboot direct method and polling the device twin for status:
Customize and extend the device management actions
Your IoT solutions can expand the defined set of device management patterns or enable custom patterns by using the device twin and cloud-to-device method primitives. Other examples of device management actions include factory reset, firmware update, software update, power management, network and connectivity management, and data encryption.
Device maintenance windows
Typically, you configure devices to perform actions at a time that minimizes interruptions and downtime. Device maintenance windows are a commonly used pattern to define the time when a device should update its configuration. Your back-end solutions can use the desired properties of the device twin to define and activate a policy on your device that enables a maintenance window. When a device receives the maintenance window policy, it can use the reported property of the device twin to report the status of the policy. The back-end app can then use device twin queries to attest to compliance of devices and each policy.
Next steps
In this article, you used a direct method to trigger a remote reboot on a device. You used the reported properties to report the last reboot time from the device, and queried the device twin to discover the last reboot time of the device from the cloud.
To continue getting started with IoT Hub and device management patterns such as remote over the air firmware update, see How to do a firmware update.
To learn how to extend your IoT solution and schedule method calls on multiple devices, see Schedule and broadcast jobs.