Get started with IoT Hub module identity and module twin (Python)

Note

Module identities and module twins are similar to Azure IoT Hub device identities and device twins, but provide finer granularity. While Azure IoT Hub device identities and device twins enable a back-end application to configure a device and provide visibility on the device's conditions, module identities and module twins provide these capabilities for individual components of a device. On capable devices with multiple components, such as operating system based devices or firmware devices, they allow for isolated configuration and conditions for each component.

At the end of this tutorial, you have three Python apps:

  • CreateModule, which creates a device identity, a module identity, and associated security keys to connect your device and module clients.

  • UpdateModuleTwinDesiredProperties, which sends updated module twin desired properties to your IoT Hub.

  • ReceiveModuleTwinDesiredPropertiesPatch, which receives the module twin desired properties patch on your device.

Note

IoT Hub has SDK support for many device platforms and languages (including C, Java, Javascript, and Python) through Azure IoT device SDKs. For instructions on how to use Python to connect your device to this tutorial's code, and generally to Azure IoT Hub, see the Azure IoT Python SDK.

Prerequisites

Create an IoT hub

This section describes how to create an IoT hub using the Azure portal.

  1. Sign in to the Azure portal.

  2. From the Azure homepage, select the + Create a resource button, and then enter IoT Hub in the Search the Marketplace field.

  3. Select IoT Hub from the search results, and then select Create.

  4. On the Basics tab, complete the fields as follows:

    • Subscription: Select the subscription to use for your hub.

    • Resource Group: Select a resource group or create a new one. To create a new one, select Create new and fill in the name you want to use. To use an existing resource group, select that resource group. For more information, see Manage Azure Resource Manager resource groups.

    • Region: Select the region in which you want your hub to be located. Select the location closest to you. Some features, such as IoT Hub device streams, are only available in specific regions. For these limited features, you must select one of the supported regions.

    • IoT Hub Name: Enter a name for your hub. This name must be globally unique. If the name you enter is available, a green check mark appears.

    Important

    Because the IoT hub will be publicly discoverable as a DNS endpoint, be sure to avoid entering any sensitive or personally identifiable information when you name it.

    Create a hub in the Azure portal

  5. Select Next: Size and scale to continue creating your hub.

    Set the size and scale for a new hub using the Azure portal

    You can accept the default settings here. If desired, you can modify any of the following fields:

    • Pricing and scale tier: Your selected tier. You can choose from several tiers, depending on how many features you want and how many messages you send through your solution per day. The free tier is intended for testing and evaluation. It allows 500 devices to be connected to the hub and up to 8,000 messages per day. Each Azure subscription can create one IoT hub in the free tier.

      If you are working through a Quickstart for IoT Hub device streams, select the free tier.

    • IoT Hub units: The number of messages allowed per unit per day depends on your hub's pricing tier. For example, if you want the hub to support ingress of 700,000 messages, you choose two S1 tier units. For details about the other tier options, see Choosing the right IoT Hub tier.

    • Azure Security Center: Turn this on to add an extra layer of threat protection to IoT and your devices. This option is not available for hubs in the free tier. For more information about this feature, see Azure Security Center for IoT.

    • Advanced Settings > Device-to-cloud partitions: This property relates the device-to-cloud messages to the number of simultaneous readers of the messages. Most hubs need only four partitions.

  6. Select Next: Tags to continue to the next screen.

    Tags are name/value pairs. You can assign the same tag to multiple resources and resource groups to categorize resources and consolidate billing. For more information, see Use tags to organize your Azure resources.

    Assign tags for the hub using the Azure portal

  7. Select Next: Review + create to review your choices. You see something similar to this screen, but with the values you selected when creating the hub.

    Review information for creating the new hub

  8. Select Create to create your new hub. Creating the hub takes a few minutes.

Get the IoT hub connection string

In this article, you create a back-end service that adds a device in the identity registry and then adds a module to that device. This service requires the registry write permission (which also includes registry read). You also create a service that adds desired properties to the module twin for the newly created module. This service needs the service connect permission. Although there are default shared access policies that grant these permissions individually, in this section, you create a custom shared access policy that contains both of these permissions.

