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

Note

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

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

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

  • UpdateModuleTwinReportedProperties, which sends updated module twin reported properties to your IoT Hub.

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. Choose Create a resource, 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.

    • 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

    This screen allows you to set the following values:

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

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

    • 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. For this article, accept the default choices, and then select Review + create to review your choices. You see something similar to this screen.

    Review information for creating the new hub

  7. 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. Your service requires the registry write permission. By default, every IoT hub is created with a shared access policy named registryReadWrite that grants this permission.

To get the IoT Hub connection string for the registryReadWrite 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 list of policies, select the registryReadWrite policy.

  4. 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 app that creates a device identity and a module identity in the identity registry in your IoT hub. A device or module cannot connect to IoT hub unless it has an entry in the identity registry. For more information, see the "Identity registry" section of the IoT Hub developer guide. 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.

Add the following code to your Python file:

import sys
import iothub_service_client
from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod, IoTHubError

CONNECTION_STRING = "YourConnString"
DEVICE_ID = "myFirstDevice"
MODULE_ID = "myFirstModule"

try:
    # RegistryManager
    iothub_registry_manager = IoTHubRegistryManager(CONNECTION_STRING)

    # CreateDevice
    primary_key = ""
    secondary_key = ""
    auth_method = IoTHubRegistryManagerAuthMethod.SHARED_PRIVATE_KEY
    new_device = iothub_registry_manager.create_device(
        DEVICE_ID, primary_key, secondary_key, auth_method)
    print("new_device <" + DEVICE_ID +
          "> has primary key = " + new_device.primaryKey)

    # CreateModule
    new_module = iothub_registry_manager.create_module(
        DEVICE_ID, primary_key, secondary_key, MODULE_ID, auth_method)
    print("device/new_module <" + DEVICE_ID + "/" + MODULE_ID +
          "> has primary key = " + new_module.primaryKey)

except IoTHubError as iothub_error:
    print("Unexpected error {0}".format(iothub_error))
except KeyboardInterrupt:
    print("IoTHubRegistryManager sample stopped")

This app creates a device identity with ID myFirstDevice and a module identity with ID myFirstModule under device myFirstDevice. (If that module ID already exists in the identity registry, the code simply retrieves the existing module information.) The app then displays the primary key for that identity. You use this key in the simulated module app to connect to your IoT hub.

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 IoT Hub developer guide.

Update the module twin using Python device SDK

In this section, you create a Python app on your simulated device that updates the module twin reported properties.

  1. Get your module connection string -- now if you sign into the Azure portal. Navigate to your IoT Hub and click IoT Devices. Find myFirstDevice, open it and you see myFirstModule was successfully created. Copy the module connection string. It is needed in the next step.

    Azure portal module detail

  2. Create UpdateModuleTwinReportedProperties app

    Add the following using statements at the top of the Program.cs file:

    import sys
    import iothub_service_client
    from iothub_service_client import IoTHubRegistryManager, IoTHubRegistryManagerAuthMethod, IoTHubDeviceTwin, IoTHubError
    
    CONNECTION_STRING = "FILL IN CONNECTION STRING"
    DEVICE_ID = "MyFirstDevice"
    MODULE_ID = "MyFirstModule"
    
    UPDATE_JSON = "{\"properties\":{\"desired\":{\"telemetryInterval\":122}}}"
    
    try:
        iothub_twin = IoTHubDeviceTwin(CONNECTION_STRING)
    
        twin_info = iothub_twin.get_twin(DEVICE_ID, MODULE_ID)
        print ( "" )
        print ( "Twin before update    :" )
        print ( "{0}".format(twin_info) )
    
        twin_info_updated = iothub_twin.update_twin(DEVICE_ID, MODULE_ID, UPDATE_JSON)
        print ( "" )
        print ( "Twin after update     :" )
        print ( "{0}".format(twin_info_updated) )
    
    except IoTHubError as iothub_error:
        print ( "Unexpected error {0}".format(iothub_error) )
    except KeyboardInterrupt:
        print ( "IoTHubRegistryManager sample stopped" )
    

This code sample shows you how to retrieve the module twin and update reported properties with AMQP protocol.

Get updates on the device side

In addition to the above code, you can add below code block to get the twin update message on your device.

import time
import threading
from azure.iot.device import IoTHubModuleClient

CONNECTION_STRING = "{deviceConnectionString}"


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()

Next steps

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