Duck Dodgers
Duck Dodgers

Reputation: 339

Dynamically Provision iot Device With Azure dps - Unexpected Failure. Python sdk

I am dynamically provision an iot device using the python azure-iot-device python package. I am using v2 and not 3.0.0b2. I can't even get that to compile.

Here's my python code trying to provision a device:

import asyncio
import os

from azure.iot.device.aio import (
    ProvisioningDeviceClient,
)
from dotenv import load_dotenv
load_dotenv(dotenv_path=".env")

CONNECTION_STRING = os.getenv("IOTHUB_DEVICE_CONNECTION_STRING")
ID_SCOPE = os.getenv("PROVISIONING_IDSCOPE")
REGISTRATION_ID = os.getenv("PROVISIONING_REGISTRATION_ID")
SYMMETRIC_KEY = os.getenv("PROVISIONING_SYMMETRIC_KEY")
PROVISIONING_HOST = os.getenv("PROVISIONING_HOST")
# PROVISIONING_SHARED_ACCESS_KEY = os.getenv("PROVISIONING_SHARED_ACCESS_KEY")

async def main():
    print("Starting multi-feature sample")
    provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key(
        provisioning_host=PROVISIONING_HOST,
        registration_id=REGISTRATION_ID,
        id_scope=ID_SCOPE,
        symmetric_key=SYMMETRIC_KEY,
    )
    provisioning_device_client.provisioning_payload = "<Your Payload>"
    provisioning_result = None
    try:
        provisioning_result = await provisioning_device_client.register()
    except Exception as e:
        print(f"an error occurred provisioning the device -- {e}")
    finally:
        print(f"result -- {provisioning_result}")
  
if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        # Exit application because user indicated they wish to exit.
        # This will have cancelled `main()` implicitly.
        print("User initiated exit. Exiting.")

The symmetric key is derived by using the enrollment group master key to compute an HMAC-SHA256 of the registration ID for the device. I simply followed the "Derive a Device Key" section in this guide -- https://learn.microsoft.com/en-us/azure/iot-dps/how-to-legacy-device-symm-key?tabs=linux&pivots=programming-language-python#derive-a-device-key

I keep getting 'Unexpected Failure' error. The code is so little that there's almost nothing to debug. I believe I followed the steps closely in setting up my iot hub and dps. Please let me know any suggestions

Upvotes: 0

Views: 389

Answers (1)

Sampath
Sampath

Reputation: 3639

The error message ‘Unexpected Failure’ is too generic to identify the root cause of the issue. However, there are a few things we can check to resolve the issue.

  • First, make sure that the connection string, ID scope, registration ID, symmetric key, and provisioning host are all correct and valid. Second, ensure that the device is not already provisioned.

enter image description here

enter image description here

  • Create an IoT Hub and IoT device

  • Create Azure IoT Hub Device Provisioning Service

  • Add IoT hub in (DPS) Linked IoT hubs.

  • Manage enrollments with Add link to IoT hub.

  • Enable IoT Edge on the provision device.

  • Used this link for az iot dps enrollment-group from MSDOC.

  • Replace the your resourcegroupname, dpsname, enrollment_id, registration_id. It gives derived-device-key or PROVISIONING_SYMMETRIC_KEY.

      az iot dps enrollment-group compute-device-key -g {resource_group_name} --dps-name {dps_name} --enrollment-id {enrollment_id} --registration-id {registration_id}
    

enter image description here

  • Used the same reference for Provision devices using a symmetric key enrollment group in DPS Azure IoT Hub Device Provisioning Service

enter image description here

Code:

import asyncio
import os
import logging
from azure.iot.device.aio import ProvisioningDeviceClient
from azure.iot.device import exceptions
from dotenv import load_dotenv
logging.basicConfig(level=logging.DEBUG)
load_dotenv(dotenv_path=".env")
CONNECTION_STRING = os.getenv("IOTHUB_DEVICE_CONNECTION_STRING")
ID_SCOPE = os.getenv("PROVISIONING_IDSCOPE")
REGISTRATION_ID = os.getenv("PROVISIONING_REGISTRATION_ID")
SYMMETRIC_KEY = os.getenv("PROVISIONING_SYMMETRIC_KEY")
PROVISIONING_HOST = os.getenv("PROVISIONING_HOST")
async def main():
    print("Starting the device provisioning process")
    provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key(
        provisioning_host=PROVISIONING_HOST,
        registration_id=REGISTRATION_ID,
        id_scope=ID_SCOPE,
        symmetric_key=SYMMETRIC_KEY,
    )
    provisioning_device_client.provisioning_payload = "<Your Payload>"
    provisioning_result = None
    try:
        provisioning_result = await provisioning_device_client.register()
        print("Device successfully provisioned!")
        print("Provisioning result:")
        print(provisioning_result.registration_state)
        print(f"Device ID: {provisioning_result.registration_state.device_id}")
    except exceptions.ProvisioningError as pe:
        print(f"Provisioning failed with error: {pe}")
    except Exception as e:
        print(f"An error occurred provisioning the device: {e}")
if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("User initiated exit. Exiting.")


Output:
enter image description here

Provisioned status:
enter image description here

Upvotes: 0

Related Questions