To create a shared access policy that grants service connect and registry write permissions and to get a connection string for this policy, follow these steps:

  1. 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.

  2. On the left-side pane of your hub, select Shared access policies.

  3. From the top menu above the list of policies, select Add.

  4. Under Add a shared access policy, enter a descriptive name for your policy, such as serviceAndRegistryReadWrite. Under Permissions, select Registry write and Service connect, and then select Create. (The Registry read permission is included automatically when you select Registry write.)

    Show how to add a new shared access policy

  5. Select your new policy from the list of policies.

  6. Under Shared access keys, select the copy icon for the Connection string -- primary key and save the value.

    Show how to retrieve the connection string

For more information about IoT Hub shared access policies and permissions, see Access control and permissions.

Create a device identity and a module identity in IoT Hub

In this section, you create a Python service app that creates a device identity and a module identity in the identity registry in your IoT hub. A device or module can't connect to IoT hub unless it has an entry in the identity registry. For more information, see Understand the identity registry in your IoT hub. When you run this console app, it generates a unique ID and key for both device and module. Your device and module use these values to identify itself when it sends device-to-cloud messages to IoT Hub. The IDs are case-sensitive.

  1. At your command prompt, run the following command to install the azure-iot-hub package:

    pip install azure-iot-hub
    
  2. At your command prompt, run the following command to install the msrest package. You need this package to catch HTTPOperationError exceptions.

    pip install msrest
    
  3. Using a text editor, create a file named CreateModule.py in your working directory.

  4. Add the following code to your Python file. Replace YourIoTHubConnectionString with the connection string you copied in Get the IoT hub connection string.

    import sys
    from msrest.exceptions import HttpOperationError
    from azure.iot.hub import IoTHubRegistryManager
    
    CONNECTION_STRING = "YourIotHubConnectionString"
    DEVICE_ID = "myFirstDevice"
    MODULE_ID = "myFirstModule"
    
    try:
        # RegistryManager
        iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)
    
        try:
            # CreateDevice - let IoT Hub assign keys
            primary_key = ""
            secondary_key = ""
            device_state = "enabled"
            new_device = iothub_registry_manager.create_device_with_sas(
                DEVICE_ID, primary_key, secondary_key, device_state
            )
        except HttpOperationError as ex:
            if ex.response.status_code == 409:
                # 409 indicates a conflict. This happens because the device already exists.
                new_device = iothub_registry_manager.get_device(DEVICE_ID)
            else:
                raise
    
        print("device <" + DEVICE_ID +
              "> has primary key = " + new_device.authentication.symmetric_key.primary_key)
    
        try:
            # CreateModule - let IoT Hub assign keys
            primary_key = ""
            secondary_key = ""
            managed_by = ""
            new_module = iothub_registry_manager.create_module_with_sas(
                DEVICE_ID, MODULE_ID, managed_by, primary_key, secondary_key
            )
        except HttpOperationError as ex:
            if ex.response.status_code == 409:
                # 409 indicates a conflict. This happens because the module already exists.
                new_module = iothub_registry_manager.get_module(DEVICE_ID, MODULE_ID)
            else:
                raise
    
        print("device/module <" + DEVICE_ID + "/" + MODULE_ID +
              "> has primary key = " + new_module.authentication.symmetric_key.primary_key)
    
    except Exception as ex:
        print("Unexpected error {0}".format(ex))
    except KeyboardInterrupt:
        print("IoTHubRegistryManager sample stopped")
    
  5. At your command prompt, run the following command:

    python CreateModule.py
    

This app creates a device identity with ID myFirstDevice and a module identity with ID myFirstModule under device myFirstDevice. (If the device or module ID already exists in the identity registry, the code simply retrieves the existing device or module information.) The app displays the ID and primary key for each identity.

Note

The IoT Hub identity registry only stores device and module identities to enable secure access to the IoT hub. The identity registry stores device IDs and keys to use as security credentials. The identity registry also stores an enabled/disabled flag for each device that you can use to disable access for that device. If your application needs to store other device-specific metadata, it should use an application-specific store. There is no enabled/disabled flag for module identities. For more information, see Understand the identity registry in your IoT hub.

Update the module twin using Python service SDK

In this section, you create a Python service app that updates the module twin desired properties.

  1. At your command prompt, run the following command to install the azure-iot-hub package. You can skip this step if you installed the azure-iot-hub package in the previous section.

    pip install azure-iot-hub
    
  2. Using a text editor, create a file named UpdateModuleTwinDesiredProperties.py in your working directory.

  3. Add the following code to your Python file. Replace YourIoTHubConnectionString with the connection string you copied in Get the IoT hub connection string.

    import sys
    from azure.iot.hub import IoTHubRegistryManager
    from azure.iot.hub.models import Twin, TwinProperties
    
    CONNECTION_STRING = "YourIoTHubConnectionString"
    DEVICE_ID = "myFirstDevice"
    MODULE_ID = "myFirstModule"
    
    try:
        # RegistryManager
        iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)
    
        module_twin = iothub_registry_manager.get_module_twin(DEVICE_ID, MODULE_ID)
        print ( "" )
        print ( "Module twin properties before update    :" )
        print ( "{0}".format(module_twin.properties) )
    
        # Update twin
        twin_patch = Twin()
        twin_patch.properties = TwinProperties(desired={"telemetryInterval": 122})
        updated_module_twin = iothub_registry_manager.update_module_twin(
            DEVICE_ID, MODULE_ID, twin_patch, module_twin.etag
        )
        print ( "" )
        print ( "Module twin properties after update     :" )
        print ( "{0}".format(updated_module_twin.properties) )
    
    except Exception as ex:
        print ( "Unexpected error {0}".format(ex) )
    except KeyboardInterrupt:
        print ( "IoTHubRegistryManager sample stopped" )
    

Get updates on the device side

In this section, you create a Python app to get the module twin desired properties update on your device.

  1. Get your module connection string. In Azure portal, navigate to your IoT Hub and select IoT devices in the left pane. Select myFirstDevice from the list of devices and open it. Under Module identities, select myFirstModule. Copy the module connection string. You need it in a following step.

    Azure portal module detail

  2. At your command prompt, run the following command to install the azure-iot-device package:

    pip install azure-iot-device
    
  3. Using a text editor, create a file named ReceiveModuleTwinDesiredPropertiesPatch.py in your working directory.

  4. Add the following code to your Python file. Replace YourModuleConnectionString with the module connection string you copied in step 1.

    import time
    import threading
    from azure.iot.device import IoTHubModuleClient
    
    CONNECTION_STRING = "YourModuleConnectionString"
    
    
    def twin_update_listener(client):
        while True:
            patch = client.receive_twin_desired_properties_patch()  # blocking call
            print("")
            print("Twin desired properties patch received:")
            print(patch)
    
    def iothub_client_sample_run():
        try:
            module_client = IoTHubModuleClient.create_from_connection_string(CONNECTION_STRING)
    
            twin_update_listener_thread = threading.Thread(target=twin_update_listener, args=(module_client,))
            twin_update_listener_thread.daemon = True
            twin_update_listener_thread.start()
    
            while True:
                time.sleep(1000000)
    
        except KeyboardInterrupt:
            print("IoTHubModuleClient sample stopped")
    
    
    if __name__ == '__main__':
        print ( "Starting the IoT Hub Python sample..." )
        print ( "IoTHubModuleClient waiting for commands, press Ctrl-C to exit" )
    
        iothub_client_sample_run()
    

Run the apps

In this section, you run the ReceiveModuleTwinDesiredPropertiesPatch device app and then run the UpdateModuleTwinDesiredProperties service app to update the desired properties of your module.

  1. Open a command prompt and run the device app:

    python ReceiveModuleTwinDesiredPropertiesPatch.py
    

    Device app initial output

  2. Open a separate command prompt and run the service app:

    python UpdateModuleTwinDesiredProperties.py
    

    Notice that the TelemetryInterval desired property appears in the updated module twin in your service app output:

    Service app output

    The same property appears in the desired properties patch received in your device app output:

    Device app output shows desired properties patch

Next steps

To continue getting started with IoT Hub and to explore other IoT scenarios, see: